@@ -15,14 +15,13 @@ use hir::map::DefPathData;
1515use infer:: InferCtxt ;
1616use ich:: { StableHashingContext , NodeIdHashingMode } ;
1717use traits:: { self , Reveal } ;
18- use ty:: { self , Ty , TyCtxt , TypeFlags , TypeFoldable } ;
18+ use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
1919use ty:: ParameterEnvironment ;
2020use ty:: fold:: TypeVisitor ;
2121use ty:: layout:: { Layout , LayoutError } ;
2222use ty:: subst:: { Subst , Kind } ;
2323use ty:: TypeVariants :: * ;
2424use util:: common:: ErrorReported ;
25- use util:: nodemap:: FxHashSet ;
2625use middle:: lang_items;
2726
2827use rustc_const_math:: { ConstInt , ConstIsize , ConstUsize } ;
@@ -754,110 +753,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
754753 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
755754 param_env : ty:: ParameterEnvironment < ' tcx > )
756755 -> bool {
757- if self . flags . get ( ) . intersects ( TypeFlags :: NEEDS_DROP_CACHED ) {
758- return self . flags . get ( ) . intersects ( TypeFlags :: NEEDS_DROP ) ;
759- }
760-
761- self . needs_drop_uncached ( tcx, param_env, & mut FxHashSet ( ) )
762- }
763-
764- fn needs_drop_inner ( & ' tcx self ,
765- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
766- param_env : ty:: ParameterEnvironment < ' tcx > ,
767- stack : & mut FxHashSet < Ty < ' tcx > > )
768- -> bool {
769- if self . flags . get ( ) . intersects ( TypeFlags :: NEEDS_DROP_CACHED ) {
770- return self . flags . get ( ) . intersects ( TypeFlags :: NEEDS_DROP ) ;
771- }
772-
773- // This should be reported as an error by `check_representable`.
774- //
775- // Consider the type as not needing drop in the meanwhile to avoid
776- // further errors.
777- if let Some ( _) = stack. replace ( self ) {
778- return false ;
779- }
780-
781- let needs_drop = self . needs_drop_uncached ( tcx, param_env, stack) ;
782-
783- // "Pop" the cycle detection "stack".
784- stack. remove ( self ) ;
785-
786- needs_drop
787- }
788-
789- fn needs_drop_uncached ( & ' tcx self ,
790- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
791- param_env : ty:: ParameterEnvironment < ' tcx > ,
792- stack : & mut FxHashSet < Ty < ' tcx > > )
793- -> bool {
794- assert ! ( !self . needs_infer( ) ) ;
795-
796- let result = match self . sty {
797- // Fast-path for primitive types
798- ty:: TyInfer ( ty:: FreshIntTy ( _) ) | ty:: TyInfer ( ty:: FreshFloatTy ( _) ) |
799- ty:: TyBool | ty:: TyInt ( _) | ty:: TyUint ( _) | ty:: TyFloat ( _) | ty:: TyNever |
800- ty:: TyFnDef ( ..) | ty:: TyFnPtr ( _) | ty:: TyChar |
801- ty:: TyRawPtr ( _) | ty:: TyRef ( ..) | ty:: TyStr => false ,
802-
803- // Issue #22536: We first query type_moves_by_default. It sees a
804- // normalized version of the type, and therefore will definitely
805- // know whether the type implements Copy (and thus needs no
806- // cleanup/drop/zeroing) ...
807- _ if !self . moves_by_default ( tcx, param_env, DUMMY_SP ) => false ,
808-
809- // ... (issue #22536 continued) but as an optimization, still use
810- // prior logic of asking for the structural "may drop".
811-
812- // FIXME(#22815): Note that this is a conservative heuristic;
813- // it may report that the type "may drop" when actual type does
814- // not actually have a destructor associated with it. But since
815- // the type absolutely did not have the `Copy` bound attached
816- // (see above), it is sound to treat it as having a destructor.
817-
818- // User destructors are the only way to have concrete drop types.
819- ty:: TyAdt ( def, _) if def. has_dtor ( tcx) => true ,
820-
821- // Can refer to a type which may drop.
822- // FIXME(eddyb) check this against a ParameterEnvironment.
823- ty:: TyDynamic ( ..) | ty:: TyProjection ( ..) | ty:: TyParam ( _) |
824- ty:: TyAnon ( ..) | ty:: TyInfer ( _) | ty:: TyError => true ,
825-
826- // Structural recursion.
827- ty:: TyArray ( ty, _) | ty:: TySlice ( ty) => {
828- ty. needs_drop_inner ( tcx, param_env, stack)
829- }
830-
831- ty:: TyClosure ( def_id, ref substs) => {
832- substs. upvar_tys ( def_id, tcx)
833- . any ( |ty| ty. needs_drop_inner ( tcx, param_env, stack) )
834- }
835-
836- ty:: TyTuple ( ref tys, _) => {
837- tys. iter ( ) . any ( |ty| ty. needs_drop_inner ( tcx, param_env, stack) )
838- }
839-
840- // unions don't have destructors regardless of the child types
841- ty:: TyAdt ( def, _) if def. is_union ( ) => false ,
842-
843- ty:: TyAdt ( def, substs) => {
844- def. variants . iter ( ) . any ( |v| {
845- v. fields . iter ( ) . any ( |f| {
846- f. ty ( tcx, substs) . needs_drop_inner ( tcx, param_env, stack)
847- } )
848- } )
849- }
850- } ;
851-
852- if !self . has_param_types ( ) && !self . has_self_ty ( ) {
853- self . flags . set ( self . flags . get ( ) | if result {
854- TypeFlags :: NEEDS_DROP_CACHED | TypeFlags :: NEEDS_DROP
855- } else {
856- TypeFlags :: NEEDS_DROP_CACHED
857- } ) ;
858- }
859-
860- result
756+ tcx. needs_drop_raw ( param_env. and ( self ) )
861757 }
862758
863759 #[ inline]
@@ -1075,11 +971,81 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1075971 . enter ( |infcx| traits:: type_known_to_meet_bound ( & infcx, ty, trait_def_id, DUMMY_SP ) )
1076972}
1077973
974+ fn needs_drop_raw < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
975+ query : ty:: ParameterEnvironmentAnd < ' tcx , Ty < ' tcx > > )
976+ -> bool
977+ {
978+ let ( param_env, ty) = query. into_parts ( ) ;
979+
980+ let needs_drop = |ty : Ty < ' tcx > | -> bool {
981+ match ty:: queries:: needs_drop_raw:: try_get ( tcx, DUMMY_SP , param_env. and ( ty) ) {
982+ Ok ( v) => v,
983+ Err ( _) => {
984+ // Cycles should be reported as an error by `check_representable`.
985+ //
986+ // Consider the type as not needing drop in the meanwhile to avoid
987+ // further errors.
988+ false
989+ }
990+ }
991+ } ;
992+
993+ assert ! ( !ty. needs_infer( ) ) ;
994+
995+ match ty. sty {
996+ // Fast-path for primitive types
997+ ty:: TyInfer ( ty:: FreshIntTy ( _) ) | ty:: TyInfer ( ty:: FreshFloatTy ( _) ) |
998+ ty:: TyBool | ty:: TyInt ( _) | ty:: TyUint ( _) | ty:: TyFloat ( _) | ty:: TyNever |
999+ ty:: TyFnDef ( ..) | ty:: TyFnPtr ( _) | ty:: TyChar |
1000+ ty:: TyRawPtr ( _) | ty:: TyRef ( ..) | ty:: TyStr => false ,
1001+
1002+ // Issue #22536: We first query type_moves_by_default. It sees a
1003+ // normalized version of the type, and therefore will definitely
1004+ // know whether the type implements Copy (and thus needs no
1005+ // cleanup/drop/zeroing) ...
1006+ _ if !ty. moves_by_default ( tcx, param_env, DUMMY_SP ) => false ,
1007+
1008+ // ... (issue #22536 continued) but as an optimization, still use
1009+ // prior logic of asking for the structural "may drop".
1010+
1011+ // FIXME(#22815): Note that this is a conservative heuristic;
1012+ // it may report that the type "may drop" when actual type does
1013+ // not actually have a destructor associated with it. But since
1014+ // the type absolutely did not have the `Copy` bound attached
1015+ // (see above), it is sound to treat it as having a destructor.
1016+
1017+ // User destructors are the only way to have concrete drop types.
1018+ ty:: TyAdt ( def, _) if def. has_dtor ( tcx) => true ,
1019+
1020+ // Can refer to a type which may drop.
1021+ // FIXME(eddyb) check this against a ParameterEnvironment.
1022+ ty:: TyDynamic ( ..) | ty:: TyProjection ( ..) | ty:: TyParam ( _) |
1023+ ty:: TyAnon ( ..) | ty:: TyInfer ( _) | ty:: TyError => true ,
1024+
1025+ // Structural recursion.
1026+ ty:: TyArray ( ty, _) | ty:: TySlice ( ty) => needs_drop ( ty) ,
1027+
1028+ ty:: TyClosure ( def_id, ref substs) => substs. upvar_tys ( def_id, tcx) . any ( needs_drop) ,
1029+
1030+ ty:: TyTuple ( ref tys, _) => tys. iter ( ) . cloned ( ) . any ( needs_drop) ,
1031+
1032+ // unions don't have destructors regardless of the child types
1033+ ty:: TyAdt ( def, _) if def. is_union ( ) => false ,
1034+
1035+ ty:: TyAdt ( def, substs) =>
1036+ def. variants . iter ( ) . any (
1037+ |variant| variant. fields . iter ( ) . any (
1038+ |field| needs_drop ( field. ty ( tcx, substs) ) ) ) ,
1039+ }
1040+ }
1041+
1042+
10781043pub fn provide ( providers : & mut ty:: maps:: Providers ) {
10791044 * providers = ty:: maps:: Providers {
10801045 is_copy_raw,
10811046 is_sized_raw,
10821047 is_freeze_raw,
1048+ needs_drop_raw,
10831049 ..* providers
10841050 } ;
10851051}
0 commit comments