Skip to content

coherence incorrectly considers unnormalizable_projection: Trait to not hold even if it could #114061

Closed
@lcnr

Description

@lcnr
// 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

Metadata

Metadata

Assignees

Labels

A-associated-itemsArea: Associated items (types, constants & functions)A-coherenceArea: CoherenceC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

Status

Completed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions