@@ -214,6 +214,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
214214 }
215215 for j_stmt in 0 ..statements. len ( ) {
216216 let location = Location { block : bb, statement_index : j_stmt } ;
217+ self . flow_state . operator . before_statement_effect ( sets, location) ;
217218 self . flow_state . operator . statement_effect ( sets, location) ;
218219 if track_intrablock {
219220 sets. apply_local_effect ( ) ;
@@ -222,6 +223,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
222223
223224 if terminator. is_some ( ) {
224225 let location = Location { block : bb, statement_index : statements. len ( ) } ;
226+ self . flow_state . operator . before_terminator_effect ( sets, location) ;
225227 self . flow_state . operator . terminator_effect ( sets, location) ;
226228 if track_intrablock {
227229 sets. apply_local_effect ( ) ;
@@ -365,9 +367,10 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
365367 fn mir ( & self ) -> & ' a Mir < ' tcx > ;
366368}
367369
368- pub fn state_for_location < T : BitDenotation > ( loc : Location ,
369- analysis : & T ,
370- result : & DataflowResults < T > )
370+ pub fn state_for_location < ' tcx , T : BitDenotation > ( loc : Location ,
371+ analysis : & T ,
372+ result : & DataflowResults < T > ,
373+ mir : & Mir < ' tcx > )
371374 -> IdxSetBuf < T :: Idx > {
372375 let mut entry = result. sets ( ) . on_entry_set_for ( loc. block . index ( ) ) . to_owned ( ) ;
373376
@@ -381,8 +384,16 @@ pub fn state_for_location<T: BitDenotation>(loc: Location,
381384 for stmt in 0 ..loc. statement_index {
382385 let mut stmt_loc = loc;
383386 stmt_loc. statement_index = stmt;
387+ analysis. before_statement_effect ( & mut sets, stmt_loc) ;
384388 analysis. statement_effect ( & mut sets, stmt_loc) ;
385389 }
390+
391+ // Apply the pre-statement effect of the statement we're evaluating.
392+ if loc. statement_index == mir[ loc. block ] . statements . len ( ) {
393+ analysis. before_terminator_effect ( & mut sets, loc) ;
394+ } else {
395+ analysis. before_statement_effect ( & mut sets, loc) ;
396+ }
386397 }
387398
388399 entry
@@ -637,6 +648,21 @@ pub trait BitDenotation: BitwiseOperator {
637648 /// (For example, establishing the call arguments.)
638649 fn start_block_effect ( & self , entry_set : & mut IdxSet < Self :: Idx > ) ;
639650
651+ /// Similar to `statement_effect`, except it applies
652+ /// *just before* the statement rather than *just after* it.
653+ ///
654+ /// This matters for "dataflow at location" APIs, because the
655+ /// before-statement effect is visible while visiting the
656+ /// statement, while the after-statement effect only becomes
657+ /// visible at the next statement.
658+ ///
659+ /// Both the before-statement and after-statement effects are
660+ /// applied, in that order, before moving for the next
661+ /// statement.
662+ fn before_statement_effect ( & self ,
663+ _sets : & mut BlockSets < Self :: Idx > ,
664+ _location : Location ) { }
665+
640666 /// Mutates the block-sets (the flow sets for the given
641667 /// basic block) according to the effects of evaluating statement.
642668 ///
@@ -651,6 +677,21 @@ pub trait BitDenotation: BitwiseOperator {
651677 sets : & mut BlockSets < Self :: Idx > ,
652678 location : Location ) ;
653679
680+ /// Similar to `terminator_effect`, except it applies
681+ /// *just before* the terminator rather than *just after* it.
682+ ///
683+ /// This matters for "dataflow at location" APIs, because the
684+ /// before-terminator effect is visible while visiting the
685+ /// terminator, while the after-terminator effect only becomes
686+ /// visible at the terminator's successors.
687+ ///
688+ /// Both the before-terminator and after-terminator effects are
689+ /// applied, in that order, before moving for the next
690+ /// terminator.
691+ fn before_terminator_effect ( & self ,
692+ _sets : & mut BlockSets < Self :: Idx > ,
693+ _location : Location ) { }
694+
654695 /// Mutates the block-sets (the flow sets for the given
655696 /// basic block) according to the effects of evaluating
656697 /// the terminator.
0 commit comments