Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

the same projection may use different candidates #2

Open
lcnr opened this issue May 2, 2023 · 2 comments
Open

the same projection may use different candidates #2

lcnr opened this issue May 2, 2023 · 2 comments

Comments

@lcnr
Copy link
Owner

lcnr commented May 2, 2023

fn callee<T>(t: <T as Iterator>::Item) -> <T as IntoIterator>::Item
where
    T: Iterator,
{
    t
}

fn caller<T>(t: <T as Iterator>::Item) -> <T as IntoIterator>::Item
where
    T: Iterator + IntoIterator,
{
    callee::<T>(t)
}

here caller uses the IntoIterator ParamEnv candidate while callee uses an impl candidate.

@eddyb
Copy link

eddyb commented May 9, 2023

I believe this shows the same behavior (playground):

pub trait Id {
    type Out;
}

impl<T> Id for T {
    type Out = T;
}

pub fn callee<T>(x: T) -> <T as Id>::Out { x }

pub fn caller<T: Id>(x: T) -> <T as Id>::Out {
    // Uncomment to see what rustc thinks the type `<T as Id>::Out` is.
    // let _: <T as Id>::Out = x;

    callee(x)
}

Uncommenting that let gives an error with:

   = note: expected associated type `<T as Id>::Out`
               found type parameter `T`

@lcnr
Copy link
Owner Author

lcnr commented Oct 21, 2024

normalization via impl and where-bound may result in different types even without impossible where-bounds:

trait Trait {
    type Item;
}
impl<T> Trait for T {
    type Item = T;
}

fn callee<T>(t: T) -> <T as Trait>::Item {
    t
}

fn caller<T: Trait<Item = U>, U>(t: T) -> U {
    callee(t)
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants