Closed
Description
In this code snippet, we impl a trait on all types that implement Bar. However, we impl the trait twice, and this correctly does not compile:
fn main() {
//let qux = Qux;
//qux.foo();
}
struct Qux;
trait Bar {
fn bar(&self);
}
impl Bar for Qux {
fn bar(&self) { println("qux"); }
}
trait Foo {
fn foo(&self);
}
impl<T: Bar> Foo for T {
fn foo(&self) { println("foo1"); }
}
impl<T: Bar> Foo for T {
fn foo(&self) { println("foo2"); }
}
4894.rs:24:0: 26:1 error: conflicting implementations for a trait
4894.rs:24 impl<T: Bar> Foo for T {
4894.rs:25 fn foo(&self) { println("foo2"); }
4894.rs:26 }
4894.rs:20:0: 22:1 note: note conflicting implementation here
4894.rs:20 impl<T: Bar> Foo for T {
4894.rs:21 fn foo(&self) { println("foo1"); }
4894.rs:22 }
4894.rs:20:0: 22:1 error: conflicting implementations for a trait
4894.rs:20 impl<T: Bar> Foo for T {
4894.rs:21 fn foo(&self) { println("foo1"); }
4894.rs:22 }
4894.rs:24:0: 26:1 note: note conflicting implementation here
4894.rs:24 impl<T: Bar> Foo for T {
4894.rs:25 fn foo(&self) { println("foo2"); }
4894.rs:26 }
error: aborting due to 2 previous errors
But, if instead of bounding our generics with Bar we bound them with the built-in Copy trait, this compiles successfully!
fn main() {
//let qux = Qux;
//qux.foo();
}
struct Qux;
trait Foo {
fn foo(&self);
}
impl<T: Copy> Foo for T {
fn foo(&self) { println("foo1"); }
}
impl<T: Copy> Foo for T {
fn foo(&self) { println("foo2"); }
}
However, if you uncomment the lines that actually attempt to invoke .foo(), this code will fail to compile with "multiple applicable methods in scope".
Given that the non-built-in trait correctly prevents compilation at definition-time rather than waiting for invocation, I think it would be correct for Copy
to do the same.