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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</detailsNOTE: The bug is found by our work-in-progress compiler testing tool Kira, and the test program is reduced/minimized by <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
does this still panic after ? That only merged a couple days ago so you'll need to update your version of nightly.
Hmm I checked and it does, and it also panics before. So probably unrelated? cc just in case
Note that this works fine on .
Sorry, I accidentally closed the issue. Yes, you are right. It still crashes on the latest nightly version. I have a cron job to update my rust version everyday.
I think we ended up (incorrectly) removing a check in We shouldn't be calling upvarsty if is . This is a separate issue than that was fixed in
claim

Discussion:
} fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout { <del> let tcx = cx.tcx(); let tag_layout = |tag: &Scalar| -> C::TyAndLayout { let layout = Layout::scalar(cx, tag.clone()); MaybeResult::from(Ok(TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx), })) }; </del> <ins> enum TyMaybeWithLayout<C: LayoutOf> { Ty(C::Ty), TyAndLayout(C::TyAndLayout), } </ins> <del> cx.layout_of(match *this.ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::FnPtr(_) | ty::Never | ty::FnDef(..) | ty::GeneratorWitness(..) | ty::Foreign(..) | ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this), // Potentially-fat pointers. ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { assert!(i < this.fields.count()); // Reuse the fat `*T` type as its own thin pointer data field. // This provides information about, e.g., DST struct pointees // (which may have no non-DST form), and will work as long // as the `Abi` or `FieldsShape` is checked by users. if i == 0 { let nil = tcx.mk_unit(); let ptr_ty = if this.ty.is_unsafe_ptr() { tcx.mk_mut_ptr(nil) } else { tcx.mk_mut_ref(tcx.lifetimes.re_static, nil) }; return MaybeResult::from(cx.layout_of(ptr_ty).to_result().map( |mut ptr_layout| { ptr_layout.ty = this.ty; ptr_layout }, )); } </del> <ins> fn ty_and_layout_kind< C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout: MaybeResult<TyAndLayout<'tcx>>> + HasTyCtxt<'tcx> + HasParamEnv<'tcx>, >( this: TyAndLayout<'tcx>, cx: &C, i: usize, ty: C::Ty, ) -> TyMaybeWithLayout<C> { let tcx = cx.tcx(); let tag_layout = |tag: &Scalar| -> C::TyAndLayout { let layout = Layout::scalar(cx, tag.clone()); MaybeResult::from(Ok(TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx), })) }; </ins> <del> match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { ty::Slice(_) | ty::Str => tcx.types.usize, ty::Dynamic(_, _) => { tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3)) /* FIXME: use actual fn pointers Warning: naively computing the number of entries in the vtable by counting the methods on the trait + methods on all parent traits does not work, because some methods can be not object safe and thus excluded from the vtable. Increase this counter if you tried to implement this but failed to do it without duplicating a lot of code from other places in the compiler: 2 tcx.mk_tup(&[ tcx.mk_array(tcx.types.usize, 3), tcx.mk_array(Option<fn()>), ]) */ </del> <ins> match *ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::FnPtr(_) | ty::Never | ty::FnDef(..) | ty::GeneratorWitness(..) | ty::Foreign(..) | ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this), // Potentially-fat pointers. ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { assert!(i < this.fields.count()); // Reuse the fat `*T` type as its own thin pointer data field. // This provides information about, e.g., DST struct pointees // (which may have no non-DST form), and will work as long // as the `Abi` or `FieldsShape` is checked by users. if i == 0 { let nil = tcx.mk_unit(); let ptr_ty = if ty.is_unsafe_ptr() { tcx.mk_mut_ptr(nil) } else { tcx.mk_mut_ref(tcx.lifetimes.re_static, nil) }; return TyMaybeWithLayout::TyAndLayout(MaybeResult::from( cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| { ptr_layout.ty = ty; ptr_layout }), )); </ins> } <del> _ => bug!("TyAndLayout::field_type({:?}): not applicable", this), } } // Arrays and slices. ty::Array(element, _) | ty::Slice(element) => element, ty::Str => tcx.types.u8, // Tuples, generators and closures. ty::Closure(_, ref substs) => substs.as_closure().upvar_tys().nth(i).unwrap(), ty::Generator(def_id, ref substs, _) => match this.variants { Variants::Single { index } => substs .as_generator() .state_tys(def_id, tcx) .nth(index.as_usize()) .unwrap() .nth(i) .unwrap(), Variants::Multiple { ref tag, tag_field, .. } => { if i == tag_field { return tag_layout(tag); </del> <ins> match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize), ty::Dynamic(_, _) => { TyMaybeWithLayout::Ty(tcx.mk_imm_ref( tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3), )) /* FIXME: use actual fn pointers Warning: naively computing the number of entries in the vtable by counting the methods on the trait + methods on all parent traits does not work, because some methods can be not object safe and thus excluded from the vtable. Increase this counter if you tried to implement this but failed to do it without duplicating a lot of code from other places in the compiler: 2 tcx.mk_tup(&[ tcx.mk_array(tcx.types.usize, 3), tcx.mk_array(Option<fn()>), ]) */ } _ => bug!("TyAndLayout::field_type({:?}): not applicable", this), </ins> } <del> substs.as_generator().prefix_tys().nth(i).unwrap() </del> } <del> }, ty::Tuple(tys) => tys[i].expect_ty(), </del> <ins> // Arrays and slices. ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element), ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8), </ins> <del> // ADTs. ty::Adt(def, substs) => { match this.variants { Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs), </del> <ins> // Tuples, generators and closures. ty::Closure(_, ref substs) => { ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty()) } ty::Generator(def_id, ref substs, _) => match this.variants { Variants::Single { index } => TyMaybeWithLayout::Ty( substs .as_generator() .state_tys(def_id, tcx) .nth(index.as_usize()) .unwrap() .nth(i) .unwrap(), ), Variants::Multiple { ref tag, tag_field, .. } => { if i == tag_field { return TyMaybeWithLayout::TyAndLayout(tag_layout(tag)); } TyMaybeWithLayout::Ty(substs.as_generator().prefix_tys().nth(i).unwrap()) } }, ty::Tuple(tys) => TyMaybeWithLayout::Ty(tys[i].expect_ty()), // ADTs. ty::Adt(def, substs) => { match this.variants { Variants::Single { index } => { TyMaybeWithLayout::Ty(def.variants[index].fields[i].ty(tcx, substs)) } </ins> <del> // Discriminant field for enums (where applicable). Variants::Multiple { ref tag, .. } => { assert_eq!(i, 0); return tag_layout(tag); </del> <ins> // Discriminant field for enums (where applicable). Variants::Multiple { ref tag, .. } => { assert_eq!(i, 0); return TyMaybeWithLayout::TyAndLayout(tag_layout(tag)); } </ins> } } <ins> ty::Projection(_) | ty::Bound(..) | ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty), </ins> } <ins> } </ins> <del> ty::Projection(_) | ty::Bound(..) | ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty), </del> <ins> cx.layout_of(match ty_and_layout_kind(this, cx, i, this.ty) { TyMaybeWithLayout::Ty(result) => result, TyMaybeWithLayout::TyAndLayout(result) => return result, </ins> }) }

