Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. -- <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --(Build fails with an ICE on current stable/beta/nightly on the playground.) <!-- : --<!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Same error message as , though it's unclear whether that issue is related.
Minimized: The trait gets used by the impl for , which leads to the bad monomorphization: The issue is caused by how we handle projections when computing the type. We don't normalize the 'tail' type: which causes us to not create a candidate for the projection type in the tail of (which is ): cc - we need to be normalizing somewhere*, but I'm not exactly sure where the correct place is.
I’m sorry but I don’t think I can help much. I don’t even know what normalizing means precisely. As I mentioned in So the only hint I can offer is: does the code for do something differently? Or is there a reason it’s not affected by this problem?
cc - I'm not quite sure what the proper normalization behavior is. We need to be able to perform this projection during typecheck (e.g. ), so I think we need to try to faillibly normalize the trailing field type here?
Why are we not normalizing? Because we don't want to replace with an inference var?
so I put up a fix for this in . Someone mind reviewing that PR? It's gone some time without being touched. My PR seems to successfully compile both examples linked in this issue. Is it really not sufficient to just normalize during selection? Are there any consequences of normalization failing here, other than giving us errors the regular ambiguity "type annotation needed" errors?

Discussion:
} /// Returns the type of metadata for (potentially fat) pointers to this type. <del> pub fn ptr_metadata_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { // FIXME: should this normalize? let tail = tcx.struct_tail_without_normalization(self); </del> <ins> pub fn ptr_metadata_ty( &'tcx self, tcx: TyCtxt<'tcx>, normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, ) -> Ty<'tcx> { let tail = tcx.struct_tail_with_normalize(self, normalize); </ins> match tail.kind() { // Sized types ty::Infer(ty::IntVar(_) | ty::FloatVar(_))

pub fn struct_tail_with_normalize( self, mut ty: Ty<'tcx>, <del> normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>, </del> <ins> mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, </ins> ) -> Ty<'tcx> { let recursion_limit = self.recursion_limit(); for iteration in 0.. {

// Any type with multiple potential metadata types is therefore not eligible. let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); <del> // FIXME: should this normalize? let tail = selcx.tcx().struct_tail_without_normalization(self_ty); </del> <ins> let tail = selcx.tcx().struct_tail_with_normalize(self_ty, |ty| { normalize_with_depth( selcx, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, ty, ) .value }); </ins> match tail.kind() { ty::Bool | ty::Char

| ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) <del> | ty::Error(_) => false, </del> <ins> | ty::Error(_) => { if tail.has_infer_types() { candidate_set.mark_ambiguous(); } false }, </ins> } } super::ImplSource::Param(..) => {

_: ImplSourcePointeeData, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); <del> let substs = tcx.mk_substs([self_ty.into()].iter()); </del> <ins> let mut obligations = vec![]; let metadata_ty = self_ty.ptr_metadata_ty(tcx, |ty| { normalize_with_depth_to( selcx, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, ty, &mut obligations, ) }); let substs = tcx.mk_substs([self_ty.into()].iter()); </ins> let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); let predicate = ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id }, <del> ty: self_ty.ptr_metadata_ty(tcx), </del> <ins> ty: metadata_ty, </ins> }; confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) <ins> .with_addl_obligations(obligations) </ins> } fn confirm_fn_pointer_candidate<'cx, 'tcx>(

<ins> // run-pass #![feature(ptr_metadata)] use std::alloc::Layout; use std::ptr::Pointee; trait Foo { type Bar; } impl Foo for () { type Bar = (); } struct Wrapper1<T: Foo>(<T as Foo>::Bar); struct Wrapper2<T: Foo>(<Wrapper1<T> as Pointee>::Metadata); fn main() { let _: Wrapper2<()> = Wrapper2(()); let _ = Layout::new::<Wrapper2<()>>(); } </ins>