@@ -670,13 +670,24 @@ where
670670 } ) ;
671671 }
672672
673- match tcx. struct_tail_erasing_lifetimes ( pointee, cx. param_env ( ) ) . kind ( ) {
674- ty:: Slice ( _) | ty:: Str => TyMaybeWithLayout :: Ty ( tcx. types . usize ) ,
675- ty:: Dynamic ( _, _, ty:: Dyn ) => {
676- TyMaybeWithLayout :: Ty ( tcx. mk_imm_ref (
673+ let metadata = if let Some ( metadata_def_id) = tcx. lang_items ( ) . metadata_type ( ) {
674+ let metadata = tcx. normalize_erasing_regions (
675+ cx. param_env ( ) ,
676+ tcx. mk_projection ( metadata_def_id, [ pointee] ) ,
677+ ) ;
678+
679+ // Map `Metadata = DynMetadata<dyn Trait>` back to a vtable, since it
680+ // offers better information than `std::ptr::metadata::VTable`,
681+ // and we rely on this layout information to trigger a panic in
682+ // `std::mem::uninitialized::<&dyn Trait>()`, for example.
683+ if let ty:: Adt ( def, substs) = metadata. kind ( )
684+ && Some ( def. did ( ) ) == tcx. lang_items ( ) . dyn_metadata ( )
685+ && substs. type_at ( 0 ) . is_trait ( )
686+ {
687+ tcx. mk_imm_ref (
677688 tcx. lifetimes . re_static ,
678689 tcx. mk_array ( tcx. types . usize , 3 ) ,
679- ) )
690+ )
680691 /* FIXME: use actual fn pointers
681692 Warning: naively computing the number of entries in the
682693 vtable by counting the methods on the trait + methods on
@@ -690,9 +701,36 @@ where
690701 tcx.mk_array(Option<fn()>),
691702 ])
692703 */
704+ } else {
705+ metadata
693706 }
694- _ => bug ! ( "TyAndLayout::field({:?}): not applicable" , this) ,
695- }
707+ } else {
708+ match tcx. struct_tail_erasing_lifetimes ( pointee, cx. param_env ( ) ) . kind ( ) {
709+ ty:: Slice ( _) | ty:: Str => tcx. types . usize ,
710+ ty:: Dynamic ( _, _, ty:: Dyn ) => {
711+ tcx. mk_imm_ref (
712+ tcx. lifetimes . re_static ,
713+ tcx. mk_array ( tcx. types . usize , 3 ) ,
714+ )
715+ /* FIXME: use actual fn pointers
716+ Warning: naively computing the number of entries in the
717+ vtable by counting the methods on the trait + methods on
718+ all parent traits does not work, because some methods can
719+ be not object safe and thus excluded from the vtable.
720+ Increase this counter if you tried to implement this but
721+ failed to do it without duplicating a lot of code from
722+ other places in the compiler: 2
723+ tcx.mk_tup(&[
724+ tcx.mk_array(tcx.types.usize, 3),
725+ tcx.mk_array(Option<fn()>),
726+ ])
727+ */
728+ }
729+ _ => bug ! ( "TyAndLayout::field({:?}): not applicable" , this) ,
730+ }
731+ } ;
732+
733+ TyMaybeWithLayout :: Ty ( metadata)
696734 }
697735
698736 // Arrays and slices.
0 commit comments