@@ -670,13 +670,24 @@ where
670
670
} ) ;
671
671
}
672
672
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 (
677
688
tcx. lifetimes . re_static ,
678
689
tcx. mk_array ( tcx. types . usize , 3 ) ,
679
- ) )
690
+ )
680
691
/* FIXME: use actual fn pointers
681
692
Warning: naively computing the number of entries in the
682
693
vtable by counting the methods on the trait + methods on
@@ -690,9 +701,36 @@ where
690
701
tcx.mk_array(Option<fn()>),
691
702
])
692
703
*/
704
+ } else {
705
+ metadata
693
706
}
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)
696
734
}
697
735
698
736
// Arrays and slices.
0 commit comments