@@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId;
16
16
use rustc_macros:: { HashStable , TyDecodable , TyEncodable , TypeFoldable , extension} ;
17
17
use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
18
18
use rustc_type_ir:: TyKind :: * ;
19
+ use rustc_type_ir:: solve:: SizedTraitKind ;
19
20
use rustc_type_ir:: { self as ir, BoundVar , CollectAndApply , DynKind , TypeVisitableExt , elaborate} ;
20
21
use tracing:: instrument;
21
22
use ty:: util:: { AsyncDropGlueMorphology , IntTypeExt } ;
@@ -1783,7 +1784,7 @@ impl<'tcx> Ty<'tcx> {
1783
1784
let Some ( pointee_ty) = self . builtin_deref ( true ) else {
1784
1785
bug ! ( "Type {self:?} is not a pointer or reference type" )
1785
1786
} ;
1786
- if pointee_ty. is_trivially_sized ( tcx) {
1787
+ if pointee_ty. has_trivial_sizedness ( tcx, SizedTraitKind :: Sized ) {
1787
1788
tcx. types . unit
1788
1789
} else {
1789
1790
match pointee_ty. ptr_metadata_ty_or_tail ( tcx, |x| x) {
@@ -1886,17 +1887,16 @@ impl<'tcx> Ty<'tcx> {
1886
1887
}
1887
1888
}
1888
1889
1889
- /// Fast path helper for testing if a type is `Sized`.
1890
+ /// Fast path helper for testing if a type is `Sized`, `MetaSized` or `PointeeSized` .
1890
1891
///
1891
- /// Returning true means the type is known to be sized . Returning
1892
- /// `false` means nothing -- could be sized, might not be.
1892
+ /// Returning true means the type is known to implement the sizedness trait . Returning `false`
1893
+ /// means nothing -- could be sized, might not be.
1893
1894
///
1894
- /// Note that we could never rely on the fact that a type such as `[_]` is
1895
- /// trivially `!Sized` because we could be in a type environment with a
1896
- /// bound such as `[_]: Copy`. A function with such a bound obviously never
1897
- /// can be called, but that doesn't mean it shouldn't typecheck. This is why
1898
- /// this method doesn't return `Option<bool>`.
1899
- pub fn is_trivially_sized ( self , tcx : TyCtxt < ' tcx > ) -> bool {
1895
+ /// Note that we could never rely on the fact that a type such as `[_]` is trivially `!Sized`
1896
+ /// because we could be in a type environment with a bound such as `[_]: Copy`. A function with
1897
+ /// such a bound obviously never can be called, but that doesn't mean it shouldn't typecheck.
1898
+ /// This is why this method doesn't return `Option<bool>`.
1899
+ pub fn has_trivial_sizedness ( self , tcx : TyCtxt < ' tcx > , sizedness : SizedTraitKind ) -> bool {
1900
1900
match self . kind ( ) {
1901
1901
ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
1902
1902
| ty:: Uint ( _)
@@ -1919,20 +1919,36 @@ impl<'tcx> Ty<'tcx> {
1919
1919
| ty:: Error ( _)
1920
1920
| ty:: Dynamic ( _, _, ty:: DynStar ) => true ,
1921
1921
1922
- ty:: Str | ty:: Slice ( _) | ty:: Dynamic ( _, _, ty:: Dyn ) | ty:: Foreign ( ..) => false ,
1922
+ ty:: Str | ty:: Slice ( _) | ty:: Dynamic ( _, _, ty:: Dyn ) => match sizedness {
1923
+ SizedTraitKind :: Sized => false ,
1924
+ SizedTraitKind :: MetaSized | SizedTraitKind :: PointeeSized => true ,
1925
+ } ,
1926
+
1927
+ ty:: Foreign ( ..) => match sizedness {
1928
+ SizedTraitKind :: Sized | SizedTraitKind :: MetaSized => false ,
1929
+ SizedTraitKind :: PointeeSized => true ,
1930
+ } ,
1923
1931
1924
- ty:: Tuple ( tys) => tys. last ( ) . is_none_or ( |ty| ty. is_trivially_sized ( tcx) ) ,
1932
+ ty:: Tuple ( tys) => tys. last ( ) . is_none_or ( |ty| ty. has_trivial_sizedness ( tcx, sizedness ) ) ,
1925
1933
1926
- ty:: Adt ( def, args) => def
1927
- . sized_constraint ( tcx)
1928
- . is_none_or ( |ty| ty. instantiate ( tcx, args) . is_trivially_sized ( tcx) ) ,
1934
+ ty:: Adt ( def, args) => {
1935
+ let constraint = match sizedness {
1936
+ SizedTraitKind :: Sized => def. sized_constraint ( tcx) ,
1937
+ SizedTraitKind :: MetaSized => def. meta_sized_constraint ( tcx) ,
1938
+ SizedTraitKind :: PointeeSized => def. pointee_sized_constraint ( tcx) ,
1939
+ } ;
1940
+
1941
+ constraint. is_none_or ( |ty| {
1942
+ ty. instantiate ( tcx, args) . has_trivial_sizedness ( tcx, sizedness)
1943
+ } )
1944
+ }
1929
1945
1930
1946
ty:: Alias ( ..) | ty:: Param ( _) | ty:: Placeholder ( ..) | ty:: Bound ( ..) => false ,
1931
1947
1932
1948
ty:: Infer ( ty:: TyVar ( _) ) => false ,
1933
1949
1934
1950
ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
1935
- bug ! ( "`is_trivially_sized ` applied to unexpected type: {:?}" , self )
1951
+ bug ! ( "`has_trivial_sizedness ` applied to unexpected type: {:?}" , self )
1936
1952
}
1937
1953
}
1938
1954
}
0 commit comments