@@ -697,7 +697,7 @@ impl<'tcx> ty::TyS<'tcx> {
697697 /// strange rules like `<T as Foo<'static>>::Bar: Sized` that
698698 /// actually carry lifetime requirements.
699699 pub fn is_sized ( & ' tcx self , tcx_at : TyCtxtAt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> bool {
700- tcx_at. is_sized_raw ( param_env. and ( self ) )
700+ self . is_trivially_sized ( tcx_at . tcx ) || tcx_at. is_sized_raw ( param_env. and ( self ) )
701701 }
702702
703703 /// Checks whether values of this type `T` implement the `Freeze`
@@ -713,7 +713,43 @@ impl<'tcx> ty::TyS<'tcx> {
713713 param_env : ty:: ParamEnv < ' tcx > ,
714714 span : Span ,
715715 ) -> bool {
716- tcx. at ( span) . is_freeze_raw ( param_env. and ( self ) )
716+ self . is_trivially_freeze ( ) || tcx. at ( span) . is_freeze_raw ( param_env. and ( self ) )
717+ }
718+
719+ /// Fast path helper for testing if a type is `Freeze`.
720+ ///
721+ /// Returning true means the type is known to be `Freeze`. Returning
722+ /// `false` means nothing -- could be `Freeze`, might not be.
723+ fn is_trivially_freeze ( & self ) -> bool {
724+ match self . kind {
725+ ty:: Int ( _)
726+ | ty:: Uint ( _)
727+ | ty:: Float ( _)
728+ | ty:: Bool
729+ | ty:: Char
730+ | ty:: Str
731+ | ty:: Never
732+ | ty:: Ref ( ..)
733+ | ty:: RawPtr ( _)
734+ | ty:: FnDef ( ..)
735+ | ty:: Error
736+ | ty:: FnPtr ( _) => true ,
737+ ty:: Tuple ( _) => self . tuple_fields ( ) . all ( Self :: is_trivially_freeze) ,
738+ ty:: Slice ( elem_ty) | ty:: Array ( elem_ty, _) => elem_ty. is_trivially_freeze ( ) ,
739+ ty:: Adt ( ..)
740+ | ty:: Bound ( ..)
741+ | ty:: Closure ( ..)
742+ | ty:: Dynamic ( ..)
743+ | ty:: Foreign ( _)
744+ | ty:: Generator ( ..)
745+ | ty:: GeneratorWitness ( _)
746+ | ty:: Infer ( _)
747+ | ty:: Opaque ( ..)
748+ | ty:: Param ( _)
749+ | ty:: Placeholder ( _)
750+ | ty:: Projection ( _)
751+ | ty:: UnnormalizedProjection ( _) => false ,
752+ }
717753 }
718754
719755 /// If `ty.needs_drop(...)` returns `true`, then `ty` is definitely
0 commit comments