Closed
Description
// crate dep
trait IsUnit {}
impl IsUnit for () {}
pub trait WithAssoc<'a> {
type Assoc;
}
// The two impls of `Trait` overlap
pub trait Trait {}
impl<T> Trait for T
where
T: 'static,
for<'a> T: WithAssoc<'a>,
for<'a> <T as WithAssoc<'a>>::Assoc: IsUnit,
{
}
impl<T> Trait for Box<T> {}
// root crate
use dep::*;
struct Local;
impl WithAssoc<'_> for Box<Local> {
type Assoc = ();
}
fn impls_trait<T: Trait>() {}
fn main() {
impls_trait::<Box<Local>>();
}
During coherence for<'a> <Box<T> as WithAssoc<'a>>::Assoc: IsUnit
is considered to not hold.
This allows overlapping impls in coherence which is generally considered to be unsound™.
Coherence considers the impls to be disjoint because for<'a> <Box<T> as WithAssoc<'a>>::Assoc: IsUnit,
does not hold. When trying to normalize <Box<T> as WithAssoc<'a>>::Assoc
ends up ambiguous, we keep the projection around. Coherence then considers for<'a> <Box<T> as WithAssoc<'a>>::Assoc: IsUnit
to not have any impl as IsUnit
is a local trait.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Completed