// 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.
cc rust-lang/trait-system-refactor-initiative#52
During coherence
for<'a> <Box<T> as WithAssoc<'a>>::Assoc: IsUnitis 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>>::Assocends up ambiguous, we keep the projection around. Coherence then considersfor<'a> <Box<T> as WithAssoc<'a>>::Assoc: IsUnitto not have any impl asIsUnitis a local trait.cc rust-lang/trait-system-refactor-initiative#52