Skip to content

Commit df233f0

Browse files
committed
stop using borrows for anything but iterating over live data
1 parent d4005a2 commit df233f0

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};
@@ -237,7 +236,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
237236
let mut mbcx = MirBorrowckCtxt {
238237
tcx: tcx,
239238
mir: mir,
240-
node_id: id,
239+
mir_def_id: def_id,
241240
move_data: &mdpe.move_data,
242241
param_env: param_env,
243242
movable_generator,
@@ -250,6 +249,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
250249
moved_error_reported: FxHashSet(),
251250
nonlexical_regioncx: opt_regioncx,
252251
nonlexical_cause_info: None,
252+
borrow_set,
253253
dominators,
254254
};
255255

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

@@ -544,11 +549,10 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
544549

545550
if self.movable_generator {
546551
// Look for any active borrows to locals
547-
let domain = flow_state.borrows.operator();
548-
let data = domain.borrows();
552+
let borrow_set = self.borrow_set.clone();
549553
flow_state.borrows.with_iter_outgoing(|borrows| {
550554
for i in borrows {
551-
let borrow = &data[i];
555+
let borrow = &borrow_set[i];
552556
self.check_for_local_borrow(borrow, span);
553557
}
554558
});
@@ -560,13 +564,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
560564
// Often, the storage will already have been killed by an explicit
561565
// StorageDead, but we don't always emit those (notably on unwind paths),
562566
// so this "extra check" serves as a kind of backup.
563-
let domain = flow_state.borrows.operator();
564-
let data = domain.borrows();
567+
let borrow_set = self.borrow_set.clone();
565568
flow_state.borrows.with_iter_outgoing(|borrows| {
566569
for i in borrows {
567-
let borrow = &data[i];
570+
let borrow = &borrow_set[i];
568571
let context = ContextKind::StorageDead.new(loc);
569-
self.check_for_invalidation_at_exit(context, borrow, span, flow_state);
572+
self.check_for_invalidation_at_exit(context, borrow, span);
570573
}
571574
});
572575
}
@@ -894,10 +897,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
894897
this.report_use_while_mutably_borrowed(context, place_span, borrow)
895898
}
896899
ReadKind::Borrow(bk) => {
897-
let end_issued_loan_span = flow_state
898-
.borrows
899-
.operator()
900-
.opt_region_end_span(&borrow.region);
900+
let end_issued_loan_span = this.opt_region_end_span(&borrow.region);
901901
error_reported = true;
902902
this.report_conflicting_borrow(
903903
context,
@@ -936,10 +936,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
936936

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

944941
error_reported = true;
945942
this.report_conflicting_borrow(
@@ -956,7 +953,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
956953
context,
957954
borrow,
958955
place_span.1,
959-
flow_state.borrows.operator(),
960956
);
961957
}
962958
WriteKind::Mutate => {
@@ -1158,7 +1154,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
11581154
context: Context,
11591155
borrow: &BorrowData<'tcx>,
11601156
span: Span,
1161-
flow_state: &Flows<'cx, 'gcx, 'tcx>,
11621157
) {
11631158
debug!("check_for_invalidation_at_exit({:?})", borrow);
11641159
let place = &borrow.borrowed_place;
@@ -1211,7 +1206,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
12111206
context,
12121207
borrow,
12131208
span,
1214-
flow_state.borrows.operator(),
12151209
)
12161210
}
12171211
}
@@ -1266,9 +1260,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
12661260
// Two-phase borrow support: For each activation that is newly
12671261
// generated at this statement, check if it interferes with
12681262
// another borrow.
1269-
let borrows = flow_state.borrows.operator();
1270-
for &borrow_index in borrows.activations_at_location(location) {
1271-
let borrow = &borrows.borrows()[borrow_index];
1263+
let borrow_set = self.borrow_set.clone();
1264+
for &borrow_index in borrow_set.activations_at_location(location) {
1265+
let borrow = &borrow_set[borrow_index];
12721266

12731267
// only mutable borrows should be 2-phase
12741268
assert!(match borrow.kind {
@@ -1838,6 +1832,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18381832
_ => None,
18391833
}
18401834
}
1835+
1836+
/// Returns the span for the "end point" given region. This will
1837+
/// return `None` if NLL is enabled, since that concept has no
1838+
/// meaning there. Otherwise, return region span if it exists and
1839+
/// span for end of the function if it doesn't exist.
1840+
pub(crate) fn opt_region_end_span(&self, region: &ty::Region<'tcx>) -> Option<Span> {
1841+
match self.nonlexical_regioncx {
1842+
Some(_) => None,
1843+
None => {
1844+
match self.borrow_set.region_span_map.get(region) {
1845+
Some(span) => Some(self.tcx.sess.codemap().end_point(*span)),
1846+
None => Some(self.tcx.sess.codemap().end_point(self.mir.span))
1847+
}
1848+
}
1849+
}
1850+
}
18411851
}
18421852

18431853
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -2238,13 +2248,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
22382248
// FIXME: analogous code in check_loans first maps `place` to
22392249
// its base_path.
22402250

2241-
let data = flow_state.borrows.operator().borrows();
2242-
22432251
// check for loan restricting path P being used. Accounts for
22442252
// borrows of P, P.a.b, etc.
22452253
let mut iter_incoming = flow_state.borrows.iter_incoming();
2254+
let borrow_set = self.borrow_set.clone();
22462255
while let Some(i) = iter_incoming.next() {
2247-
let borrowed = &data[i];
2256+
let borrowed = &borrow_set[i];
22482257

22492258
if self.places_conflict(&borrowed.borrowed_place, place, access) {
22502259
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)