Closed
Description
Consider the following snippet:
trait A {}
trait B {}
trait C<T> {}
impl <T: A> C<T> { fn asdf(&self) { println!("asdf"); } }
impl <T: B> C<T> { fn asdf(&self) { println!("asdf!!"); } }
struct Z {}
impl A for Z {}
impl B for Z {}
struct W {}
impl C<Z> for W {}
fn main() {
let asdf = Box::new(W {}) as Box<C<Z>>;
asdf.asdf();
}
When asdf.asdf()
is called, which impl should be used? Is it possible to select one impl or the other?
When discussing this in #rust, @mbrubeck also found that impls on trait objects don't check for overlap at all:
trait C<T> {}
impl<T> C<T> { fn asdf(&self) {} }
impl<T> C<T> { fn asdf(&self) {} }
struct W {}
impl<T> C<T> for W {}
fn main() {
let b = Box::new(W {}) as Box<C<()>>;
b.asdf();
}
In both of these examples, taking out the call to asdf()
makes the sample compile, meaning that it's only upon method resolution that this conflict is found. The former can be ruled out as a coherence issue, and the latter is directly an overlapping impl, that wouldn't be allowed on a regular struct/enum.
cc #36889, per talchas in #rust