Skip to content

incomplete projection candidate selection for trait objects #101

Open
@lcnr

Description

@lcnr

rust-lang/rust#107887

trait Trait<T> {
    type Assoc: ?Sized;
}

impl Trait<u32> for u32 {
    type Assoc = u16;
}

// This would trigger the check for overlap between automatic and custom impl
// They actually don't overlap so an impl like this should remain possible
// forever.
//
// impl Trait<u64> for dyn Trait<u32, Assoc = u32> {
//     type Assoc =  dyn Trait<u32, Assoc = u32>;
// }
trait Indirect<T: ?Sized> {}
impl Indirect<dyn Trait<u32, Assoc = u32>> for () {}
impl<T: ?Sized> Trait<u64> for T
where
    (): Indirect<T>,
{
    type Assoc = dyn Trait<u32, Assoc = u32>;
}

fn yay<T: Trait<U> + ?Sized, U>(x: &'static T) -> &'static <T as Trait<U>>::Assoc {
    todo!();
}

fn unconstrained<T>() -> T {
    todo!()
}

fn should_be_ambig() {
    let y: &'static dyn Trait<u32, Assoc = u32> = unconstrained();
    let _ = yay::<dyn Trait<u32, Assoc = u32>, _>(y);
    // The current solver incorrectly constrains `_` to `u32` here.
}

fn main() {
    let y: &'static dyn Trait<u32, Assoc = u32> = unconstrained();
    let mut x = yay::<_, u64>(y); // compiles
    // let mut x = yay::<_, _>(y); // errors
    x = y;
}

This example works on stable but will break with the new solver.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions