Skip to content

Commit 171eec5

Browse files
Use ResultsVisitor for borrow_check
1 parent 141483a commit 171eec5

File tree

2 files changed

+72
-63
lines changed

2 files changed

+72
-63
lines changed

src/librustc_mir/borrow_check/flows.rs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//! FIXME: this might be better as a "generic" fixed-point combinator,
44
//! but is not as ugly as it is right now.
55
6+
#![allow(unused)]
7+
68
use crate::borrow_check::location::LocationIndex;
79

810
use crate::borrow_check::nll::PoloniusOutput;

src/librustc_mir/borrow_check/mod.rs

+70-63
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_data_structures::graph::dominators::Dominators;
1818
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
1919
use rustc_hir as hir;
2020
use rustc_hir::{def_id::DefId, HirId, Node};
21+
use rustc_index::bit_set::BitSet;
2122
use rustc_index::vec::IndexVec;
2223

2324
use smallvec::SmallVec;
@@ -30,7 +31,9 @@ use rustc_span::{Span, DUMMY_SP};
3031
use syntax::ast::Name;
3132

3233
use crate::dataflow;
33-
use crate::dataflow::generic::ResultsCursor;
34+
use crate::dataflow::generic::visitor::{
35+
visit_results, BorrowckAnalyses, BorrowckResults, ResultsVisitable, ResultsVisitor,
36+
};
3437
use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex};
3538
use crate::dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveError, MovePath};
3639
use crate::dataflow::Borrows;
@@ -40,7 +43,6 @@ use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
4043
use crate::transform::MirSource;
4144

4245
use self::diagnostics::{AccessKind, RegionName};
43-
use self::flows::Flows;
4446
use self::location::LocationTable;
4547
use self::prefixes::PrefixSet;
4648
use self::MutateMode::{JustWrite, WriteAndRead};
@@ -195,7 +197,7 @@ fn do_mir_borrowck<'a, 'tcx>(
195197
Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data));
196198

197199
// 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 } =
199201
nll::compute_regions(
200202
infcx,
201203
def_id,
@@ -226,17 +228,14 @@ fn do_mir_borrowck<'a, 'tcx>(
226228

227229
let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set);
228230
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();
231232
let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe);
232233
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();
235235
let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe);
236236
let flow_ever_inits =
237237
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();
240239

241240
let movable_generator = match tcx.hir().get(id) {
242241
Node::Expr(&hir::Expr {
@@ -276,28 +275,22 @@ fn do_mir_borrowck<'a, 'tcx>(
276275
// Compute and report region errors, if any.
277276
mbcx.report_region_errors(nll_errors);
278277

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+
};
280283

281284
if let Some(errors) = move_errors {
282285
mbcx.report_move_errors(errors);
283286
}
284287

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+
);
301294

302295
// Convert any reservation warnings into lints.
303296
let reservation_warnings = mem::take(&mut mbcx.reservation_warnings);
@@ -495,23 +488,23 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
495488
next_region_name: RefCell<usize>,
496489
}
497490

491+
type Flows<'mir, 'tcx> = <BorrowckResults<'mir, 'tcx> as ResultsVisitable<'tcx>>::FlowState;
492+
498493
// Check that:
499494
// 1. assignments are always made to mutable locations (FIXME: does that still really go here?)
500495
// 2. loans made in overlapping scopes do not conflict
501496
// 3. assignments do not affect things loaned out as immutable
502497
// 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>;
507500

508-
fn visit_statement_entry(
501+
fn visit_statement(
509502
&mut self,
510-
location: Location,
503+
flow_state: &Flows<'cx, 'tcx>,
511504
stmt: &'cx Statement<'tcx>,
512-
flow_state: &mut Flows<'cx, 'tcx>,
505+
location: Location,
513506
) {
514-
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {}", location, stmt, flow_state);
507+
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
515508
let span = stmt.source_info.span;
516509

517510
self.check_activations(location, span, flow_state);
@@ -594,13 +587,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
594587
}
595588
}
596589

597-
fn visit_terminator_entry(
590+
fn visit_terminator(
598591
&mut self,
599-
loc: Location,
592+
flow_state: &Flows<'cx, 'tcx>,
600593
term: &'cx Terminator<'tcx>,
601-
flow_state: &mut Flows<'cx, 'tcx>,
594+
loc: Location,
602595
) {
603-
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {}", loc, term, flow_state);
596+
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
604597
let span = term.source_info.span;
605598

606599
self.check_activations(loc, span, flow_state);
@@ -672,18 +665,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
672665

673666
TerminatorKind::Yield { ref value, resume: _, drop: _ } => {
674667
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+
}
675682

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;
679690

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);
687698
}
688699
}
689700

@@ -693,22 +704,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
693704
// StorageDead, but we don't always emit those (notably on unwind paths),
694705
// so this "extra check" serves as a kind of backup.
695706
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() {
701708
let borrow = &borrow_set[i];
702709
self.check_for_invalidation_at_exit(loc, borrow, span);
703710
}
704711
}
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+
_ => {}
712714
}
713715
}
714716
}
@@ -843,6 +845,10 @@ impl InitializationRequiringAction {
843845
}
844846

845847
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
848+
fn body(&self) -> &'cx Body<'tcx> {
849+
*self.body
850+
}
851+
846852
/// Checks an access to the given place to see if it is allowed. Examines the set of borrows
847853
/// that are in scope, as well as which paths have been initialized, to ensure that (a) the
848854
/// 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> {
922928
let tcx = self.infcx.tcx;
923929
let body = self.body;
924930
let body: &Body<'_> = &body;
925-
let location_table = self.location_table.start_index(location);
931+
let _location_table = self.location_table.start_index(location);
926932
let borrow_set = self.borrow_set.clone();
927933
each_borrow_involving_path(
928934
self,
@@ -931,7 +937,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
931937
location,
932938
(sd, place_span.0),
933939
&borrow_set,
934-
flow_state.borrows_in_scope(location_table),
940+
// flow_state.borrows_in_scope(location_table),
941+
flow_state.borrows.iter(),
935942
|this, borrow_index, borrow| match (rw, borrow.kind) {
936943
// Obviously an activation is compatible with its own
937944
// reservation (or even prior activating uses of same
@@ -1553,7 +1560,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15531560
location: Location,
15541561
desired_action: InitializationRequiringAction,
15551562
place_span: (PlaceRef<'cx, 'tcx>, Span),
1556-
maybe_uninits: &ResultsCursor<'cx, 'tcx, MaybeUninitializedPlaces<'cx, 'tcx>>,
1563+
maybe_uninits: &BitSet<MovePathIndex>,
15571564
from: u32,
15581565
to: u32,
15591566
) {

0 commit comments

Comments
 (0)