Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

Closed
eddyb opened this issue Jul 28, 2018 · 3 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@eddyb
Copy link
Member

eddyb commented Jul 28, 2018

(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)

@eddyb eddyb added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jul 29, 2018
@eddyb eddyb changed the title ATC-like for<'a> Fn(<X as Trait<'a>>::Type) does not consistently normalize. ATC-like for<'a> Fn(<X as Trait<'a>>::Type) does not consistently normalize (and can ICE). Jul 29, 2018
@earthengine
Copy link

earthengine commented Sep 13, 2018

Duplicate of #53420 (at least the ICE case)?

A lot of analysis wad did in the other issue. Maybe it would help.

I doubt that, in such cases the associate type do normalize at all. My assumption is: In the case that you marked as "working", it is just delayed the normalization to the later stage. So if the later stage consider this is dead code it is passed and compile, otherwise, when it really need to normalize it, run into ICE.

So when called explicitly like f(()), the compiler have no choice but to normalize () with <() as ATC<'_>>::Type. If you instead call(f, ()) though, the compiler checked that the requirement to match the argument can in theory fullfill, but the lifetime parameter was not free in the function body so it can consider this is a late bound. So the normalization is not happen right away.

Later on, when you add the code in main to call with_default, the compiler have to do normalization again, but it is already in codegen (see the backtrace messages) phase, so normalization is unexpected and ICE occurs.

Given all that, I guess a proper solution is to add a "late normalization" pass to normalize any postponed normalization like this.

@eddyb
Copy link
Member Author

eddyb commented Nov 3, 2018

This is a probably a duplicate of #29997 and/or #33364?

@pnkfelix
Copy link
Member

closing as duplicate of #62529, which is where I will try to track future instances of this field of ICE.

Noratrieb added a commit to Noratrieb/rust that referenced this issue Feb 20, 2024
Remove `RefMutL` hack in `proc_macro::bridge`

From what I can tell, rust-lang#52812 is now fixed, so there is no longer any need to keep this hack around.
Noratrieb added a commit to Noratrieb/rust that referenced this issue Feb 20, 2024
Remove `RefMutL` hack in `proc_macro::bridge`

From what I can tell, rust-lang#52812 is now fixed, so there is no longer any need to keep this hack around.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 20, 2024
Rollup merge of rust-lang#121302 - GrigorenkoPV:refmutl, r=bjorn3

Remove `RefMutL` hack in `proc_macro::bridge`

From what I can tell, rust-lang#52812 is now fixed, so there is no longer any need to keep this hack around.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

3 participants