Rust: ICE with impl Fn alias.

Created on 29 Oct 2019  ·  14Comments  ·  Source: rust-lang/rust

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: https://github.com/luna/basegl/commit/9fac17b2ae69b5a63b6555529e431db1a740f11a

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
A-traits C-bug F-type_alias_impl_trait I-ICE P-high T-compiler glacier requires-nightly

Most helpful comment

Relevant log output:

[DEBUG rustc::traits::query::normalize] QueryNormalizer: c_data = Canonical {
        max_universe: U0,
        variables: [],
        value: ParamEnvAnd {
            param_env: ParamEnv {
                caller_bounds: [
                    Binder(
                        TraitPredicate(<U as std::marker::Sized>),
                    ),
                    Binder(
                        TraitPredicate(<T as MyFrom<Phantom2<DummyT::<U>>>>),
                    ),
                    Binder(
                        TraitPredicate(<T as std::marker::Sized>),
                    ),
                ],
                reveal: All,
                def_id: None,
            },
            value: ProjectionTy {
                substs: [
                    T,
                    Phantom2<()>,
                ],
                item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]),
            },
        },
    }
[DEBUG rustc::traits::query::normalize] QueryNormalizer: orig_values = OriginalQueryValues {
        universe_map: [
            U0,
        ],
        var_values: [],
    }
[DEBUG rustc::traits::project] opt_normalize_projection_type(projection_ty=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0)
[DEBUG rustc::traits::project] project(obligation=Obligation(predicate=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0))
[DEBUG rustc::traits::project] project: obligation_trait_ref=<T as MyFrom<Phantom2<()>>>
[DEBUG rustc::traits::project] assemble_candidates_from_param_env(..)
[DEBUG rustc::traits::project] assemble_candidates_from_predicates(obligation=Obligation(predicate=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<U as std::marker::Sized>))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<DummyT::<U>>>>))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<T as std::marker::Sized>))
[DEBUG rustc::traits::project] assemble_candidates_from_trait_def(..)
[DEBUG rustc::traits::select] select(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] candidate_from_obligation(cache_fresh_trait_pred=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), obligation=TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)))
[DEBUG rustc::traits::select] is_knowable(intercrate=None)
[DEBUG rustc::traits::select] assemble_candidates_for_trait_alias(self_ty=T)
[DEBUG rustc::traits::select] assemble_candidates_from_impls(obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] assemble_candidates_from_object_ty(self_ty=T)
[DEBUG rustc::traits::select] assemble_candidates_for_projected_tys(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] assemble_candidates_from_caller_bounds(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] match_poly_trait_ref: obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0) poly_trait_ref=Binder(<T as MyFrom<Phantom2<DummyT::<U>>>>)
[DEBUG rustc::traits::select] assemble_candidates_from_auto_impls(self_ty=T)
[DEBUG rustc::traits::select] candidate list size: 0
[DEBUG rustc::traits::select] assembled 0 candidates for TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)): []
[DEBUG rustc::traits::select] winnowed to 0 candidates for TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)): []
[DEBUG rustc::traits::select] CACHE MISS: SELECT(Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)))=Err(Unimplemented)
[DEBUG rustc::traits::select] insert_candidate_cache(trait_ref=<T as MyFrom<Phantom2<()>>>, candidate=Err(Unimplemented)) local
[DEBUG rustc::traits::project] assemble_candidates_from_impls: selection error Unimplemented
[DEBUG rustc::traits::project] opt_normalize_projection_type: ERROR
[DEBUG rustc::traits::fulfill] register_predicate_obligation(obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::fulfill] select(obligation-forest-size=1)
[DEBUG rustc::traits::fulfill] select: starting another iteration
[DEBUG rustc::traits::fulfill] process_obligation: obligation = Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0) cause = ObligationCause { span: tait_normalize.rs:1:1: 1:1, body_id: HirId { owner: DefIndex(0), local_id: 4294967040 }, code: MiscObligation }
[DEBUG rustc::traits::select] select(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] candidate_from_obligation(cache_fresh_trait_pred=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), obligation=TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)))
[DEBUG rustc::traits::select] CACHE HIT: SELECT(Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)))=Err(Unimplemented)
[INFO  rustc::traits::fulfill] selecting trait `Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>))` at depth 0 yielded Err
[DEBUG rustc::traits::fulfill] select: outcome=Outcome {
        completed: None,
        errors: [
            Error {
                error: Unimplemented,
                backtrace: [
                    PendingPredicateObligation {
                        obligation: Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0),
                        stalled_on: [],
                    },
                ],
            },
        ],
        stalled: false,
    }
