error[E0119]: conflicting implementations of trait `SomeTrait`
トレイト実装の指定が既存のものと衝突した。
同じ型と同じトレイトの組合せで、すでに他に実装があると衝突する。
これがもし許されると、どの実装が正しいのか分からなくなってしまう。
マーカートレイトのような空のトレイトについても、例外扱いはされない。つまり、空の実装どうしでも衝突しうる (ソースが短くなるので以降のサンプルでは多用している)。
全く同じトレイトと型を指定している。
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`
同じトレイトについて、個別の型への実装と、ブランケット実装がある。
しかし、個別の型がブランケット実装の範囲に含まれてしまっている。
以下では、MyType
は T
に含まれている。
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`
同じトレイトについて、ブランケット実装が複数ある。
しかし、両者の範囲が重複してしまっている。
以下では、TraitX
と TraitY
の両方を実装する型への考慮がない。
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
ジェネリクス型どうしが同じになりうるパターン。
以下では、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>`
ジェネリクストレイトどうしが同じになりうるパターン。
以下では、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`
トレイトと型に同じ型パラメタが含まれるパターン。
以下では、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`
関連型を区別しない問題がある。
以下では、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
作成中のクレートと上流クレートのトレイト実装が衝突するパターン。
これは身に覚えがないぶん、いざ発生すると混乱しやすい。
以下では、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;
作成中のクレートと下流クレートのトレイト実装の衝突予防のためのパターン。
型とトレイトの両方が作成中のクレート由来の場合、かつそれらが『孤児ルール』の抜け道となる『特別ルール』の適用パターンの場合に発生する。なお、殆どの衝突予防は孤児ルールの『基本ルール』の守備範囲のため、そちらで対策されている。
以下では、下流クレートが OurTrait
を OurType
に実装するかもしれない。
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`