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

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

作成中のクレートと下流クレートのトレイト実装の衝突予防のためのパターン。

型とトレイトの両方が作成中のクレート由来の場合、かつそれらが『孤児ルール』の抜け道となる『特別ルール』の適用パターンの場合に発生する。なお、殆どの衝突予防は孤児ルールの『基本ルール』の守備範囲のため、そちらで対策されている。


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


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

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

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