Skip to content

Commit 6e242be

Browse files
committed
stop using borrows for anything but iterating over live data
1 parent cdbe060 commit 6e242be

File tree

4 files changed

+56
-57
lines changed

4 files changed

+56
-57
lines changed

src/librustc_mir/borrow_check/borrow_set.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
1818
use rustc_data_structures::indexed_vec::IndexVec;
1919
use std::fmt;
2020
use std::hash::Hash;
21+
use std::ops::Index;
2122
use syntax_pos::Span;
2223

2324
crate struct BorrowSet<'tcx> {
@@ -49,6 +50,14 @@ crate struct BorrowSet<'tcx> {
4950
crate region_span_map: FxHashMap<RegionKind, Span>,
5051
}
5152

53+
impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
54+
type Output = BorrowData<'tcx>;
55+
56+
fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
57+
&self.borrows[index]
58+
}
59+
}
60+
5261
#[derive(Debug)]
5362
crate struct BorrowData<'tcx> {
5463
/// Location where the borrow reservation starts.
@@ -124,6 +133,13 @@ impl<'tcx> BorrowSet<'tcx> {
124133
region_span_map: visitor.region_span_map,
125134
}
126135
}
136+
137+
crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
138+
self.activation_map
139+
.get(&location)
140+
.map(|activations| &activations[..])
141+
.unwrap_or(&[])
142+
}
127143
}
128144

129145
struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use super::{Context, MirBorrowckCtxt};
2020
use super::{InitializationRequiringAction, PrefixSet};
2121
use super::borrow_set::BorrowData;
2222

23-
use dataflow::{Borrows, FlowAtLocation, MovingOutStatements};
23+
use dataflow::{FlowAtLocation, MovingOutStatements};
2424
use dataflow::move_paths::MovePathIndex;
2525
use util::borrowck_errors::{BorrowckErrors, Origin};
2626

@@ -391,10 +391,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
391391
context: Context,
392392
borrow: &BorrowData<'tcx>,
393393
drop_span: Span,
394-
borrows: &Borrows<'cx, 'gcx, 'tcx>
395394
) {
396-
let end_span = borrows.opt_region_end_span(&borrow.region);
397-
let scope_tree = borrows.scope_tree();
395+
let end_span = self.opt_region_end_span(&borrow.region);
396+
let scope_tree = self.tcx.region_scope_tree(self.mir_def_id);
398397
let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
399398
.last()
400399
.unwrap();

src/librustc_mir/borrow_check/mod.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use rustc_data_structures::indexed_vec::Idx;
2929

3030
use std::rc::Rc;
3131

32-
use syntax::ast;
3332
use syntax_pos::Span;
3433

3534
use dataflow::{do_dataflow, DebugFormatted};
@@ -236,7 +235,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
236235
let mut mbcx = MirBorrowckCtxt {
237236
tcx: tcx,
238237
mir: mir,
239-
node_id: id,
238+
mir_def_id: def_id,
240239
move_data: &mdpe.move_data,
241240
param_env: param_env,
242241
movable_generator,
@@ -249,6 +248,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
249248
moved_error_reported: FxHashSet(),
250249
nonlexical_regioncx: opt_regioncx,
251250
nonlexical_cause_info: None,
251+
borrow_set,
252252
dominators,
253253
};
254254

@@ -269,7 +269,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
269269
pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
270270
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
271271
mir: &'cx Mir<'tcx>,
272-
node_id: ast::NodeId,
272+
mir_def_id: DefId,
273273
move_data: &'cx MoveData<'tcx>,
274274
param_env: ParamEnv<'gcx>,
275275
movable_generator: bool,
@@ -302,6 +302,11 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
302302
/// find out which CFG points are contained in each borrow region.
303303
nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
304304
nonlexical_cause_info: Option<RegionCausalInfo>,
305+
306+
/// The set of borrows extracted from the MIR
307+
borrow_set: Rc<BorrowSet<'tcx>>,
308+
309+
/// Dominators for MIR
305310
dominators: Dominators<BasicBlock>,
306311
}
307312

@@ -543,11 +548,10 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
543548

