33use rustc_errors:: struct_span_err;
44use rustc_hir:: lang_items;
55use rustc_hir:: { def_id:: DefId , HirId } ;
6- use rustc_index:: bit_set:: BitSet ;
76use rustc_infer:: infer:: TyCtxtInferExt ;
87use rustc_middle:: mir:: visit:: { MutatingUseContext , NonMutatingUseContext , PlaceContext , Visitor } ;
98use rustc_middle:: mir:: * ;
@@ -31,67 +30,59 @@ use crate::dataflow::{self, Analysis};
3130type IndirectlyMutableResults < ' mir , ' tcx > =
3231 dataflow:: ResultsCursor < ' mir , ' tcx , MaybeMutBorrowedLocals < ' mir , ' tcx > > ;
3332
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 > > ;
5635
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 > ,
6039 indirectly_mutable : IndirectlyMutableResults < ' mir , ' tcx > ,
6140}
6241
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 {
6549 self . indirectly_mutable . seek_before ( location) ;
6650 self . indirectly_mutable . get ( ) . contains ( local)
6751 }
6852
6953 /// Returns `true` if `local` is `NeedsDrop` at the given `Location`.
7054 ///
7155 /// 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) {
7459 return false ;
7560 }
7661
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)
7964 }
8065
8166 /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
8267 ///
8368 /// 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) {
8677 return false ;
8778 }
8879
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)
9283 }
9384
94- fn in_return_place ( & mut self , ccx : & ConstCx < ' _ , ' tcx > ) -> ConstQualifs {
85+ fn in_return_place ( & mut self , item : & Item < ' mir , ' tcx > ) -> ConstQualifs {
9586 // Find the `Return` terminator if one exists.
9687 //
9788 // If no `Return` terminator exists, this MIR is divergent. Just return the conservative
@@ -114,34 +105,31 @@ impl Qualifs<'a, 'mir, 'tcx> {
114105 let return_loc = ccx. body . terminator_loc ( return_block) ;
115106
116107 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) ,
119110 }
120111 }
121112}
122113
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 > ,
126117
127118 /// The span of the current statement.
128119 span : Span ,
129120}
130121
131- impl Deref for Validator < ' _ , ' mir , ' tcx > {
122+ impl Deref for Validator < ' mir , ' tcx > {
132123 type Target = ConstCx < ' mir , ' tcx > ;
133124
134125 fn deref ( & self ) -> & Self :: Target {
135126 & self . ccx
136127 }
137128}
138129
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;
145133
146134 // We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not
147135 // allowed in a const.
@@ -154,6 +142,16 @@ impl Validator<'a, 'mir, 'tcx> {
154142 . iterate_to_fixpoint ( )
155143 . into_results_cursor ( body) ;
156144
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+
157155 let qualifs = Qualifs { needs_drop, has_mut_interior, indirectly_mutable } ;
158156
159157 Validator { span : ccx. body . span , ccx, qualifs }
@@ -239,7 +237,7 @@ impl Validator<'a, 'mir, 'tcx> {
239237 }
240238}
241239
242- impl Visitor < ' tcx > for Validator < ' _ , ' mir , ' tcx > {
240+ impl Visitor < ' tcx > for Validator < ' mir , ' tcx > {
243241 fn visit_basic_block_data ( & mut self , bb : BasicBlock , block : & BasicBlockData < ' tcx > ) {
244242 trace ! ( "visit_basic_block_data: bb={:?} is_cleanup={:?}" , bb, block. is_cleanup) ;
245243
@@ -345,7 +343,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
345343 | Rvalue :: AddressOf ( Mutability :: Not , ref place) => {
346344 let borrowed_place_has_mut_interior = qualifs:: in_place :: < HasMutInterior , _ > (
347345 & self . ccx ,
348- & mut |local| self . qualifs . has_mut_interior ( local, location) ,
346+ & mut |local| self . qualifs . has_mut_interior ( self . ccx , local, location) ,
349347 place. as_ref ( ) ,
350348 ) ;
351349
@@ -571,7 +569,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
571569 let needs_drop = if let Some ( local) = dropped_place. as_local ( ) {
572570 // Use the span where the local was declared as the span of the drop error.
573571 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)
575573 } else {
576574 true
577575 } ;
0 commit comments