diff options
| author | Michael Goulet <michael@errs.io> | 2022-11-13 21:49:54 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-01-04 00:56:05 +0000 |
| commit | 2011316e596c19a8b5ae8cc00102667c2cdb1ef7 (patch) | |
| tree | 0063c958e4e65c2ba1a7088ffa487d1246629d8b | |
| parent | b25da9ce6dd28d13c85911e0630d019403b7f5f3 (diff) | |
| download | rust-2011316e596c19a8b5ae8cc00102667c2cdb1ef7.tar.gz rust-2011316e596c19a8b5ae8cc00102667c2cdb1ef7.zip | |
Mirror metadata changes in layout sanity check
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 9e0ca44d098..112f15c6f9e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -670,13 +670,24 @@ where }); } - match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { - ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize), - ty::Dynamic(_, _, ty::Dyn) => { - TyMaybeWithLayout::Ty(tcx.mk_imm_ref( + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata = tcx.normalize_erasing_regions( + cx.param_env(), + tcx.mk_projection(metadata_def_id, [pointee]), + ); + + // Map `Metadata = DynMetadata<dyn Trait>` back to a vtable, since it + // offers better information than `std::ptr::metadata::VTable`, + // and we rely on this layout information to trigger a panic in + // `std::mem::uninitialized::<&dyn Trait>()`, for example. + if let ty::Adt(def, substs) = metadata.kind() + && Some(def.did()) == tcx.lang_items().dyn_metadata() + && substs.type_at(0).is_trait() + { + 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 @@ -690,9 +701,36 @@ where tcx.mk_array(Option<fn()>), ]) */ + } else { + metadata } - _ => bug!("TyAndLayout::field({:?}): not applicable", this), - } + } else { + match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { + ty::Slice(_) | ty::Str => tcx.types.usize, + ty::Dynamic(_, _, ty::Dyn) => { + 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({:?}): not applicable", this), + } + }; + + TyMaybeWithLayout::Ty(metadata) } // Arrays and slices. |
