Skip to content

ICE with impl Fn alias. #65918

Description

@wdanilo

Hi,
I'm building a project and I'm using the nightly channel. I was testing it with several builds between 2019-09-20 and 2019-10-27, all with the same results – when targetting native, the compilation succeeds, when targetting WASM, we see ICE.

Unfortunately, it was hard for me to minimize the example. Fortunately, the codebase is pretty small. Here is the exact commit: enso-org/ide@9fac17b

After downloading it you can run cargo build and it should succeed. But if you run ./scripts/build.sh (which is 1-line wrapper over wasm-pack), we get:

error: internal compiler error: src/librustc_traits/normalize_erasing_regions.rs:42: could 
not fully normalize `fn(std::result::Result<&mut T, <&mut T as std::convert::TryFrom<&mut 
display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, 
Closure_attribute_on_resize_handler::<OnDirty>>>>::Error>) -> std::option::Option<&mut 
T> {std::result::Result::<&mut T, <&mut T as std::convert::TryFrom<&mut 
display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, 
Closure_attribute_on_resize_handler::<OnDirty>>>>::Error>::ok}`

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:925:9

After commenting out this line, everything should compile OK (WASM target should compile as well): https://github.com/luna/basegl/blob/9fac17b2ae69b5a63b6555529e431db1a740f11a/lib/core/src/lib.rs#L126

EDIT
The backtrace from the compiler is not very helpful:

stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   ...
   61: <unknown>

However, there is some additional info:

query stack during panic:
#0 [normalize_ty_after_erasing_regions] normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [Binder(TraitPredicate(<&'t mut T as std::convert::TryFrom<&'t mut display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, Closure_attribute_on_resize_handler::<OnDirty>>>>)), Binder(TraitPredicate(<&'t mut T as std::marker::Sized>)), Binder(TraitPredicate(<&'t T as std::convert::TryFrom<&'t display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, Closure_attribute_on_resize_handler::<OnDirty>>>>)), Binder(TraitPredicate(<&'t T as std::marker::Sized>)), Binder(TraitPredicate(<OnDirty as std::marker::Sized>)), Binder(TraitPredicate(<T as std::marker::Sized>))], reveal: All, def_id: None }, value: fn(std::result::Result<&mut T, <&mut T as std::convert::TryFrom<&mut display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, Closure_attribute_on_resize_handler::<OnDirty>>>>::Error>) -> std::option::Option<&mut T> {std::result::Result::<&mut T, <&mut T as std::convert::TryFrom<&mut display::symbol::attribute::AnyAttribute<Closure_attribute_on_set_handler::<OnDirty>, Closure_attribute_on_resize_handler::<OnDirty>>>>::Error>::ok} }`
#1 [optimized_mir] processing `<display::symbol::scope::Scope<OnDirty> as std::ops::index::IndexMut<display::symbol::scope::TypedIndex<usize, T>>>::index_mut`
#2 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack

