@@ -1957,12 +1957,12 @@ impl<'tcx> Ty<'tcx> {
19571957 }
19581958
19591959 /// Returns the type of metadata for (potentially fat) pointers to this type,
1960- /// and a boolean signifying if this is conditional on this type being `Sized` .
1961- pub fn ptr_metadata_ty (
1960+ /// or the struct tail if the metadata type cannot be determined .
1961+ pub fn ptr_metadata_ty_or_tail (
19621962 self ,
19631963 tcx : TyCtxt < ' tcx > ,
19641964 normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
1965- ) -> ( Ty < ' tcx > , bool ) {
1965+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
19661966 let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
19671967 match tail. kind ( ) {
19681968 // Sized types
@@ -1984,31 +1984,47 @@ impl<'tcx> Ty<'tcx> {
19841984 | ty:: Error ( _)
19851985 // Extern types have metadata = ().
19861986 | ty:: Foreign ( ..)
1987- // `dyn*` has no metadata
1987+ // `dyn*` has metadata = ().
19881988 | ty:: Dynamic ( _, _, ty:: DynStar )
1989- // If returned by `struct_tail_without_normalization ` this is a unit struct
1989+ // If returned by `struct_tail_with_normalize ` this is a unit struct
19901990 // without any fields, or not a struct, and therefore is Sized.
19911991 | ty:: Adt ( ..)
1992- // If returned by `struct_tail_without_normalization ` this is the empty tuple,
1992+ // If returned by `struct_tail_with_normalize ` this is the empty tuple,
19931993 // a.k.a. unit type, which is Sized
1994- | ty:: Tuple ( ..) => ( tcx. types . unit , false ) ,
1994+ | ty:: Tuple ( ..) => Ok ( tcx. types . unit ) ,
1995+
1996+ ty:: Str | ty:: Slice ( _) => Ok ( tcx. types . usize ) ,
19951997
1996- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
19971998 ty:: Dynamic ( _, _, ty:: Dyn ) => {
19981999 let dyn_metadata = tcx. require_lang_item ( LangItem :: DynMetadata , None ) ;
1999- ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) , false )
2000- } ,
2000+ Ok ( tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ tail. into ( ) ] ) )
2001+ }
20012002
2002- // type parameters only have unit metadata if they're sized, so return true
2003- // to make sure we double check this during confirmation
2004- ty:: Param ( _) | ty:: Alias ( ..) => ( tcx . types . unit , true ) ,
2003+ // We don't know the metadata of `self`, but it must be equal to the
2004+ // metadata of `tail`.
2005+ ty:: Param ( _) | ty:: Alias ( ..) => Err ( tail ) ,
20052006
20062007 ty:: Infer ( ty:: TyVar ( _) )
20072008 | ty:: Bound ( ..)
20082009 | ty:: Placeholder ( ..)
2009- | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
2010- bug ! ( "`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})" , self , tail)
2011- }
2010+ | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! (
2011+ "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})"
2012+ ) ,
2013+ }
2014+ }
2015+
2016+ /// Returns the type of metadata for (potentially fat) pointers to this type.
2017+ /// Causes an ICE if the metadata type cannot be determined.
2018+ pub fn ptr_metadata_ty (
2019+ self ,
2020+ tcx : TyCtxt < ' tcx > ,
2021+ normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
2022+ ) -> Ty < ' tcx > {
2023+ match self . ptr_metadata_ty_or_tail ( tcx, normalize) {
2024+ Ok ( metadata) => metadata,
2025+ Err ( tail) => bug ! (
2026+ "`ptr_metadata_ty` failed to get metadata for type: {self:?} (tail = {tail:?})"
2027+ ) ,
20122028 }
20132029 }
20142030
0 commit comments