@@ -15,14 +15,13 @@ use hir::map::DefPathData;
15
15
use infer:: InferCtxt ;
16
16
use ich:: { StableHashingContext , NodeIdHashingMode } ;
17
17
use traits:: { self , Reveal } ;
18
- use ty:: { self , Ty , TyCtxt , TypeFlags , TypeFoldable } ;
18
+ use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
19
19
use ty:: ParameterEnvironment ;
20
20
use ty:: fold:: TypeVisitor ;
21
21
use ty:: layout:: { Layout , LayoutError } ;
22
22
use ty:: subst:: { Subst , Kind } ;
23
23
use ty:: TypeVariants :: * ;
24
24
use util:: common:: ErrorReported ;
25
- use util:: nodemap:: FxHashSet ;
26
25
use middle:: lang_items;
27
26
28
27
use rustc_const_math:: { ConstInt , ConstIsize , ConstUsize } ;
@@ -754,110 +753,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
754
753
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
755
754
param_env : ty:: ParameterEnvironment < ' tcx > )
756
755
-> 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 ) )
861
757
}
862
758
863
759
#[ inline]
@@ -1075,11 +971,81 @@ fn is_freeze_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1075
971
. enter ( |infcx| traits:: type_known_to_meet_bound ( & infcx, ty, trait_def_id, DUMMY_SP ) )
1076
972
}
1077
973
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
+
1078
1043
pub fn provide ( providers : & mut ty:: maps:: Providers ) {
1079
1044
* providers = ty:: maps:: Providers {
1080
1045
is_copy_raw,
1081
1046
is_sized_raw,
1082
1047
is_freeze_raw,
1048
+ needs_drop_raw,
1083
1049
..* providers
1084
1050
} ;
1085
1051
}
0 commit comments