@@ -2710,12 +2710,12 @@ impl<'tcx> Ty<'tcx> {
27102710 }
27112711
27122712 /// Returns the type of metadata for (potentially fat) pointers to this type,
2713- /// and a boolean signifying if this is conditional on this type being `Sized` .
2714- pub fn ptr_metadata_ty (
2713+ /// or the struct tail if the metadata type cannot be determinded .
2714+ pub fn ptr_metadata_ty_or_tail (
27152715 self ,
27162716 tcx : TyCtxt < ' tcx > ,
27172717 normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2718- ) -> ( Ty < ' tcx > , bool ) {
2718+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
27192719 let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
27202720 match tail. kind ( ) {
27212721 // Sized types
@@ -2739,29 +2739,45 @@ impl<'tcx> Ty<'tcx> {
27392739 | ty:: Foreign ( ..)
27402740 // `dyn*` has no metadata
27412741 | ty:: Dynamic ( _, _, ty:: DynStar )
2742- // If returned by `struct_tail_without_normalization ` this is a unit struct
2742+ // If returned by `struct_tail_with_normalize ` this is a unit struct
27432743 // without any fields, or not a struct, and therefore is Sized.
27442744 | ty:: Adt ( ..)
2745- // If returned by `struct_tail_without_normalization ` this is the empty tuple,
2745+ // If returned by `struct_tail_with_normalize ` this is the empty tuple,
27462746 // a.k.a. unit type, which is Sized
2747- | ty:: Tuple ( ..) => ( tcx. types . unit , false ) ,
2747+ | ty:: Tuple ( ..) => Ok ( tcx. types . unit ) ,
2748+
2749+ ty:: Str | ty:: Slice ( _) => Ok ( tcx. types . usize ) ,
27482750
2749- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
27502751 ty:: Dynamic ( _, _, ty:: Dyn ) => {
27512752 let dyn_metadata = tcx. require_lang_item ( LangItem :: DynMetadata , None ) ;
2752- ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) , false )
2753- } ,
2753+ Ok ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) )
2754+ }
27542755
2755- // type parameters only have unit metadata if they're sized, so return true
2756- // to make sure we double check this during confirmation
2757- ty:: Param ( _) | ty:: Alias ( ..) => ( tcx . types . unit , true ) ,
2756+ // We don't know the metadata of `self`, but it must be equal to the
2757+ // metadata of `tail`.
2758+ ty:: Param ( _) | ty:: Alias ( ..) => Err ( tail ) ,
27582759
27592760 ty:: Infer ( ty:: TyVar ( _) )
27602761 | ty:: Bound ( ..)
27612762 | ty:: Placeholder ( ..)
2762- | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
2763- bug ! ( "`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})" , self , tail)
2764- }
2763+ | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! (
2764+ "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})"
2765+ ) ,
2766+ }
2767+ }
2768+
2769+ /// Returns the type of metadata for (potentially fat) pointers to this type.
2770+ /// Causes an ICE if the metadata type cannot be determined.
2771+ pub fn ptr_metadata_ty (
2772+ self ,
2773+ tcx : TyCtxt < ' tcx > ,
2774+ normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2775+ ) -> Ty < ' tcx > {
2776+ match self . ptr_metadata_ty_or_tail ( tcx, normalize) {
2777+ Ok ( metadata) => metadata,
2778+ Err ( tail) => bug ! (
2779+ "`ptr_metadata_ty` failed to get metadata for type: {self:?} (tail = {tail:?})"
2780+ ) ,
27652781 }
27662782 }
27672783
0 commit comments