Skip to content

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

Closed
@eddyb

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)

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