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
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:
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
Most helpful comment
Relevant log output:
It looks like
<T as MyFrom<Phantom2<DummyT::<U>>>>is getting normalied to<T as MyFrom<Phantom2<()>>(since the underlying type ofDummyTis()) when we attempt to compute the layout of a type. However, theParamEnvstill contains<T as MyFrom<Phantom2<DummyT::<U>>>>, which will not match with the normalized version.I think the solution is to normalize the
ParamEnvwhen we callwith_reveal_allon it.