@@ -18,6 +18,7 @@ use rustc_data_structures::graph::dominators::Dominators;
18
18
use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder } ;
19
19
use rustc_hir as hir;
20
20
use rustc_hir:: { def_id:: DefId , HirId , Node } ;
21
+ use rustc_index:: bit_set:: BitSet ;
21
22
use rustc_index:: vec:: IndexVec ;
22
23
23
24
use smallvec:: SmallVec ;
@@ -30,7 +31,9 @@ use rustc_span::{Span, DUMMY_SP};
30
31
use syntax:: ast:: Name ;
31
32
32
33
use crate :: dataflow;
33
- use crate :: dataflow:: generic:: ResultsCursor ;
34
+ use crate :: dataflow:: generic:: visitor:: {
35
+ visit_results, BorrowckAnalyses , BorrowckResults , ResultsVisitable , ResultsVisitor ,
36
+ } ;
34
37
use crate :: dataflow:: indexes:: { BorrowIndex , InitIndex , MoveOutIndex , MovePathIndex } ;
35
38
use crate :: dataflow:: move_paths:: { InitLocation , LookupResult , MoveData , MoveError , MovePath } ;
36
39
use crate :: dataflow:: Borrows ;
@@ -40,7 +43,6 @@ use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
40
43
use crate :: transform:: MirSource ;
41
44
42
45
use self :: diagnostics:: { AccessKind , RegionName } ;
43
- use self :: flows:: Flows ;
44
46
use self :: location:: LocationTable ;
45
47
use self :: prefixes:: PrefixSet ;
46
48
use self :: MutateMode :: { JustWrite , WriteAndRead } ;
@@ -195,7 +197,7 @@ fn do_mir_borrowck<'a, 'tcx>(
195
197
Rc :: new ( BorrowSet :: build ( tcx, body, locals_are_invalidated_at_exit, & mdpe. move_data ) ) ;
196
198
197
199
// Compute non-lexical lifetimes.
198
- let nll:: NllOutput { regioncx, polonius_output, opt_closure_req, nll_errors } =
200
+ let nll:: NllOutput { regioncx, polonius_output : _ , opt_closure_req, nll_errors } =
199
201
nll:: compute_regions (
200
202
infcx,
201
203
def_id,
@@ -226,17 +228,14 @@ fn do_mir_borrowck<'a, 'tcx>(
226
228
227
229
let flow_borrows = Borrows :: new ( tcx, & body, regioncx. clone ( ) , & borrow_set) ;
228
230
let flow_borrows = dataflow:: generic:: Engine :: new_gen_kill ( tcx, & body, def_id, flow_borrows)
229
- . iterate_to_fixpoint ( )
230
- . into_cursor ( & body) ;
231
+ . iterate_to_fixpoint ( ) ;
231
232
let flow_uninits = MaybeUninitializedPlaces :: new ( tcx, & body, & mdpe) ;
232
233
let flow_uninits = dataflow:: generic:: Engine :: new_gen_kill ( tcx, & body, def_id, flow_uninits)
233
- . iterate_to_fixpoint ( )
234
- . into_cursor ( & body) ;
234
+ . iterate_to_fixpoint ( ) ;
235
235
let flow_ever_inits = EverInitializedPlaces :: new ( tcx, & body, & mdpe) ;
236
236
let flow_ever_inits =
237
237
dataflow:: generic:: Engine :: new_gen_kill ( tcx, & body, def_id, flow_ever_inits)
238
- . iterate_to_fixpoint ( )
239
- . into_cursor ( & body) ;
238
+ . iterate_to_fixpoint ( ) ;
240
239
241
240
let movable_generator = match tcx. hir ( ) . get ( id) {
242
241
Node :: Expr ( & hir:: Expr {
@@ -276,28 +275,22 @@ fn do_mir_borrowck<'a, 'tcx>(
276
275
// Compute and report region errors, if any.
277
276
mbcx. report_region_errors ( nll_errors) ;
278
277
279
- let mut state = Flows :: new ( flow_borrows, flow_uninits, flow_ever_inits, polonius_output) ;
278
+ let results = BorrowckAnalyses {
279
+ ever_inits : flow_ever_inits,
280
+ uninits : flow_uninits,
281
+ borrows : flow_borrows,
282
+ } ;
280
283
281
284
if let Some ( errors) = move_errors {
282
285
mbcx. report_move_errors ( errors) ;
283
286
}
284
287
285
- // FIXME: refactor into visitor
286
- for ( block, block_data) in traversal:: reverse_postorder ( * body) {
287
- for ( statement_index, stmt) in block_data. statements . iter ( ) . enumerate ( ) {
288
- let loc = Location { block, statement_index } ;
289
- state. borrows . seek_before ( loc) ;
290
- state. uninits . seek_before ( loc) ;
291
- state. ever_inits . seek_before ( loc) ;
292
- mbcx. visit_statement_entry ( loc, & stmt, & mut state) ;
293
- }
294
-
295
- let loc = body. terminator_loc ( block) ;
296
- state. borrows . seek_before ( loc) ;
297
- state. uninits . seek_before ( loc) ;
298
- state. ever_inits . seek_before ( loc) ;
299
- mbcx. visit_terminator_entry ( loc, block_data. terminator ( ) , & mut state) ;
300
- }
288
+ visit_results (
289
+ & * body,
290
+ traversal:: reverse_postorder ( & * body) . map ( |( bb, _) | bb) ,
291
+ & results,
292
+ & mut mbcx,
293
+ ) ;
301
294
302
295
// Convert any reservation warnings into lints.
303
296
let reservation_warnings = mem:: take ( & mut mbcx. reservation_warnings ) ;
@@ -495,23 +488,23 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
495
488
next_region_name : RefCell < usize > ,
496
489
}
497
490
491
+ type Flows < ' mir , ' tcx > = <BorrowckResults < ' mir , ' tcx > as ResultsVisitable < ' tcx > >:: FlowState ;
492
+
498
493
// Check that:
499
494
// 1. assignments are always made to mutable locations (FIXME: does that still really go here?)
500
495
// 2. loans made in overlapping scopes do not conflict
501
496
// 3. assignments do not affect things loaned out as immutable
502
497
// 4. moves do not affect things loaned out in any way
503
- impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
504
- fn body ( & self ) -> & ' cx Body < ' tcx > {
505
- * self . body
506
- }
498
+ impl < ' cx , ' tcx > ResultsVisitor < ' cx , ' tcx > for MirBorrowckCtxt < ' cx , ' tcx > {
499
+ type FlowState = Flows < ' cx , ' tcx > ;
507
500
508
- fn visit_statement_entry (
501
+ fn visit_statement (
509
502
& mut self ,
510
- location : Location ,
503
+ flow_state : & Flows < ' cx , ' tcx > ,
511
504
stmt : & ' cx Statement < ' tcx > ,
512
- flow_state : & mut Flows < ' cx , ' tcx > ,
505
+ location : Location ,
513
506
) {
514
- debug ! ( "MirBorrowckCtxt::process_statement({:?}, {:?}): {}" , location, stmt, flow_state) ;
507
+ debug ! ( "MirBorrowckCtxt::process_statement({:?}, {:?}): {:? }" , location, stmt, flow_state) ;
515
508
let span = stmt. source_info . span ;
516
509
517
510
self . check_activations ( location, span, flow_state) ;
@@ -594,13 +587,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
594
587
}
595
588
}
596
589
597
- fn visit_terminator_entry (
590
+ fn visit_terminator (
598
591
& mut self ,
599
- loc : Location ,
592
+ flow_state : & Flows < ' cx , ' tcx > ,
600
593
term : & ' cx Terminator < ' tcx > ,
601
- flow_state : & mut Flows < ' cx , ' tcx > ,
594
+ loc : Location ,
602
595
) {
603
- debug ! ( "MirBorrowckCtxt::process_terminator({:?}, {:?}): {}" , loc, term, flow_state) ;
596
+ debug ! ( "MirBorrowckCtxt::process_terminator({:?}, {:?}): {:? }" , loc, term, flow_state) ;
604
597
let span = term. source_info . span ;
605
598
606
599
self . check_activations ( loc, span, flow_state) ;
@@ -672,18 +665,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
672
665
673
666
TerminatorKind :: Yield { ref value, resume : _, drop : _ } => {
674
667
self . consume_operand ( loc, ( value, span) , flow_state) ;
668
+ }
669
+
670
+ TerminatorKind :: Goto { target : _ }
671
+ | TerminatorKind :: Abort
672
+ | TerminatorKind :: Unreachable
673
+ | TerminatorKind :: Resume
674
+ | TerminatorKind :: Return
675
+ | TerminatorKind :: GeneratorDrop
676
+ | TerminatorKind :: FalseEdges { real_target : _, imaginary_target : _ }
677
+ | TerminatorKind :: FalseUnwind { real_target : _, unwind : _ } => {
678
+ // no data used, thus irrelevant to borrowck
679
+ }
680
+ }
681
+ }
675
682
676
- if self . movable_generator {
677
- // Look for any active borrows to locals
678
- let borrow_set = self . borrow_set . clone ( ) ;
683
+ fn visit_terminator_exit (
684
+ & mut self ,
685
+ flow_state : & Flows < ' cx , ' tcx > ,
686
+ term : & ' cx Terminator < ' tcx > ,
687
+ loc : Location ,
688
+ ) {
689
+ let span = term. source_info . span ;
679
690
680
- // FIXME: Don't call `seek_after` manually, instead use a visitor that visits
681
- // the exit of a basic block.
682
- flow_state . borrows . seek_after ( loc ) ;
683
- for i in flow_state . borrows . get ( ) . iter ( ) {
684
- let borrow = & borrow_set [ i ] ;
685
- self . check_for_local_borrow ( borrow, span ) ;
686
- }
691
+ match term . kind {
692
+ TerminatorKind :: Yield { value : _ , resume : _ , drop : _ } if self . movable_generator => {
693
+ // Look for any active borrows to locals
694
+ let borrow_set = self . borrow_set . clone ( ) ;
695
+ for i in flow_state . borrows . iter ( ) {
696
+ let borrow = & borrow_set [ i ] ;
697
+ self . check_for_local_borrow ( borrow , span ) ;
687
698
}
688
699
}
689
700
@@ -693,22 +704,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
693
704
// StorageDead, but we don't always emit those (notably on unwind paths),
694
705
// so this "extra check" serves as a kind of backup.
695
706
let borrow_set = self . borrow_set . clone ( ) ;
696
-
697
- // FIXME: Don't call `seek_after` manually, instead use a visitor that visits
698
- // the exit of a basic block.
699
- flow_state. borrows . seek_after ( loc) ;
700
- for i in flow_state. borrows . get ( ) . iter ( ) {
707
+ for i in flow_state. borrows . iter ( ) {
701
708
let borrow = & borrow_set[ i] ;
702
709
self . check_for_invalidation_at_exit ( loc, borrow, span) ;
703
710
}
704
711
}
705
- TerminatorKind :: Goto { target : _ }
706
- | TerminatorKind :: Abort
707
- | TerminatorKind :: Unreachable
708
- | TerminatorKind :: FalseEdges { real_target : _, imaginary_target : _ }
709
- | TerminatorKind :: FalseUnwind { real_target : _, unwind : _ } => {
710
- // no data used, thus irrelevant to borrowck
711
- }
712
+
713
+ _ => { }
712
714
}
713
715
}
714
716
}
@@ -843,6 +845,10 @@ impl InitializationRequiringAction {
843
845
}
844
846
845
847
impl < ' cx , ' tcx > MirBorrowckCtxt < ' cx , ' tcx > {
848
+ fn body ( & self ) -> & ' cx Body < ' tcx > {
849
+ * self . body
850
+ }
851
+
846
852
/// Checks an access to the given place to see if it is allowed. Examines the set of borrows
847
853
/// that are in scope, as well as which paths have been initialized, to ensure that (a) the
848
854
/// place is initialized and (b) it is not borrowed in some way that would prevent this
@@ -922,7 +928,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
922
928
let tcx = self . infcx . tcx ;
923
929
let body = self . body ;
924
930
let body: & Body < ' _ > = & body;
925
- let location_table = self . location_table . start_index ( location) ;
931
+ let _location_table = self . location_table . start_index ( location) ;
926
932
let borrow_set = self . borrow_set . clone ( ) ;
927
933
each_borrow_involving_path (
928
934
self ,
@@ -931,7 +937,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
931
937
location,
932
938
( sd, place_span. 0 ) ,
933
939
& borrow_set,
934
- flow_state. borrows_in_scope ( location_table) ,
940
+ // flow_state.borrows_in_scope(location_table),
941
+ flow_state. borrows . iter ( ) ,
935
942
|this, borrow_index, borrow| match ( rw, borrow. kind ) {
936
943
// Obviously an activation is compatible with its own
937
944
// reservation (or even prior activating uses of same
@@ -1553,7 +1560,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1553
1560
location : Location ,
1554
1561
desired_action : InitializationRequiringAction ,
1555
1562
place_span : ( PlaceRef < ' cx , ' tcx > , Span ) ,
1556
- maybe_uninits : & ResultsCursor < ' cx , ' tcx , MaybeUninitializedPlaces < ' cx , ' tcx > > ,
1563
+ maybe_uninits : & BitSet < MovePathIndex > ,
1557
1564
from : u32 ,
1558
1565
to : u32 ,
1559
1566
) {
0 commit comments