@@ -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