22
33use std:: borrow:: Borrow ;
44
5- use rustc:: mir:: { self , BasicBlock , Location } ;
5+ use rustc:: mir:: { self , BasicBlock , Location , TerminatorKind } ;
66use rustc_index:: bit_set:: BitSet ;
77
88use super :: { Analysis , Results } ;
@@ -29,14 +29,14 @@ where
2929
3030 pos : CursorPosition ,
3131
32- /// When this flag is set, the cursor is pointing at a `Call` terminator whose call return
33- /// effect has been applied to `state`.
32+ /// When this flag is set, the cursor is pointing at a `Call` or `Yield` terminator whose call
33+ /// return or resume effect has been applied to `state`.
3434 ///
35- /// This flag helps to ensure that multiple calls to `seek_after_assume_call_returns ` with the
35+ /// This flag helps to ensure that multiple calls to `seek_after_assume_success ` with the
3636 /// same target will result in exactly one invocation of `apply_call_return_effect`. It is
3737 /// sufficient to clear this only in `seek_to_block_start`, since seeking away from a
3838 /// terminator will always require a cursor reset.
39- call_return_effect_applied : bool ,
39+ success_effect_applied : bool ,
4040}
4141
4242impl < ' mir , ' tcx , A , R > ResultsCursor < ' mir , ' tcx , A , R >
5050 body,
5151 pos : CursorPosition :: BlockStart ( mir:: START_BLOCK ) ,
5252 state : results. borrow ( ) . entry_sets [ mir:: START_BLOCK ] . clone ( ) ,
53- call_return_effect_applied : false ,
53+ success_effect_applied : false ,
5454 results,
5555 }
5656 }
@@ -76,14 +76,14 @@ where
7676 pub fn seek_to_block_start ( & mut self , block : BasicBlock ) {
7777 self . state . overwrite ( & self . results . borrow ( ) . entry_sets [ block] ) ;
7878 self . pos = CursorPosition :: BlockStart ( block) ;
79- self . call_return_effect_applied = false ;
79+ self . success_effect_applied = false ;
8080 }
8181
8282 /// Advances the cursor to hold all effects up to and including to the "before" effect of the
8383 /// statement (or terminator) at the given location.
8484 ///
8585 /// If you wish to observe the full effect of a statement or terminator, not just the "before"
86- /// effect, use `seek_after` or `seek_after_assume_call_returns `.
86+ /// effect, use `seek_after` or `seek_after_assume_success `.
8787 pub fn seek_before ( & mut self , target : Location ) {
8888 assert ! ( target <= self . body. terminator_loc( target. block) ) ;
8989 self . seek_ ( target, false ) ;
@@ -93,15 +93,15 @@ where
9393 /// terminators) up to and including the `target`.
9494 ///
9595 /// If the `target` is a `Call` terminator, any call return effect for that terminator will
96- /// **not** be observed. Use `seek_after_assume_call_returns ` if you wish to observe the call
96+ /// **not** be observed. Use `seek_after_assume_success ` if you wish to observe the call
9797 /// return effect.
9898 pub fn seek_after ( & mut self , target : Location ) {
9999 assert ! ( target <= self . body. terminator_loc( target. block) ) ;
100100
101101 // If we have already applied the call return effect, we are currently pointing at a `Call`
102102 // terminator. Unconditionally reset the dataflow cursor, since there is no way to "undo"
103103 // the call return effect.
104- if self . call_return_effect_applied {
104+ if self . success_effect_applied {
105105 self . seek_to_block_start ( target. block ) ;
106106 }
107107
@@ -111,25 +111,25 @@ where
111111 /// Advances the cursor to hold all effects up to and including of the statement (or
112112 /// terminator) at the given location.
113113 ///
114- /// If the `target` is a `Call` terminator, any call return effect for that terminator will
115- /// be observed. Use `seek_after` if you do **not** wish to observe the call return effect.
116- pub fn seek_after_assume_call_returns ( & mut self , target : Location ) {
114+ /// If the `target` is a `Call` or `Yield` terminator, any call return or resume effect for that
115+ /// terminator will be observed. Use `seek_after` if you do **not** wish to observe the
116+ /// "success" effect.
117+ pub fn seek_after_assume_success ( & mut self , target : Location ) {
117118 let terminator_loc = self . body . terminator_loc ( target. block ) ;
118119 assert ! ( target. statement_index <= terminator_loc. statement_index) ;
119120
120121 self . seek_ ( target, true ) ;
121122
122- if target != terminator_loc {
123+ if target != terminator_loc || self . success_effect_applied {
123124 return ;
124125 }
125126
127+ // Apply the effect of the "success" path of the terminator.
128+
129+ self . success_effect_applied = true ;
126130 let terminator = self . body . basic_blocks ( ) [ target. block ] . terminator ( ) ;
127- if let mir:: TerminatorKind :: Call {
128- destination : Some ( ( return_place, _) ) , func, args, ..
129- } = & terminator. kind
130- {
131- if !self . call_return_effect_applied {
132- self . call_return_effect_applied = true ;
131+ match & terminator. kind {
132+ TerminatorKind :: Call { destination : Some ( ( return_place, _) ) , func, args, .. } => {
133133 self . results . borrow ( ) . analysis . apply_call_return_effect (
134134 & mut self . state ,
135135 target. block ,
@@ -138,6 +138,14 @@ where
138138 return_place,
139139 ) ;
140140 }
141+ TerminatorKind :: Yield { resume, resume_arg, .. } => {
142+ self . results . borrow ( ) . analysis . apply_yield_resume_effect (
143+ & mut self . state ,
144+ * resume,
145+ resume_arg,
146+ ) ;
147+ }
148+ _ => { }
141149 }
142150 }
143151
@@ -172,7 +180,7 @@ where
172180 self . seek_to_block_start ( target. block )
173181 }
174182
175- // N.B., `call_return_effect_applied ` is checked in `seek_after`, not here.
183+ // N.B., `success_effect_applied ` is checked in `seek_after`, not here.
176184 _ => ( ) ,
177185 }
178186
0 commit comments