error[E0119]: conflicting implementations of trait `SomeTrait`

トレイト実装の指定が既存のものと衝突した。

基本ルール

同じ型と同じトレイトの組合せで、すでに他に実装があると衝突する。

これがもし許されると、どの実装が正しいのか分からなくなってしまう。

空のトレイトの取扱

マーカートレイトのような空のトレイトについても、例外扱いはされない。つまり、空の実装どうしでも衝突しうる (ソースが短くなるので以降のサンプルでは多用している)。

パターン

パターン A

自明なパターン

同じ型と同じトレイトですでに実装があるパターン。

サンプル

以下では、全く同じトレイトと型ですでに実装がある。


trait MyTrait {}
struct MyType {}

impl MyTrait for MyType {}
impl MyTrait for MyType {}

error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`
 --> src\lib.rs:5:1
  |
4 | impl MyTrait for MyType {}
  | ----------------------- first implementation here
5 | impl MyTrait for MyType {}
  | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`

パターン B1

型パラメタ (ブランケット実装との衝突)

同じトレイトについて、個別の型への実装と、ブランケット実装がある。
そして、個別の型がブランケット実装の範囲に含まれてしまっている。

サンプル

以下では、MyTypeT に含まれている。


trait MyTrait {}
struct MyType {}

impl MyTrait for MyType {}
impl<T> MyTrait for T {}

error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`
 --> src\sub.rs:5:1
  |
4 | impl MyTrait for MyType {}
  | ----------------------- first implementation here
5 | impl<T> MyTrait for T {}
  | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`

パターン B2

型パラメタ (ブランケット実装どうしの衝突)

同じトレイトについて、ブランケット実装が複数ある。
そして、両者の範囲が重複してしまっている。

サンプル

以下では、TraitXTraitY の両方を実装する型への考慮がない。


trait MyTrait {}
trait TraitX {}
trait TraitY {}

impl<T> MyTrait for T where T: TraitX {}
impl<T> MyTrait for T where T: TraitY {}

error[E0119]: conflicting implementations of trait `MyTrait`
 --> src\lib.rs:6:1
  |
5 | impl<T> MyTrait for T where T: TraitX {}
  | --------------------- first implementation here
6 | impl<T> MyTrait for T where T: TraitY {}
  | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

パターン B3

型パラメタ (ジェネリクス型)

ジェネリクス型どうしが同じになりうるパターン。

サンプル

以下では、MyType<i32>MyType<T> は同じになりうる。


trait MyTrait {}
struct MyType<T>(T);

impl MyTrait for MyType<i32> {}
impl<T> MyTrait for MyType<T> {}

error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType<i32>`
 --> src\lib.rs:5:1
  |
4 | impl MyTrait for MyType<i32> {}
  | ---------------------------- first implementation here
5 | impl<T> MyTrait for MyType<T> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType<i32>`

パターン B4

型パラメタ (ジェネリクストレイト)

ジェネリクストレイトどうしが同じになりうるパターン。

サンプル

以下では、MyTrait<i32>MyTrait<T> は同じになりうる。


trait MyTrait<T> {}
struct MyType {}

impl MyTrait<i32> for MyType {}
impl<T> MyTrait<T> for MyType {}

error[E0119]: conflicting implementations of trait `MyTrait<i32>` for type `MyType`
 --> src\lib.rs:5:1
  |
4 | impl MyTrait<i32> for MyType {}
  | ---------------------------- first implementation here
5 | impl<T> MyTrait<T> for MyType {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`

パターン B5

型パラメタ (共有される型パラメタ)

トレイトと型に同じ型パラメタが含まれるパターン。

サンプル

以下では、MyTrait<i32>i32 の組は、MyTrait<T>T の組と同じになりうる。


trait MyTrait<T> {}

impl MyTrait<i32> for i32 {}
impl<T> MyTrait<T> for T {}

error[E0119]: conflicting implementations of trait `MyTrait<i32>` for type `i32`
 --> src\lib.rs:4:1
  |
3 | impl MyTrait<i32> for i32 {}
  | ------------------------- first implementation here
4 | impl<T> MyTrait<T> for T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`

パターン C

関連型 (Rust の欠陥)

関連型を区別しない問題がある。

サンプル

以下では、HasType<Type = i32>HasType<Type = i64> 区別されず衝突にいたる。


trait MyTrait {}
trait HasType { type Type; }

impl<T: HasType<Type = i32>> MyTrait for T {}
impl<T: HasType<Type = i64>> MyTrait for T {}

error[E0119]: conflicting implementations of trait `MyTrait`
 --> src\lib.rs:5:1
  |
4 | impl<T: HasType<Type = i32>> MyTrait for T {}
  | ------------------------------------------ first implementation here
5 | impl<T: HasType<Type = i64>> MyTrait for T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

パターン D1

外部クレート (上流クレートとの衝突)

作成中のクレートと上流クレートのトレイト実装が衝突するパターン。

これは身に覚えがないぶん、いざ発生すると混乱しやすい。

サンプル

以下では、core にある Fromブランケット実装 (自身への恒等変換) と重複がおきる。


struct MyType {}

impl From<MyType> for MyType {
    fn from(value: MyType) -> Self {
        value
    }
}

error[E0119]: conflicting implementations of trait `From<MyType>` for type `MyType`
 --> src\lib.rs:3:1
  |
3 | impl From<MyType> for MyType {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T> From<T> for T;

パターン D2

外部クレート (上流クレートとの衝突予防)

型へのトレイト実装とブランケット実装との将来的な衝突を予防するパターン。

これは型が上流クレート由来で、衝突の有無がその上流クレート次第だと発生する。

サンプル

以下では、std が将来的に f32Eq を実装すると、前のブランケット実装と衝突する (そのような変更は今後とも絶対にないだろうが、あり得そうかどうかでなく、上流クレート次第の状況になるとエラーが発生する)。


trait MyTrait {}
struct MyType<T>(T);

impl<T: Eq> MyTrait for MyType<T> {}
impl<T> MyTrait for MyType<f32> {}

error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType<f32>`
 --> src\lib.rs:5:1
  |
4 | impl<T: Eq> MyTrait for MyType<T> {}
  | --------------------------------- first implementation here
5 | impl<T> MyTrait for MyType<f32> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType<f32>`
  |
  = note: upstream crates may add a new impl of trait `std::cmp::Eq` for type `f32` in future versions

パターン D3

外部クレート (下流クレートへの配慮)

作成中のクレートの下流クレートでありうる実装を考慮したパターン。

これは下流クレートがトレイト実装を、作成中のクレートを含む上流クレートが提供するトレイトと型で行う可能性を考慮している (『孤児ルール』の『基本ルール』のみを考えるとこれは不可能に思えるが、『追加ルール』により型パラメタつきのトレイトで可能となる)。

サンプル

以下では、下流クレートが OurTraitOurType に実装するかもしれない。


trait MyTrait {}
trait OurTrait<T> {}
struct OurType {}

impl MyTrait for OurType {}
impl<T, U> MyTrait for T where T: OurTrait<U> {}

error[E0119]: conflicting implementations of trait `MyTrait` for type `OurType`
 --> src\lib.rs:6:1
  |
5 | impl MyTrait for OurType {}
  | ------------------------ first implementation here
6 | impl<T, U> MyTrait for T where T: OurTrait<U> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OurType`
  |
  = note: downstream crates may implement trait `OurTrait<_>` for type `OurType`