@@ -1957,12 +1957,12 @@ impl<'tcx> Ty<'tcx> {
1957
1957
}
1958
1958
1959
1959
/// 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 (
1962
1962
self ,
1963
1963
tcx : TyCtxt < ' tcx > ,
1964
1964
normalize : impl FnMut ( Ty < ' tcx > ) -> Ty < ' tcx > ,
1965
- ) -> ( Ty < ' tcx > , bool ) {
1965
+ ) -> Result < Ty < ' tcx > , Ty < ' tcx > > {
1966
1966
let tail = tcx. struct_tail_with_normalize ( self , normalize, || { } ) ;
1967
1967
match tail. kind ( ) {
1968
1968
// Sized types
@@ -1984,31 +1984,47 @@ impl<'tcx> Ty<'tcx> {
1984
1984
| ty:: Error ( _)
1985
1985
// Extern types have metadata = ().
1986
1986
| ty:: Foreign ( ..)
1987
- // `dyn*` has no metadata
1987
+ // `dyn*` has metadata = ().
1988
1988
| 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
1990
1990
// without any fields, or not a struct, and therefore is Sized.
1991
1991
| 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,
1993
1993
// 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 ) ,
1995
1997
1996
- ty:: Str | ty:: Slice ( _) => ( tcx. types . usize , false ) ,
1997
1998
ty:: Dynamic ( _, _, ty:: Dyn ) => {
1998
1999
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
+ }
2001
2002
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 ) ,
2005
2006
2006
2007
ty:: Infer ( ty:: TyVar ( _) )
2007
2008
| ty:: Bound ( ..)
2008
2009
| 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
+ ) ,
2012
2028
}
2013
2029
}
2014
2030
0 commit comments