// Skip lifetime parameters of the enclosing item(s) substs.as_closure().tupled_upvars_ty().visit_with(self); <del> for upvar_ty in substs.as_closure().upvar_tys() { upvar_ty.visit_with(self); } </del> substs.as_closure().sig_as_fn_ptr_ty().visit_with(self); }

// Also skip the witness type, because that has no free regions. substs.as_generator().tupled_upvars_ty().visit_with(self); <del> for upvar_ty in substs.as_generator().upvar_tys() { upvar_ty.visit_with(self); } </del> substs.as_generator().return_ty().visit_with(self); substs.as_generator().yield_ty().visit_with(self); substs.as_generator().resume_ty().visit_with(self);

_ if component.is_copy_modulo_regions(tcx.at(DUMMY_SP), self.param_env) => (), ty::Closure(_, substs) => { <del> for upvar_ty in substs.as_closure().upvar_tys() { queue_type(self, upvar_ty); } </del> <ins> queue_type(self, substs.as_closure().tupled_upvars_ty()); </ins> } ty::Generator(def_id, substs, _) => { let substs = substs.as_generator(); <del> for upvar_ty in substs.upvar_tys() { queue_type(self, upvar_ty); } </del> <ins> queue_type(self, substs.tupled_upvars_ty()); </ins> let witness = substs.witness(); let interior_tys = match witness.kind() {

<ins> fn server() -> impl { //~^ ERROR at least one trait must be specified ().map2(|| "") } trait FilterBase2 { fn map2<F>(self, F) -> Map2<F> {} //~^ ERROR mismatched types //~^^ ERROR the size for values of type `Self` cannot be known at compilation time } struct Map2<Segment2> { _func: F, //~^ ERROR cannot find type `F` in this scope } impl<F> FilterBase2 for F {} fn main() {} </ins>

<ins> error: at least one trait must be specified --> $DIR/issue-78720.rs:1:16 | LL | fn server() -> impl { |                ^^^^ error[E0412]: cannot find type `F` in this scope --> $DIR/issue-78720.rs:13:12 | LL |     _func: F, |            ^ | ::: $SRC_DIR/core/src/ops/function.rs:LL:COL | LL | pub trait Fn<Args>: FnMut<Args> { | ------------------------------- similarly named trait `Fn` defined here | help: a trait with a similar name exists | LL |     _func: Fn, |            ^^ help: you might be missing a type parameter | LL | struct Map2<Segment2, F> { |                     ^^^ error[E0308]: mismatched types --> $DIR/issue-78720.rs:7:36 | LL |     fn map2<F>(self, F) -> Map2<F> {} |                                    ^^ expected struct `Map2`, found `()` | = note: expected struct `Map2<F>` found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/issue-78720.rs:7:16 | LL |     fn map2<F>(self, F) -> Map2<F> {} |                ^^^^ doesn't have a size known at compile-time | = help: unsized fn params are gated as an unstable feature help: consider further restricting `Self` | LL |     fn map2<F>(self, F) -> Map2<F> where Self: Sized {} |                                    ^^^^^^^^^^^^^^^^^ help: function arguments must have a statically known size, borrowed types always have a known size | LL |     fn map2<F>(&self, F) -> Map2<F> {} |                ^ error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. </ins>