@@ -2710,12 +2710,12 @@ impl<'tcx> Ty<'tcx> {
2710
2710
}
2711
2711
2712
2712
/// 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 (
2715
2715
self ,
2716
2716
tcx : TyCtxt < ' tcx > ,
2717
2717
normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2718
- ) -> ( Ty < ' tcx > , bool ) {
2718
+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
2719
2719
let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
2720
2720
match tail. kind ( ) {
2721
2721
// Sized types
@@ -2739,29 +2739,45 @@ impl<'tcx> Ty<'tcx> {
2739
2739
| ty:: Foreign ( ..)
2740
2740
// `dyn*` has no metadata
2741
2741
| 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
2743
2743
// without any fields, or not a struct, and therefore is Sized.
2744
2744
| 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,
2746
2746
// 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 ) ,
2748
2750
2749
- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
2750
2751
ty:: Dynamic ( _, _, ty:: Dyn ) => {
2751
2752
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
+ }
2754
2755
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 ) ,
2758
2759
2759
2760
ty:: Infer ( ty:: TyVar ( _) )
2760
2761
| ty:: Bound ( ..)
2761
2762
| 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
+ ) ,
2765
2781
}
2766
2782
}
2767
2783
0 commit comments