[DEBUG rustc::traits::fulfill] select: starting another iteration
[DEBUG rustc::traits::fulfill] select: outcome=Outcome {
        completed: None,
        errors: [],
        stalled: true,
    }
[DEBUG rustc::traits::fulfill] select(0 predicates remaining, 1 errors) done

It looks like <T as MyFrom<Phantom2<DummyT::<U>>>> is getting normalied to <T as MyFrom<Phantom2<()>> (since the underlying type of DummyT is ()) when we attempt to compute the layout of a type. However, the ParamEnv still contains <T as MyFrom<Phantom2<DummyT::<U>>>>, which will not match with the normalized version.

I think the solution is to normalize the ParamEnv when we call with_reveal_all on it.

All 14 comments

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

@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

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

@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];
}

@rustbot modify labels: -O-wasm +F-type_alias_impl_trait

< 50 loc :tada:

#![feature(type_alias_impl_trait)]

use std::convert::{TryFrom, TryInto};
use std::marker::PhantomData;
use std::ops::Index;

type DummyT<T> = impl Fn();
fn _dummy_t<T>() -> DummyT<T> {
    || {}
}

struct Phantom<T>(PhantomData<T>);
struct Phantom2<T>(PhantomData<T>);
struct Scope<T>(Phantom2<DummyT<T>>);

impl<'t, S> TryFrom<&'t Phantom2<S>> for &'t Phantom<S> {
    type Error = ();
    fn try_from(_: &'t Phantom2<S>) -> Result<&'t Phantom<S>, Self::Error> {
        unimplemented!()
    }
}

impl<T> Scope<T> {
    fn new() -> Self {
        unimplemented!()
    }
}

impl<T, U> Index<Phantom<T>> for Scope<U>
where
    for<'t> &'t T: TryFrom<&'t Phantom2<DummyT<U>>>,
{
    type Output = T;
    fn index(&self, _: Phantom<T>) -> &Self::Output {
        (&self.0).try_into().ok().unwrap()
    }
}

fn main() {
    let pos_id = Phantom(PhantomData);
    let pt_scope = Scope::<i32>::new();
    let _pos: &Phantom<DummyT<i32>> = &pt_scope[pos_id];
}

@hellow554 thank you for tracking it down ❤️

@wdanilo could you please change the title of this issue to something different, e.g. "ICE with impl Fn alias"? It's not about WASM anymore ;)

Because a lot has changed, here's a summary:


MCVE

#![feature(type_alias_impl_trait)]

use std::marker::PhantomData;

/* copied Index and TryFrom for convinience (and simplicity) */
trait MyIndex<T> {
    type O;
    fn my_index(self) -> Self::O;
}
trait MyFrom<T>: Sized {
    type Error;
    fn my_from(value: T) -> Result<Self, Self::Error>;
}

/* MCVE starts here */
trait F {}
impl F for () {}
type DummyT<T> = impl F;
fn _dummy_t<T>() -> DummyT<T> {}

struct Phantom1<T>(PhantomData<T>);
struct Phantom2<T>(PhantomData<T>);
struct Scope<T>(Phantom2<DummyT<T>>);

impl<T> Scope<T> {
    fn new() -> Self {
        unimplemented!()
    }
}

impl<T> MyFrom<Phantom2<T>> for Phantom1<T> {
    type Error = ();
    fn my_from(_: Phantom2<T>) -> Result<Self, Self::Error> {
        unimplemented!()
    }
}

impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {
    type O = T;
    fn my_index(self) -> Self::O {
        MyFrom::my_from(self.0).ok().unwrap()
    }
}

fn main() {
    let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
}


Backtrace