544549
if self.movable_generator {
545550
// Look for any active borrows to locals
546-
let domain = flow_state.borrows.operator();
547-
let data = domain.borrows();
551+
let borrow_set = self.borrow_set.clone();
548552
flow_state.borrows.with_iter_outgoing(|borrows| {
549553
for i in borrows {
550-
let borrow = &data[i];
554+
let borrow = &borrow_set[i];
551555
self.check_for_local_borrow(borrow, span);
552556
}
553557
});
@@ -559,13 +563,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
559563
// Often, the storage will already have been killed by an explicit
560564
// StorageDead, but we don't always emit those (notably on unwind paths),
561565
// so this "extra check" serves as a kind of backup.
562-
let domain = flow_state.borrows.operator();
563-
let data = domain.borrows();
566+
let borrow_set = self.borrow_set.clone();
564567
flow_state.borrows.with_iter_outgoing(|borrows| {
565568
for i in borrows {
566-
let borrow = &data[i];
569+
let borrow = &borrow_set[i];
567570
let context = ContextKind::StorageDead.new(loc);
568-
self.check_for_invalidation_at_exit(context, borrow, span, flow_state);
571+
self.check_for_invalidation_at_exit(context, borrow, span);
569572
}
570573
});
571574
}
@@ -893,10 +896,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
893896
this.report_use_while_mutably_borrowed(context, place_span, borrow)
894897
}
895898
ReadKind::Borrow(bk) => {
896-
let end_issued_loan_span = flow_state
897-
.borrows
898-
.operator()
899-
.opt_region_end_span(&borrow.region);
899+
let end_issued_loan_span = this.opt_region_end_span(&borrow.region);
900900
error_reported = true;
901901
this.report_conflicting_borrow(
902902
context,
@@ -935,10 +935,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
935935

936936
match kind {
937937
WriteKind::MutableBorrow(bk) => {
938-
let end_issued_loan_span = flow_state
939-
.borrows
940-
.operator()
941-
.opt_region_end_span(&borrow.region);
938+
let end_issued_loan_span = this.opt_region_end_span(&borrow.region);
942939

943940
error_reported = true;
944941
this.report_conflicting_borrow(
@@ -955,7 +952,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
955952
context,
956953
borrow,
957954
place_span.1,
958-
flow_state.borrows.operator(),
959955
);
960956
}
961957
WriteKind::Mutate => {
@@ -1157,7 +1153,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
11571153
context: Context,
11581154
borrow: &BorrowData<'tcx>,
11591155
span: Span,
1160-
flow_state: &Flows<'cx, 'gcx, 'tcx>,
11611156
) {
11621157
debug!("check_for_invalidation_at_exit({:?})", borrow);
11631158
let place = &borrow.borrowed_place;
@@ -1210,7 +1205,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
12101205
context,
12111206
borrow,
12121207
span,
1213-
flow_state.borrows.operator(),
12141208
)
12151209
}
12161210
}
@@ -1265,9 +1259,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
12651259
// Two-phase borrow support: For each activation that is newly
12661260
// generated at this statement, check if it interferes with
12671261
// another borrow.
1268-
let borrows = flow_state.borrows.operator();
1269-
for &borrow_index in borrows.activations_at_location(location) {
1270-
let borrow = &borrows.borrows()[borrow_index];
1262+
let borrow_set = self.borrow_set.clone();
1263+
for &borrow_index in borrow_set.activations_at_location(location) {
1264+
let borrow = &borrow_set[borrow_index];
12711265

12721266
// only mutable borrows should be 2-phase
12731267
assert!(match borrow.kind {
@@ -1782,6 +1776,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17821776
_ => None,
17831777
}
17841778
}
1779+
1780+
/// Returns the span for the "end point" given region. This will
1781+
/// return `None` if NLL is enabled, since that concept has no
1782+
/// meaning there. Otherwise, return region span if it exists and
1783+
/// span for end of the function if it doesn't exist.
1784+
pub(crate) fn opt_region_end_span(&self, region: &ty::Region<'tcx>) -> Option<Span> {
1785+
match self.nonlexical_regioncx {
1786+
Some(_) => None,
1787+
None => {
1788+
match self.borrow_set.region_span_map.get(region) {
1789+
Some(span) => Some(self.tcx.sess.codemap().end_point(*span)),
1790+
None => Some(self.tcx.sess.codemap().end_point(self.mir.span))
1791+
}
1792+
}
1793+
}
1794+
}
17851795
}
17861796

17871797
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -2182,13 +2192,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
21822192
// FIXME: analogous code in check_loans first maps `place` to
21832193
// its base_path.
21842194

2185-
let data = flow_state.borrows.operator().borrows();
2186-
21872195
// check for loan restricting path P being used. Accounts for
21882196
// borrows of P, P.a.b, etc.
21892197
let mut iter_incoming = flow_state.borrows.iter_incoming();
2198+
let borrow_set = self.borrow_set.clone();
21902199
while let Some(i) = iter_incoming.next() {
2191-
let borrowed = &data[i];
2200+
let borrowed = &borrow_set[i];
21922201

21932202
if self.places_conflict(&borrowed.borrowed_place, place, access) {
21942203
debug!(

src/librustc_mir/dataflow/impls/borrows.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::hir;
1616
use rustc::hir::def_id::DefId;
1717
use rustc::middle::region;
1818
use rustc::mir::{self, Location, Place, Mir};
19-
use rustc::ty::{Region, TyCtxt};
19+
use rustc::ty::TyCtxt;
2020
use rustc::ty::RegionKind;
2121
use rustc::ty::RegionKind::ReScope;
2222

@@ -30,8 +30,6 @@ pub use dataflow::indexes::BorrowIndex;
3030
use borrow_check::nll::region_infer::RegionInferenceContext;
3131
use borrow_check::nll::ToRegionVid;
3232

33-
use syntax_pos::Span;
34-
3533
use std::rc::Rc;
3634

3735
/// `Borrows` stores the data used in the analyses that track the flow
@@ -77,22 +75,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
7775
}
7876
}
7977

80-
/// Returns the span for the "end point" given region. This will
81-
/// return `None` if NLL is enabled, since that concept has no
82-
/// meaning there. Otherwise, return region span if it exists and
83-
/// span for end of the function if it doesn't exist.
84-
pub(crate) fn opt_region_end_span(&self, region: &Region) -> Option<Span> {
85-
match self.nonlexical_regioncx {
86-
Some(_) => None,
87-
None => {
88-
match self.borrow_set.region_span_map.get(region) {
89-
Some(span) => Some(self.tcx.sess.codemap().end_point(*span)),
90-
None => Some(self.tcx.sess.codemap().end_point(self.mir.span))
91-
}
92-
}
93-
}
94-
}
95-
9678
crate fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrow_set.borrows }
9779

9880
pub fn scope_tree(&self) -> &Lrc<region::ScopeTree> { &self.scope_tree }
@@ -136,13 +118,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
136118
sets.kill_all(borrow_indexes);
137119
}
138120
}
139-
140-
crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
141-
self.borrow_set.activation_map
142-
.get(&location)
143-
.map(|activations| &activations[..])
144-
.unwrap_or(&[])
145-
}
146121
}
147122

148123
impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {

0 commit comments

Comments
 (0)