-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
A-trait-systemArea: Trait systemArea: Trait systemP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
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
Metadata
Metadata
Assignees
Labels
A-trait-systemArea: Trait systemArea: Trait systemP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.