error: internal compiler error: src/librustc_traits/normalize_erasing_regions.rs:42: could not fully normalize `fn(std::result::Result<T, <T as MyFrom<Phantom2<DummyT::<U>>>>::Error>) -> std::option::Option<T> {std::result::Result::<T, <T as MyFrom<Phantom2<DummyT::<U>>>>::Error>::ok}`

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:925:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:188
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:205
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:468
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::bug
  14: rustc_errors::Handler::bug
  15: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc::ty::context::tls::with_opt::{{closure}}
  17: rustc::ty::context::tls::with_context_opt
  18: rustc::ty::context::tls::with_opt
  19: rustc::util::bug::opt_span_bug_fmt
  20: rustc::util::bug::bug_fmt
  21: rustc::ty::context::GlobalCtxt::enter_local
  22: rustc_traits::normalize_erasing_regions::normalize_ty_after_erasing_regions
  23: rustc::ty::query::__query_compute::normalize_ty_after_erasing_regions
  24: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::normalize_ty_after_erasing_regions>::compute
  25: rustc::dep_graph::graph::DepGraph::with_task_impl
  26: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  27: rustc::traits::query::normalize_erasing_regions::<impl rustc::ty::context::TyCtxt>::normalize_erasing_regions
  28: <rustc::ty::layout::LayoutCx<rustc::ty::query::TyCtxtAt> as rustc_target::abi::LayoutOf>::layout_of
  29: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_const_to_op
  30: rustc_mir::transform::const_prop::ConstPropagator::eval_constant
  31: <rustc_mir::transform::const_prop::ConstPropagator as rustc::mir::visit::MutVisitor>::visit_terminator
  32: <rustc_mir::transform::const_prop::ConstProp as rustc_mir::transform::MirPass>::run_pass
  33: rustc_mir::transform::run_passes
  34: rustc_mir::transform::run_optimization_passes
  35: rustc_mir::transform::optimized_mir
  36: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::optimized_mir>::compute
  37: rustc::dep_graph::graph::DepGraph::with_task_impl
  38: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  39: rustc_mir::monomorphize::collector::collect_items_rec
  40: rustc_mir::monomorphize::collector::collect_items_rec
  41: rustc_mir::monomorphize::collector::collect_crate_mono_items::{{closure}}
  42: rustc::util::common::time
  43: rustc_mir::monomorphize::collector::collect_crate_mono_items
  44: rustc::util::common::time
  45: rustc_mir::monomorphize::partitioning::collect_and_partition_mono_items
  46: rustc::ty::query::__query_compute::collect_and_partition_mono_items
  47: rustc::dep_graph::graph::DepGraph::with_task_impl
  48: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  49: rustc_codegen_ssa::base::codegen_crate
  50: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate
  51: rustc_interface::passes::start_codegen::{{closure}}
  52: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  53: rustc_interface::passes::create_global_ctxt::{{closure}}
  54: rustc_interface::queries::Query<T>::compute
  55: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::ongoing_codegen
  56: rustc_interface::interface::run_compiler_in_existing_thread_pool
  57: std::thread::local::LocalKey<T>::with
  58: scoped_tls::ScopedKey<T>::set
  59: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.40.0-nightly (b497e1899 2019-10-28) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [normalize_ty_after_erasing_regions] normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [Binder(TraitPredicate(<U as std::marker::Sized>)), Binder(TraitPredicate(<T as MyFrom<Phantom2<DummyT::<U>>>>)), Binder(TraitPredicate(<T as std::marker::Sized>))], reveal: All, def_id: None }, value: fn(std::result::Result<T, <T as MyFrom<Phantom2<DummyT::<U>>>>::Error>) -> std::option::Option<T> {std::result::Result::<T, <T as MyFrom<Phantom2<DummyT::<U>>>>::Error>::ok} }`
#1 [optimized_mir] processing `<Scope<U> as MyIndex<Phantom1<T>>>::my_index`
#2 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: aborting due to previous error

error: could not compile `playground`.

Relevant log output:

[DEBUG rustc::traits::query::normalize] QueryNormalizer: c_data = Canonical {
        max_universe: U0,
        variables: [],
        value: ParamEnvAnd {
            param_env: ParamEnv {
                caller_bounds: [
                    Binder(
                        TraitPredicate(<U as std::marker::Sized>),
                    ),
                    Binder(
                        TraitPredicate(<T as MyFrom<Phantom2<DummyT::<U>>>>),
                    ),
                    Binder(
                        TraitPredicate(<T as std::marker::Sized>),
                    ),
                ],
                reveal: All,
                def_id: None,
            },
            value: ProjectionTy {
                substs: [
                    T,
                    Phantom2<()>,
                ],
                item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]),
            },
        },
    }
[DEBUG rustc::traits::query::normalize] QueryNormalizer: orig_values = OriginalQueryValues {
        universe_map: [
            U0,
        ],
        var_values: [],
    }
[DEBUG rustc::traits::project] opt_normalize_projection_type(projection_ty=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0)
[DEBUG rustc::traits::project] project(obligation=Obligation(predicate=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0))
[DEBUG rustc::traits::project] project: obligation_trait_ref=<T as MyFrom<Phantom2<()>>>
[DEBUG rustc::traits::project] assemble_candidates_from_param_env(..)
[DEBUG rustc::traits::project] assemble_candidates_from_predicates(obligation=Obligation(predicate=ProjectionTy { substs: [T, Phantom2<()>], item_def_id: DefId(0:19 ~ tait_normalize[317d]::MyFrom[0]::Error[0]) }, depth=0))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<U as std::marker::Sized>))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<DummyT::<U>>>>))
[DEBUG rustc::traits::project] assemble_candidates_from_predicates: predicate=Binder(TraitPredicate(<T as std::marker::Sized>))
[DEBUG rustc::traits::project] assemble_candidates_from_trait_def(..)
[DEBUG rustc::traits::select] select(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] candidate_from_obligation(cache_fresh_trait_pred=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), obligation=TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)))
[DEBUG rustc::traits::select] is_knowable(intercrate=None)
[DEBUG rustc::traits::select] assemble_candidates_for_trait_alias(self_ty=T)
[DEBUG rustc::traits::select] assemble_candidates_from_impls(obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] assemble_candidates_from_object_ty(self_ty=T)
[DEBUG rustc::traits::select] assemble_candidates_for_projected_tys(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] assemble_candidates_from_caller_bounds(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] match_poly_trait_ref: obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0) poly_trait_ref=Binder(<T as MyFrom<Phantom2<DummyT::<U>>>>)
[DEBUG rustc::traits::select] assemble_candidates_from_auto_impls(self_ty=T)
[DEBUG rustc::traits::select] candidate list size: 0
[DEBUG rustc::traits::select] assembled 0 candidates for TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)): []
[DEBUG rustc::traits::select] winnowed to 0 candidates for TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)): []
[DEBUG rustc::traits::select] CACHE MISS: SELECT(Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)))=Err(Unimplemented)
[DEBUG rustc::traits::select] insert_candidate_cache(trait_ref=<T as MyFrom<Phantom2<()>>>, candidate=Err(Unimplemented)) local
[DEBUG rustc::traits::project] assemble_candidates_from_impls: selection error Unimplemented
[DEBUG rustc::traits::project] opt_normalize_projection_type: ERROR
[DEBUG rustc::traits::fulfill] register_predicate_obligation(obligation=Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::fulfill] select(obligation-forest-size=1)
[DEBUG rustc::traits::fulfill] select: starting another iteration
[DEBUG rustc::traits::fulfill] process_obligation: obligation = Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0) cause = ObligationCause { span: tait_normalize.rs:1:1: 1:1, body_id: HirId { owner: DefIndex(0), local_id: 4294967040 }, code: MiscObligation }
[DEBUG rustc::traits::select] select(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0))
[DEBUG rustc::traits::select] candidate_from_obligation(cache_fresh_trait_pred=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), obligation=TraitObligationStack(Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0)))
[DEBUG rustc::traits::select] CACHE HIT: SELECT(Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)))=Err(Unimplemented)
[INFO  rustc::traits::fulfill] selecting trait `Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>))` at depth 0 yielded Err
[DEBUG rustc::traits::fulfill] select: outcome=Outcome {
        completed: None,
        errors: [
            Error {
                error: Unimplemented,
                backtrace: [
                    PendingPredicateObligation {
                        obligation: Obligation(predicate=Binder(TraitPredicate(<T as MyFrom<Phantom2<()>>>)), depth=0),
                        stalled_on: [],
                    },
                ],
            },
        ],
        stalled: false,
    }
[DEBUG rustc::traits::fulfill] select: starting another iteration
[DEBUG rustc::traits::fulfill] select: outcome=Outcome {
        completed: None,
        errors: [],
        stalled: true,
    }
[DEBUG rustc::traits::fulfill] select(0 predicates remaining, 1 errors) done

It looks like <T as MyFrom<Phantom2<DummyT::<U>>>> is getting normalied to <T as MyFrom<Phantom2<()>> (since the underlying type of DummyT is ()) when we attempt to compute the layout of a type. However, the ParamEnv still contains <T as MyFrom<Phantom2<DummyT::<U>>>>, which will not match with the normalized version.

I think the solution is to normalize the ParamEnv when we call with_reveal_all on it.

triage: has PR. marking P-high, removing I-nominated.

It seems the ICE (with MCVE) has been fixed in latest nightly.

It has been fixed by #67000, marked as E-needstest

Reopening due to #68679

Was this page helpful?
0 / 5 - 0 ratings