@@ -17,7 +17,7 @@ use self::old_dataflow::IndirectlyMutableLocals;
1717use super :: ops:: { self , NonConstOp } ;
1818use super :: qualifs:: { HasMutInterior , NeedsDrop } ;
1919use super :: resolver:: FlowSensitiveAnalysis ;
20- use super :: { ConstKind , Item , Qualif , is_lang_panic_fn} ;
20+ use super :: { ConstKind , Item , Qualif , QualifSet , is_lang_panic_fn} ;
2121
2222#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
2323pub enum CheckOpResult {
@@ -85,6 +85,19 @@ impl Qualifs<'a, 'mir, 'tcx> {
8585 || self . indirectly_mutable ( local, location)
8686 }
8787
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+
88101 /// Returns `true` if `local` is `HasMutInterior`, but requires the `has_mut_interior` and
89102 /// `indirectly_mutable` cursors to be updated beforehand.
90103 fn has_mut_interior_eager_seek ( & self , local : Local ) -> bool {
@@ -95,6 +108,37 @@ impl Qualifs<'a, 'mir, 'tcx> {
95108 self . has_mut_interior . cursor . get ( ) . contains ( local)
96109 || self . indirectly_mutable . get ( ) . contains ( local)
97110 }
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+ }
98142}
99143
100144pub struct Validator < ' a , ' mir , ' tcx > {
0 commit comments