@@ -17,7 +17,7 @@ use self::old_dataflow::IndirectlyMutableLocals;
17
17
use super :: ops:: { self , NonConstOp } ;
18
18
use super :: qualifs:: { HasMutInterior , NeedsDrop } ;
19
19
use super :: resolver:: FlowSensitiveAnalysis ;
20
- use super :: { ConstKind , Item , Qualif , is_lang_panic_fn} ;
20
+ use super :: { ConstKind , Item , Qualif , QualifSet , is_lang_panic_fn} ;
21
21
22
22
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
23
23
pub enum CheckOpResult {
@@ -85,6 +85,19 @@ impl Qualifs<'a, 'mir, 'tcx> {
85
85
|| self . indirectly_mutable ( local, location)
86
86
}
87
87
88
+ /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
89
+ ///
90
+ /// Only updates the cursor if absolutely necessary.
91
+ fn has_mut_interior_lazy_seek ( & mut self , local : Local , location : Location ) -> bool {
92
+ if !self . has_mut_interior . in_any_value_of_ty . contains ( local) {
93
+ return false ;
94
+ }
95
+
96
+ self . has_mut_interior . cursor . seek_before ( location) ;
97
+ self . has_mut_interior . cursor . get ( ) . contains ( local)
98
+ || self . indirectly_mutable ( local, location)
99
+ }
100
+
88
101
/// Returns `true` if `local` is `HasMutInterior`, but requires the `has_mut_interior` and
89
102
/// `indirectly_mutable` cursors to be updated beforehand.
90
103
fn has_mut_interior_eager_seek ( & self , local : Local ) -> bool {
@@ -95,6 +108,37 @@ impl Qualifs<'a, 'mir, 'tcx> {
95
108
self . has_mut_interior . cursor . get ( ) . contains ( local)
96
109
|| self . indirectly_mutable . get ( ) . contains ( local)
97
110
}
111
+
112
+ fn in_return_place ( & mut self , item : & Item < ' _ , ' tcx > ) -> QualifSet {
113
+ // Find the `Return` terminator if one exists.
114
+ //
115
+ // If no `Return` terminator exists, this MIR is divergent. Just return the conservative
116
+ // qualifs for the return type.
117
+ let return_block = item. body
118
+ . basic_blocks ( )
119
+ . iter_enumerated ( )
120
+ . find ( |( _, block) | {
121
+ match block. terminator ( ) . kind {
122
+ TerminatorKind :: Return => true ,
123
+ _ => false ,
124
+ }
125
+ } )
126
+ . map ( |( bb, _) | bb) ;
127
+
128
+ let return_block = match return_block {
129
+ None => return QualifSet :: in_any_value_of_ty ( item, item. body . return_ty ( ) ) ,
130
+ Some ( bb) => bb,
131
+ } ;
132
+
133
+ let return_loc = item. body . terminator_loc ( return_block) ;
134
+
135
+ let mut qualifs = QualifSet :: default ( ) ;
136
+
137
+ qualifs. set :: < NeedsDrop > ( self . needs_drop_lazy_seek ( RETURN_PLACE , return_loc) ) ;
138
+ qualifs. set :: < HasMutInterior > ( self . has_mut_interior_lazy_seek ( RETURN_PLACE , return_loc) ) ;
139
+
140
+ qualifs
141
+ }
98
142
}
99
143
100
144
pub struct Validator < ' a , ' mir , ' tcx > {
0 commit comments