@@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId;
1616use rustc_macros:: { HashStable , TyDecodable , TyEncodable , TypeFoldable , extension} ;
1717use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
1818use rustc_type_ir:: TyKind :: * ;
19+ use rustc_type_ir:: solve:: SizedTraitKind ;
1920use rustc_type_ir:: { self as ir, BoundVar , CollectAndApply , DynKind , TypeVisitableExt , elaborate} ;
2021use tracing:: instrument;
2122use ty:: util:: { AsyncDropGlueMorphology , IntTypeExt } ;
@@ -1783,7 +1784,7 @@ impl<'tcx> Ty<'tcx> {
17831784 let Some ( pointee_ty) = self . builtin_deref ( true ) else {
17841785 bug ! ( "Type {self:?} is not a pointer or reference type" )
17851786 } ;
1786- if pointee_ty. is_trivially_sized ( tcx) {
1787+ if pointee_ty. has_trivial_sizedness ( tcx, SizedTraitKind :: Sized ) {
17871788 tcx. types . unit
17881789 } else {
17891790 match pointee_ty. ptr_metadata_ty_or_tail ( tcx, |x| x) {
@@ -1886,17 +1887,16 @@ impl<'tcx> Ty<'tcx> {
18861887 }
18871888 }
18881889
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` .
18901891 ///
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.
18931894 ///
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 {
19001900 match self . kind ( ) {
19011901 ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
19021902 | ty:: Uint ( _)
@@ -1919,20 +1919,36 @@ impl<'tcx> Ty<'tcx> {
19191919 | ty:: Error ( _)
19201920 | ty:: Dynamic ( _, _, ty:: DynStar ) => true ,
19211921
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+ } ,
19231931
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 ) ) ,
19251933
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+ }
19291945
19301946 ty:: Alias ( ..) | ty:: Param ( _) | ty:: Placeholder ( ..) | ty:: Bound ( ..) => false ,
19311947
19321948 ty:: Infer ( ty:: TyVar ( _) ) => false ,
19331949
19341950 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 )
19361952 }
19371953 }
19381954 }
0 commit comments