3
3
use rustc_errors:: struct_span_err;
4
4
use rustc_hir:: lang_items;
5
5
use rustc_hir:: { def_id:: DefId , HirId } ;
6
- use rustc_index:: bit_set:: BitSet ;
7
6
use rustc_infer:: infer:: TyCtxtInferExt ;
8
7
use rustc_middle:: mir:: visit:: { MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor } ;
9
8
use rustc_middle:: mir:: * ;
@@ -31,67 +30,59 @@ use crate::dataflow::{self, Analysis};
31
30
type IndirectlyMutableResults < ' mir , ' tcx > =
32
31
dataflow:: ResultsCursor < ' mir , ' tcx , MaybeMutBorrowedLocals < ' mir , ' tcx > > ;
33
32
34
- struct QualifCursor < ' a , ' mir , ' tcx , Q : Qualif > {
35
- cursor : dataflow:: ResultsCursor < ' mir , ' tcx , FlowSensitiveAnalysis < ' a , ' mir , ' tcx , Q > > ,
36
- in_any_value_of_ty : BitSet < Local > ,
37
- }
38
-
39
- impl < Q : Qualif > QualifCursor < ' a , ' mir , ' tcx , Q > {
40
- pub fn new ( q : Q , ccx : & ' a ConstCx < ' mir , ' tcx > ) -> Self {
41
- let cursor = FlowSensitiveAnalysis :: new ( q, ccx)
42
- . into_engine ( ccx. tcx , ccx. body , ccx. def_id )
43
- . iterate_to_fixpoint ( )
44
- . into_results_cursor ( ccx. body ) ;
45
-
46
- let mut in_any_value_of_ty = BitSet :: new_empty ( ccx. body . local_decls . len ( ) ) ;
47
- for ( local, decl) in ccx. body . local_decls . iter_enumerated ( ) {
48
- if Q :: in_any_value_of_ty ( ccx, decl. ty ) {
49
- in_any_value_of_ty. insert ( local) ;
50
- }
51
- }
52
-
53
- QualifCursor { cursor, in_any_value_of_ty }
54
- }
55
- }
33
+ type QualifResults < ' mir , ' tcx , Q > =
34
+ dataflow:: ResultsCursor < ' mir , ' tcx , FlowSensitiveAnalysis < ' mir , ' mir , ' tcx , Q > > ;
56
35
57
- pub struct Qualifs < ' a , ' mir , ' tcx > {
58
- has_mut_interior : QualifCursor < ' a , ' mir , ' tcx , HasMutInterior > ,
59
- needs_drop : QualifCursor < ' a , ' mir , ' tcx , NeedsDrop > ,
36
+ pub struct Qualifs < ' mir , ' tcx > {
37
+ has_mut_interior : QualifResults < ' mir , ' tcx , HasMutInterior > ,
38
+ needs_drop : QualifResults < ' mir , ' tcx , NeedsDrop > ,
60
39
indirectly_mutable : IndirectlyMutableResults < ' mir , ' tcx > ,
61
40
}
62
41
63
- impl Qualifs < ' a , ' mir , ' tcx > {
64
- fn indirectly_mutable ( & mut self , local : Local , location : Location ) -> bool {
42
+ impl Qualifs < ' mir , ' tcx > {
43
+ fn indirectly_mutable (
44
+ & mut self ,
45
+ _: & Item < ' mir , ' tcx > ,
46
+ local : Local ,
47
+ location : Location ,
48
+ ) -> bool {
65
49
self . indirectly_mutable . seek_before ( location) ;
66
50
self . indirectly_mutable . get ( ) . contains ( local)
67
51
}
68
52
69
53
/// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
70
54
///
71
55
/// Only updates the cursor if absolutely necessary
72
- fn needs_drop ( & mut self , local : Local , location : Location ) -> bool {
73
- if !self . needs_drop . in_any_value_of_ty . contains ( local) {
56
+ fn needs_drop ( & mut self , item : & Item < ' mir , ' tcx > , local : Local , location : Location ) -> bool {
57
+ let ty = item. body . local_decls [ local] . ty ;
58
+ if !NeedsDrop :: in_any_value_of_ty ( item, ty) {
74
59
return false ;
75
60
}
76
61
77
- self . needs_drop . cursor . seek_before ( location) ;
78
- self . needs_drop . cursor . get ( ) . contains ( local) || self . indirectly_mutable ( local, location)
62
+ self . needs_drop . seek_before ( location) ;
63
+ self . needs_drop . get ( ) . contains ( local) || self . indirectly_mutable ( item , local, location)
79
64
}
80
65
81
66
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
82
67
///
83
68
/// Only updates the cursor if absolutely necessary.
84
- fn has_mut_interior ( & mut self , local : Local , location : Location ) -> bool {
85
- if !self . has_mut_interior . in_any_value_of_ty . contains ( local) {
69
+ fn has_mut_interior (
70
+ & mut self ,
71
+ item : & Item < ' mir , ' tcx > ,
72
+ local : Local ,
73
+ location : Location ,
74
+ ) -> bool {
75
+ let ty = ccx. body . local_decls [ local] . ty ;
76
+ if !HasMutInterior :: in_any_value_of_ty ( ccx, ty) {
86
77
return false ;
87
78
}
88
79
89
- self . has_mut_interior . cursor . seek_before ( location) ;
90
- self . has_mut_interior . cursor . get ( ) . contains ( local)
91
- || self . indirectly_mutable ( local, location)
80
+ self . has_mut_interior . seek_before ( location) ;
81
+ self . has_mut_interior . get ( ) . contains ( local)
82
+ || self . indirectly_mutable ( item , local, location)
92
83
}
93
84
94
- fn in_return_place ( & mut self , ccx : & ConstCx < ' _ , ' tcx > ) -> ConstQualifs {
85
+ fn in_return_place ( & mut self , item : & Item < ' mir , ' tcx > ) -> ConstQualifs {
95
86
// Find the `Return` terminator if one exists.
96
87
//
97
88
// If no `Return` terminator exists, this MIR is divergent. Just return the conservative
@@ -114,34 +105,31 @@ impl Qualifs<'a, 'mir, 'tcx> {
114
105
let return_loc = ccx. body . terminator_loc ( return_block) ;
115
106
116
107
ConstQualifs {
117
- needs_drop : self . needs_drop ( RETURN_PLACE , return_loc) ,
118
- has_mut_interior : self . has_mut_interior ( RETURN_PLACE , return_loc) ,
108
+ needs_drop : self . needs_drop ( ccx , RETURN_PLACE , return_loc) ,
109
+ has_mut_interior : self . has_mut_interior ( ccx , RETURN_PLACE , return_loc) ,
119
110
}
120
111
}
121
112
}
122
113
123
- pub struct Validator < ' a , ' mir , ' tcx > {
124
- ccx : & ' a ConstCx < ' mir , ' tcx > ,
125
- qualifs : Qualifs < ' a , ' mir , ' tcx > ,
114
+ pub struct Validator < ' mir , ' tcx > {
115
+ ccx : & ' mir ConstCx < ' mir , ' tcx > ,
116
+ qualifs : Qualifs < ' mir , ' tcx > ,
126
117
127
118
/// The span of the current statement.
128
119
span : Span ,
129
120
}
130
121
131
- impl Deref for Validator < ' _ , ' mir , ' tcx > {
122
+ impl Deref for Validator < ' mir , ' tcx > {
132
123
type Target = ConstCx < ' mir , ' tcx > ;
133
124
134
125
fn deref ( & self ) -> & Self :: Target {
135
126
& self . ccx
136
127
}
137
128
}
138
129
139
- impl Validator < ' a , ' mir , ' tcx > {
140
- pub fn new ( ccx : & ' a ConstCx < ' mir , ' tcx > ) -> Self {
141
- let ConstCx { tcx, body, def_id, param_env, .. } = * ccx;
142
-
143
- let needs_drop = QualifCursor :: new ( NeedsDrop , ccx) ;
144
- let has_mut_interior = QualifCursor :: new ( HasMutInterior , ccx) ;
130
+ impl Validator < ' mir , ' tcx > {
131
+ pub fn new ( item : & ' mir Item < ' mir , ' tcx > ) -> Self {
132
+ let Item { tcx, body, def_id, param_env, .. } = * item;
145
133
146
134
// We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not
147
135
// allowed in a const.
@@ -154,6 +142,16 @@ impl Validator<'a, 'mir, 'tcx> {
154
142
. iterate_to_fixpoint ( )
155
143
. into_results_cursor ( body) ;
156
144
145
+ let needs_drop = FlowSensitiveAnalysis :: new ( NeedsDrop , item)
146
+ . into_engine ( item. tcx , & item. body , item. def_id )
147
+ . iterate_to_fixpoint ( )
148
+ . into_results_cursor ( * item. body ) ;
149
+
150
+ let has_mut_interior = FlowSensitiveAnalysis :: new ( HasMutInterior , item)
151
+ . into_engine ( item. tcx , & item. body , item. def_id )
152
+ . iterate_to_fixpoint ( )
153
+ . into_results_cursor ( * item. body ) ;
154
+
157
155
let qualifs = Qualifs { needs_drop, has_mut_interior, indirectly_mutable } ;
158
156
159
157
Validator { span : ccx. body . span , ccx, qualifs }
@@ -239,7 +237,7 @@ impl Validator<'a, 'mir, 'tcx> {
239
237
}
240
238
}
241
239
242
- impl Visitor < ' tcx > for Validator < ' _ , ' mir , ' tcx > {
240
+ impl Visitor < ' tcx > for Validator < ' mir , ' tcx > {
243
241
fn visit_basic_block_data ( & mut self , bb : BasicBlock , block : & BasicBlockData < ' tcx > ) {
244
242
trace ! ( "visit_basic_block_data: bb={:?} is_cleanup={:?}" , bb, block. is_cleanup) ;
245
243
@@ -345,7 +343,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
345
343
| Rvalue :: AddressOf ( Mutability :: Not , ref place) => {
346
344
let borrowed_place_has_mut_interior = qualifs:: in_place :: < HasMutInterior , _ > (
347
345
& self . ccx ,
348
- & mut |local| self . qualifs . has_mut_interior ( local, location) ,
346
+ & mut |local| self . qualifs . has_mut_interior ( self . ccx , local, location) ,
349
347
place. as_ref ( ) ,
350
348
) ;
351
349
@@ -571,7 +569,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
571
569
let needs_drop = if let Some ( local) = dropped_place. as_local ( ) {
572
570
// Use the span where the local was declared as the span of the drop error.
573
571
err_span = self . body . local_decls [ local] . source_info . span ;
574
- self . qualifs . needs_drop ( local, location)
572
+ self . qualifs . needs_drop ( self . ccx , local, location)
575
573
} else {
576
574
true
577
575
} ;
0 commit comments