Skip to content

ATC-like for<'a> Fn(<X as Trait<'a>>::Type) does not consistently normalize (and can ICE). #52812

Description

@eddyb

(try on playground)

trait ATC<'a> {
    type Type: Sized;
}

trait WithDefault: for<'a> ATC<'a> {
    fn with_default<F: for<'a> Fn(<Self as ATC<'a>>::Type)>(f: F);
}

fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(<T as ATC<'a>>::Type)>(
    f: F,
    x: <T as ATC<'b>>::Type,
) {
    f(x);
}

impl<'a> ATC<'a> for () {
    type Type = Self;
}

impl WithDefault for () {
    fn with_default<F: for<'a> Fn(<Self as ATC<'a>>::Type)>(f: F) {
        // Errors with a bogus type mismatch.
        //f(());
        // Going through another generic function works fine.
        call(f, ());
    }
}

fn main() {
    // <()>::with_default(|_| {});
}

As you can see, calling f directly doesn't instantiate the HRTB (even though it needs to AFAIK) or if it does it doesn't normalize the resulting bound, whereas going through call normalizes the instantiated argument types of call, while call's definition can be type-checked as-is.

EDIT: you can also get an ICE by uncommenting the use in main:

error: internal compiler error: librustc/traits/trans/mod.rs:68: Encountered error `OutputTypeParameterMismatch(
    Binder(<[closure@src/main.rs:30:24: 30:30] as std::ops::Fn<(<() as ATC<'_>>::Type,)>>),
    Binder(<[closure@src/main.rs:30:24: 30:30] as std::ops::Fn<((),)>>),
    Sorts(ExpectedFound { expected: (), found: <() as ATC<'_>>::Type })
)` selecting `Binder(<[closure@src/main.rs:30:24: 30:30] as std::ops::Fn<((),)>>)` during trans

cc @nikomatsakis (this might be a duplicate)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions