@@ -22,7 +22,7 @@ use std::mem;
22
22
use std:: ops:: Deref ;
23
23
24
24
use super :: ops:: { self , NonConstOp , Status } ;
25
- use super :: qualifs:: { self , CustomEq , HasMutInterior , NeedsNonConstDrop } ;
25
+ use super :: qualifs:: { self , CustomEq , HasMutInterior , NeedsDrop , NeedsNonConstDrop } ;
26
26
use super :: resolver:: FlowSensitiveAnalysis ;
27
27
use super :: { is_lang_panic_fn, is_lang_special_const_fn, ConstCx , Qualif } ;
28
28
use crate :: const_eval:: is_unstable_const_fn;
@@ -39,7 +39,8 @@ type QualifResults<'mir, 'tcx, Q> =
39
39
#[ derive( Default ) ]
40
40
pub struct Qualifs < ' mir , ' tcx > {
41
41
has_mut_interior : Option < QualifResults < ' mir , ' tcx , HasMutInterior > > ,
42
- needs_drop : Option < QualifResults < ' mir , ' tcx , NeedsNonConstDrop > > ,
42
+ needs_drop : Option < QualifResults < ' mir , ' tcx , NeedsDrop > > ,
43
+ needs_non_const_drop : Option < QualifResults < ' mir , ' tcx , NeedsNonConstDrop > > ,
43
44
indirectly_mutable : Option < IndirectlyMutableResults < ' mir , ' tcx > > ,
44
45
}
45
46
@@ -80,14 +81,14 @@ impl Qualifs<'mir, 'tcx> {
80
81
location : Location ,
81
82
) -> bool {
82
83
let ty = ccx. body . local_decls [ local] . ty ;
83
- if !NeedsNonConstDrop :: in_any_value_of_ty ( ccx, ty) {
84
+ if !NeedsDrop :: in_any_value_of_ty ( ccx, ty) {
84
85
return false ;
85
86
}
86
87
87
88
let needs_drop = self . needs_drop . get_or_insert_with ( || {
88
89
let ConstCx { tcx, body, .. } = * ccx;
89
90
90
- FlowSensitiveAnalysis :: new ( NeedsNonConstDrop , ccx)
91
+ FlowSensitiveAnalysis :: new ( NeedsDrop , ccx)
91
92
. into_engine ( tcx, & body)
92
93
. iterate_to_fixpoint ( )
93
94
. into_results_cursor ( & body)
@@ -97,6 +98,33 @@ impl Qualifs<'mir, 'tcx> {
97
98
needs_drop. get ( ) . contains ( local) || self . indirectly_mutable ( ccx, local, location)
98
99
}
99
100
101
+ /// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
102
+ ///
103
+ /// Only updates the cursor if absolutely necessary
104
+ pub fn needs_non_const_drop (
105
+ & mut self ,
106
+ ccx : & ' mir ConstCx < ' mir , ' tcx > ,
107
+ local : Local ,
108
+ location : Location ,
109
+ ) -> bool {
110
+ let ty = ccx. body . local_decls [ local] . ty ;
111
+ if !NeedsNonConstDrop :: in_any_value_of_ty ( ccx, ty) {
112
+ return false ;
113
+ }
114
+
115
+ let needs_non_const_drop = self . needs_non_const_drop . get_or_insert_with ( || {
116
+ let ConstCx { tcx, body, .. } = * ccx;
117
+
118
+ FlowSensitiveAnalysis :: new ( NeedsNonConstDrop , ccx)
119
+ . into_engine ( tcx, & body)
120
+ . iterate_to_fixpoint ( )
121
+ . into_results_cursor ( & body)
122
+ } ) ;
123
+
124
+ needs_non_const_drop. seek_before_primary_effect ( location) ;
125
+ needs_non_const_drop. get ( ) . contains ( local) || self . indirectly_mutable ( ccx, local, location)
126
+ }
127
+
100
128
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
101
129
///
102
130
/// Only updates the cursor if absolutely necessary.
@@ -173,6 +201,7 @@ impl Qualifs<'mir, 'tcx> {
173
201
174
202
ConstQualifs {
175
203
needs_drop : self . needs_drop ( ccx, RETURN_PLACE , return_loc) ,
204
+ needs_non_const_drop : self . needs_non_const_drop ( ccx, RETURN_PLACE , return_loc) ,
176
205
has_mut_interior : self . has_mut_interior ( ccx, RETURN_PLACE , return_loc) ,
177
206
custom_eq,
178
207
error_occured,
@@ -999,7 +1028,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
999
1028
}
1000
1029
1001
1030
// Forbid all `Drop` terminators unless the place being dropped is a local with no
1002
- // projections that cannot be `NeedsDrop `.
1031
+ // projections that cannot be `NeedsNonConstDrop `.
1003
1032
TerminatorKind :: Drop { place : dropped_place, .. }
1004
1033
| TerminatorKind :: DropAndReplace { place : dropped_place, .. } => {
1005
1034
// If we are checking live drops after drop-elaboration, don't emit duplicate
@@ -1019,15 +1048,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
1019
1048
return ;
1020
1049
}
1021
1050
1022
- let needs_drop = if let Some ( local) = dropped_place. as_local ( ) {
1051
+ let needs_non_const_drop = if let Some ( local) = dropped_place. as_local ( ) {
1023
1052
// Use the span where the local was declared as the span of the drop error.
1024
1053
err_span = self . body . local_decls [ local] . source_info . span ;
1025
- self . qualifs . needs_drop ( self . ccx , local, location)
1054
+ self . qualifs . needs_non_const_drop ( self . ccx , local, location)
1026
1055
} else {
1027
1056
true
1028
1057
} ;
1029
1058
1030
- if needs_drop {
1059
+ if needs_non_const_drop {
1031
1060
self . check_op_spanned (
1032
1061
ops:: LiveDrop { dropped_at : Some ( terminator. source_info . span ) } ,
1033
1062
err_span,
0 commit comments