@@ -2279,12 +2279,12 @@ impl<'tcx> Ty<'tcx> {
2279
2279
}
2280
2280
2281
2281
/// 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 (
2284
2284
self ,
2285
2285
tcx : TyCtxt < ' tcx > ,
2286
2286
normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2287
- ) -> ( Ty < ' tcx > , bool ) {
2287
+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
2288
2288
let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
2289
2289
match tail. kind ( ) {
2290
2290
// Sized types
@@ -2307,31 +2307,47 @@ impl<'tcx> Ty<'tcx> {
2307
2307
| ty:: Error ( _)
2308
2308
// Extern types have metadata = ().
2309
2309
| ty:: Foreign ( ..)
2310
- // `dyn*` has no metadata
2310
+ // `dyn*` has metadata = ().
2311
2311
| 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
2313
2313
// without any fields, or not a struct, and therefore is Sized.
2314
2314
| 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,
2316
2316
// 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 ) ,
2318
2320
2319
- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
2320
2321
ty:: Dynamic ( _, _, ty:: Dyn ) => {
2321
2322
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
+ }
2324
2325
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 ) ,
2328
2329
2329
2330
ty:: Infer ( ty:: TyVar ( _) )
2330
2331
| ty:: Bound ( ..)
2331
2332
| 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
+ ) ,
2335
2351
}
2336
2352
}
2337
2353
0 commit comments