@@ -2279,12 +2279,12 @@ impl<'tcx> Ty<'tcx> {
22792279 }
22802280
22812281 /// Returns the type of metadata for (potentially fat) pointers to this type,
2282- /// and a boolean signifying if this is conditional on this type being `Sized` .
2283- pub fn ptr_metadata_ty (
2282+ /// or the struct tail if the metadata type cannot be determined .
2283+ pub fn ptr_metadata_ty_or_tail (
22842284 self ,
22852285 tcx : TyCtxt < ' tcx > ,
22862286 normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2287- ) -> ( Ty < ' tcx > , bool ) {
2287+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
22882288 let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
22892289 match tail. kind ( ) {
22902290 // Sized types
@@ -2307,31 +2307,47 @@ impl<'tcx> Ty<'tcx> {
23072307 | ty:: Error ( _)
23082308 // Extern types have metadata = ().
23092309 | ty:: Foreign ( ..)
2310- // `dyn*` has no metadata
2310+ // `dyn*` has metadata = ().
23112311 | ty:: Dynamic ( _, _, ty:: DynStar )
2312- // If returned by `struct_tail_without_normalization ` this is a unit struct
2312+ // If returned by `struct_tail_with_normalize ` this is a unit struct
23132313 // without any fields, or not a struct, and therefore is Sized.
23142314 | ty:: Adt ( ..)
2315- // If returned by `struct_tail_without_normalization ` this is the empty tuple,
2315+ // If returned by `struct_tail_with_normalize ` this is the empty tuple,
23162316 // a.k.a. unit type, which is Sized
2317- | ty:: Tuple ( ..) => ( tcx. types . unit , false ) ,
2317+ | ty:: Tuple ( ..) => Ok ( tcx. types . unit ) ,
2318+
2319+ ty:: Str | ty:: Slice ( _) => Ok ( tcx. types . usize ) ,
23182320
2319- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
23202321 ty:: Dynamic ( _, _, ty:: Dyn ) => {
23212322 let dyn_metadata = tcx. require_lang_item ( LangItem :: DynMetadata , None ) ;
2322- ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) , false )
2323- } ,
2323+ Ok ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) )
2324+ }
23242325
2325- // type parameters only have unit metadata if they're sized, so return true
2326- // to make sure we double check this during confirmation
2327- ty:: Param ( _) | ty:: Alias ( ..) => ( tcx . types . unit , true ) ,
2326+ // We don't know the metadata of `self`, but it must be equal to the
2327+ // metadata of `tail`.
2328+ ty:: Param ( _) | ty:: Alias ( ..) => Err ( tail ) ,
23282329
23292330 ty:: Infer ( ty:: TyVar ( _) )
23302331 | ty:: Bound ( ..)
23312332 | ty:: Placeholder ( ..)
2332- | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
2333- bug ! ( "`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})" , self , tail)
2334- }
2333+ | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! (
2334+ "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})"
2335+ ) ,
2336+ }
2337+ }
2338+
2339+ /// Returns the type of metadata for (potentially fat) pointers to this type.
2340+ /// Causes an ICE if the metadata type cannot be determined.
2341+ pub fn ptr_metadata_ty (
2342+ self ,
2343+ tcx : TyCtxt < ' tcx > ,
2344+ normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2345+ ) -> Ty < ' tcx > {
2346+ match self . ptr_metadata_ty_or_tail ( tcx, normalize) {
2347+ Ok ( metadata) => metadata,
2348+ Err ( tail) => bug ! (
2349+ "`ptr_metadata_ty` failed to get metadata for type: {self:?} (tail = {tail:?})"
2350+ ) ,
23352351 }
23362352 }
23372353
0 commit comments