Activity

  1. added
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
    O-wasmTarget: WASM (WebAssembly), http://webassembly.org/
    on Oct 29, 2019
  2. hellow554 commented on Oct 29, 2019

    @hellow554
    Contributor

    That code is a mess! After an hour of digging through the code and removing half of it - the code that triggers the error is:

    https://github.com/luna/basegl/blob/9fac17b2ae69b5a63b6555529e431db1a740f11a/lib/core/src/display/symbol/scope.rs#L146-L153

    I try to produce a MCVE out of it currently

  3. wdanilo commented on Oct 29, 2019

    @wdanilo
    Author

    @hellow554 Yes, the code is in a very work-in-progress state, so there are a lot of places which should be refactored or even removed, sorry for that. The line that I mentioned in my original post calls the function that you have pointed to. The function alone compiles well to WASM. It does not compile when used as follow: https://github.com/luna/basegl/blob/9fac17b2ae69b5a63b6555529e431db1a740f11a/lib/core/src/lib.rs#L126

  4. hellow554 commented on Oct 29, 2019

    @hellow554
    Contributor

    Seems to be related to #[feature(type_alias_impl_trait)]. Here's something small-ish:

    #![feature(type_alias_impl_trait)]
    
    mod attribute {
        use std::convert::TryFrom;
    
        pub struct Attribute<T, OnSet, OnResize> {
            _m: std::marker::PhantomData<(T, OnSet, OnResize)>,
        }
    
        pub enum AnyAttribute<OnSet, OnResize> {
            Varianti32(Attribute<i32, OnSet, OnResize>),
        }
        impl<'t, T, S> TryFrom<&'t AnyAttribute<T, S>> for &'t Attribute<i32, T, S> {
            type Error = ();
            fn try_from(_: &'t AnyAttribute<T, S>) -> Result<&'t Attribute<i32, T, S>, Self::Error> {
                unimplemented!()
            }
        }
    
        pub trait IsAttribute<OnSet, OnResize> {
            fn add_element(&mut self);
            fn len(&self) -> usize;
        }
    }
    
    mod scope {
        use std::convert::{TryFrom, TryInto};
        use std::marker::PhantomData;
        use std::ops::Index;
    
        use crate::attribute as attr;
    
        pub struct TypedIndex<T> {
            pub ix: usize,
            phantom: PhantomData<T>,
        }
    
        impl<T> TypedIndex<T> {
            pub fn new() -> Self {
                unimplemented!()
            }
        }
    
        pub struct Scope<OnDirty> {
            pub attributes: Vec<AnyAttribute<OnDirty>>,
        }
    
        pub type Attribute<T, OnDirty> = attr::Attribute<
            T,
            DummyT<OnDirty>,
            DummyT<OnDirty>,
        >;
    
        pub type AnyAttribute<OnDirty> = attr::AnyAttribute<
            DummyT<OnDirty>,
            DummyT<OnDirty>,
        >;
    
        pub type DummyT<T> = impl Fn();
        pub fn _dummy<T>() -> DummyT<T> { move || {} }
    
        impl<OnDirty> Scope<OnDirty> {
            pub fn ne() -> Self {
                unimplemented!()
            }
        }
    
        impl<T, OnDirty> Index<TypedIndex<T>> for Scope<OnDirty>
        where
            for<'t> &'t T: TryFrom<&'t AnyAttribute<OnDirty>>,
        {
            type Output = T;
            fn index(&self, t: TypedIndex<T>) -> &Self::Output {
                self.attributes.index(t.ix).try_into().ok().unwrap()
            }
        }
    }
    
    pub type Closure_workspace_on_change_handler = impl Fn() + Clone;
    pub fn workspace_on_change_handler() -> Closure_workspace_on_change_handler {
        move || {}
    }
    
    pub type Attribute<T> = scope::Attribute<T, Closure_workspace_on_change_handler>;
    pub type AttributeScope = scope::Scope<Closure_workspace_on_change_handler>;
    
    pub fn start() {
        let pos_id = scope::TypedIndex::new();
        let pt_scope = AttributeScope::ne();
        let _pos: &Attribute<i32> = &pt_scope[pos_id];
    }

    I may give it a shot later, but now I'm gonna head home :)

  5. wdanilo commented on Oct 29, 2019

    @wdanilo
    Author

    @hellow554 that is amazing! I've created yet shorter version (still, there may be things to simplify here):

    #![feature(type_alias_impl_trait)]
    
    use std::convert::{TryFrom, TryInto};
    use std::marker::PhantomData;
    use std::ops::Index;
    
    pub struct TypedIndex<T> {
        pub ix: usize,
        phantom: PhantomData<T>,
    }
    
    impl<T> TypedIndex<T> {
        pub fn new() -> Self {
            unimplemented!()
        }
    }
    
    pub type DummyT<T> = impl Fn();
    pub type Dummy     = impl Fn();
    pub fn _dummy()      -> Dummy     { move || {} }
    pub fn _dummy_t<T>() -> DummyT<T> { move || {} }
    
    pub enum Variants<T> {
        V(A1<T>),
    }
    impl<'t, S> TryFrom<&'t Variants<S>> for &'t A1<S> {
        type Error = ();
        fn try_from(_: &'t Variants<S>) -> Result<&'t A1<S>, Self::Error> {
            unimplemented!()
        }
    }
    
    pub type Variants2<OnDirty> = Variants<DummyT<OnDirty>>;
    
    pub struct Scope<OnDirty> {
        pub attributes: Vec<Variants2<OnDirty>>,
    }
    
    impl<OnDirty> Scope<OnDirty> {
        pub fn new() -> Self {
            unimplemented!()
        }
    }
    
    impl<T, OnDirty> Index<TypedIndex<T>> for Scope<OnDirty>
    where
        for<'t> &'t T: TryFrom<&'t Variants2<OnDirty>>,
    {
        type Output = T;
        fn index(&self, t: TypedIndex<T>) -> &Self::Output {
            self.attributes.index(t.ix).try_into().ok().unwrap()
        }
    }
    
    pub struct A1 <T>  (std::marker::PhantomData<(T)>);
    pub type   A2<T>  = A1  <DummyT<T>>;
    pub type   A3     = A2 <Dummy>;
    pub type   Scope2 = Scope<Dummy>;
    
    pub fn start() {
        let pos_id = TypedIndex::new();
        let pt_scope = Scope2::new();
        let _pos: &A3 = &pt_scope[pos_id];
    }
  6. hellow554 commented on Oct 29, 2019

    @hellow554
  7. added and removed
    O-wasmTarget: WASM (WebAssembly), http://webassembly.org/
    on Oct 29, 2019
  8. hellow554 commented on Oct 29, 2019

    @hellow554
  9. wdanilo commented on Oct 29, 2019

    @wdanilo
    Author

    @hellow554 thank you for tracking it down ❤️

  10. 56 remaining items

  11. added a commit that references this issue on Jun 13, 2020
    b8c6a11
  12. added a commit that references this issue on Jul 22, 2020
    ac9dfc3
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

    A-trait-systemArea: Trait systemC-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions