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

ICE with impl Fn alias. #65918

Closed
wdanilo opened this issue Oct 29, 2019 · 14 comments · Fixed by #65989 or #68236
Closed

ICE with impl Fn alias. #65918

wdanilo opened this issue Oct 29, 2019 · 14 comments · Fixed by #65989 or #68236
Labels
A-traits Area: Trait system C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@wdanilo
Copy link

wdanilo commented Oct 29, 2019

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
@Centril Centril added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example O-wasm Target: WASM (WebAssembly), http://webassembly.org/ I-nominated A-traits Area: Trait system labels Oct 29, 2019
@hellow554
Copy link
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

@wdanilo
Copy link
Author

wdanilo commented Oct 29, 2019

@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

@hellow554
Copy link
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 :)

@wdanilo
Copy link
Author

wdanilo commented Oct 29, 2019

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

@hellow554

This comment has been minimized.

@rustbot rustbot added F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` and removed O-wasm Target: WASM (WebAssembly), http://webassembly.org/ labels Oct 29, 2019
@hellow554

This comment has been minimized.

@wdanilo
Copy link
Author

wdanilo commented Oct 29, 2019

@hellow554 thank you for tracking it down ❤️

@hellow554
Copy link
Contributor

@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 ;)

@hellow554
Copy link
Contributor

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.51.al-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.51.al-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`.

@wdanilo wdanilo changed the title Rustc ICE when targetting WASM. ICE with impl Fn alias. Oct 29, 2019
wdanilo added a commit to enso-org/ide that referenced this issue Oct 29, 2019
@Aaron1011
Copy link
Member

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.

@pnkfelix
Copy link
Member

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

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Oct 31, 2019
@Alexendoo Alexendoo removed the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Nov 1, 2019
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Nov 1, 2019
@Centril Centril added the requires-nightly This issue requires a nightly compiler in some way. label Nov 14, 2019
Aaron1011 added a commit to Aaron1011/rust that referenced this issue Dec 2, 2019
When we normalize a type using a ParamEnv with a reveal mode of
RevealMode::All, we will normalize opaque types to their underlying
types (e.g. `type MyOpaque = impl Foo` -> `StructThatImplsFoo`).
However, the ParamEnv may still have predicates referring to the
un-normalized opaque type (e.g. `<T as MyTrait<MyOpaque>>`). This can
cause trait projection to fail, since a type containing normalized
opaque types will not match up with the un-normalized type in the
`ParamEnv`.

To fix this, we now explicitly normalize all opaque types in
caller_bounds of a `ParamEnv` when changing its mode to
`RevealMode::All`. This ensures that all predicatse will refer to the
underlying types of any opaque types involved, allowing them to be
matched up properly during projection. To reflect the fact that
normalization is occuring, `ParamEnv::with_reveal_all` is renamed to
`ParamEnv::with_reveal_all_normalized`

Fixes rust-lang#65918
bors added a commit that referenced this issue Dec 7, 2019
Normalize all opaque types when converting ParamEnv to Reveal::All

When we normalize a type using a ParamEnv with a reveal mode of
RevealMode::All, we will normalize opaque types to their underlying
types (e.g. `type MyOpaque = impl Foo` -> `StructThatImplsFoo`).
However, the ParamEnv may still have predicates referring to the
un-normalized opaque type (e.g. `<T as MyTrait<MyOpaque>>`). This can
cause trait projection to fail, since a type containing normalized
opaque types will not match up with the un-normalized type in the
`ParamEnv`.

To fix this, we now explicitly normalize all opaque types in
caller_bounds of a `ParamEnv` when changing its mode to
`RevealMode::All`. This ensures that all predicatse will refer to the
underlying types of any opaque types involved, allowing them to be
matched up properly during projection. To reflect the fact that
normalization is occuring, `ParamEnv::with_reveal_all` is renamed to
`ParamEnv::with_reveal_all_normalized`

Fixes #65918
Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jun 13, 2020
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 31, 2020
…nikomatsakis

Normalize all opaque types when converting ParamEnv to Reveal::All

When we normalize a type using a ParamEnv with a reveal mode of
RevealMode::All, we will normalize opaque types to their underlying
types (e.g. `type MyOpaque = impl Foo` -> `StructThatImplsFoo`).
However, the ParamEnv may still have predicates referring to the
un-normalized opaque type (e.g. `<T as MyTrait<MyOpaque>>`). This can
cause trait projection to fail, since a type containing normalized
opaque types will not match up with the un-normalized type in the
`ParamEnv`.

To fix this, we now explicitly normalize all opaque types in
caller_bounds of a `ParamEnv` when changing its mode to
`RevealMode::All`. This ensures that all predicatse will refer to the
underlying types of any opaque types involved, allowing them to be
matched up properly during projection. To reflect the fact that
normalization is occuring, `ParamEnv::with_reveal_all` is renamed to
`ParamEnv::with_reveal_all_normalized`

Fixes rust-lang#65918
@bors bors closed this as completed in ac9dfc3 Jul 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
10 participants