Skip to content

Commit 6027e08

Browse files
committed
Only handle ReVar regions in NLL borrowck
Now that lexical MIR borrowck is gone, there's no need to store Regions unnecessarily.
1 parent b16985a commit 6027e08

File tree

4 files changed

+23
-105
lines changed

4 files changed

+23
-105
lines changed

src/librustc_mir/borrow_check/borrow_set.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
// except according to those terms.
1010

1111
use borrow_check::place_ext::PlaceExt;
12+
use borrow_check::nll::ToRegionVid;
1213
use dataflow::indexes::BorrowIndex;
1314
use dataflow::move_paths::MoveData;
1415
use rustc::mir::traversal;
1516
use rustc::mir::visit::{
1617
PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext
1718
};
1819
use rustc::mir::{self, Location, Mir, Place, Local};
19-
use rustc::ty::{Region, TyCtxt};
20+
use rustc::ty::{RegionVid, TyCtxt};
2021
use rustc::util::nodemap::{FxHashMap, FxHashSet};
2122
use rustc_data_structures::indexed_vec::IndexVec;
2223
use rustc_data_structures::bit_set::BitSet;
@@ -42,7 +43,7 @@ crate struct BorrowSet<'tcx> {
4243

4344
/// Every borrow has a region; this maps each such regions back to
4445
/// its borrow-indexes.
45-
crate region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
46+
crate region_map: FxHashMap<RegionVid, FxHashSet<BorrowIndex>>,
4647

4748
/// Map from local to all the borrows on that local
4849
crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
@@ -77,7 +78,7 @@ crate struct BorrowData<'tcx> {
7778
/// What kind of borrow this is
7879
crate kind: mir::BorrowKind,
7980
/// The region for which this borrow is live
80-
crate region: Region<'tcx>,
81+
crate region: RegionVid,
8182
/// Place from which we are borrowing
8283
crate borrowed_place: mir::Place<'tcx>,
8384
/// Place to which the borrow was stored
@@ -92,13 +93,7 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
9293
mir::BorrowKind::Unique => "uniq ",
9394
mir::BorrowKind::Mut { .. } => "mut ",
9495
};
95-
let region = self.region.to_string();
96-
let separator = if !region.is_empty() {
97-
" "
98-
} else {
99-
""
100-
};
101-
write!(w, "&{}{}{}{:?}", region, separator, kind, self.borrowed_place)
96+
write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place)
10297
}
10398
}
10499

@@ -189,7 +184,7 @@ struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
189184
idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
190185
location_map: FxHashMap<Location, BorrowIndex>,
191186
activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
192-
region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
187+
region_map: FxHashMap<RegionVid, FxHashSet<BorrowIndex>>,
193188
local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
194189

195190
/// When we encounter a 2-phase borrow statement, it will always
@@ -219,6 +214,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
219214
return;
220215
}
221216

217+
let region = region.to_region_vid();
218+
222219
let borrow = BorrowData {
223220
kind,
224221
region,
@@ -230,7 +227,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
230227
let idx = self.idx_vec.push(borrow);
231228
self.location_map.insert(location, idx);
232229

233-
self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);
230+
self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
234231

235232
self.region_map.entry(region).or_default().insert(idx);
236233
if let Some(local) = borrowed_place.root_local() {
@@ -314,7 +311,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
314311
let borrow_data = &self.idx_vec[borrow_index];
315312
assert_eq!(borrow_data.reserve_location, location);
316313
assert_eq!(borrow_data.kind, kind);
317-
assert_eq!(borrow_data.region, region);
314+
assert_eq!(borrow_data.region, region.to_region_vid());
318315
assert_eq!(borrow_data.borrowed_place, *place);
319316
}
320317

@@ -347,13 +344,12 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
347344
&mut self,
348345
start_location: Location,
349346
assigned_place: &mir::Place<'tcx>,
350-
region: Region<'tcx>,
351347
kind: mir::BorrowKind,
352348
borrow_index: BorrowIndex,
353349
) {
354350
debug!(
355-
"Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?}, {:?})",
356-
start_location, assigned_place, region, borrow_index,
351+
"Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?})",
352+
start_location, assigned_place, borrow_index,
357353
);
358354

359355
if !self.allow_two_phase_borrow(kind) {

src/librustc_mir/borrow_check/mod.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use borrow_check::nll::region_infer::RegionInferenceContext;
1414
use rustc::hir;
1515
use rustc::hir::Node;
1616
use rustc::hir::def_id::DefId;
17-
use rustc::hir::map::definitions::DefPathData;
1817
use rustc::infer::InferCtxt;
1918
use rustc::lint::builtin::UNUSED_MUT;
2019
use rustc::middle::borrowck::SignalledError;
@@ -162,10 +161,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
162161
move_data: move_data,
163162
param_env: param_env,
164163
};
165-
let body_id = match tcx.def_key(def_id).disambiguated_data.data {
166-
DefPathData::StructCtor | DefPathData::EnumVariant(_) => None,
167-
_ => Some(tcx.hir.body_owned_by(id)),
168-
};
169164

170165
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
171166
let mut flow_inits = FlowAtLocation::new(do_dataflow(
@@ -212,7 +207,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
212207
id,
213208
&attributes,
214209
&dead_unwinds,
215-
Borrows::new(tcx, mir, regioncx.clone(), def_id, body_id, &borrow_set),
210+
Borrows::new(tcx, mir, regioncx.clone(), &borrow_set),
216211
|rs, i| DebugFormatted::new(&rs.location(i)),
217212
));
218213
let flow_uninits = FlowAtLocation::new(do_dataflow(

src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
206206
let mir = self.mir;
207207
let tcx = self.infcx.tcx;
208208

209-
let borrow_region_vid = regioncx.to_region_vid(borrow.region);
209+
let borrow_region_vid = borrow.region;
210210
debug!(
211211
"explain_why_borrow_contains_point: borrow_region_vid={:?}",
212212
borrow_region_vid

src/librustc_mir/dataflow/impls/borrows.rs

+9-82
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,13 @@ use borrow_check::borrow_set::{BorrowSet, BorrowData};
1212
use borrow_check::place_ext::PlaceExt;
1313

1414
use rustc;
15-
use rustc::hir;
16-
use rustc::hir::def_id::DefId;
17-
use rustc::middle::region;
1815
use rustc::mir::{self, Location, Place, Mir};
1916
use rustc::ty::TyCtxt;
20-
use rustc::ty::{RegionKind, RegionVid};
21-
use rustc::ty::RegionKind::ReScope;
17+
use rustc::ty::RegionVid;
2218

2319
use rustc_data_structures::bit_set::{BitSet, BitSetOperator};
2420
use rustc_data_structures::fx::FxHashMap;
2521
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
26-
use rustc_data_structures::sync::Lrc;
2722

2823
use dataflow::{BitDenotation, BlockSets, InitialFlow};
2924
pub use dataflow::indexes::BorrowIndex;
@@ -42,8 +37,6 @@ use std::rc::Rc;
4237
pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
4338
tcx: TyCtxt<'a, 'gcx, 'tcx>,
4439
mir: &'a Mir<'tcx>,
45-
scope_tree: Lrc<region::ScopeTree>,
46-
root_scope: Option<region::Scope>,
4740

4841
borrow_set: Rc<BorrowSet<'tcx>>,
4942
borrows_out_of_scope_at_location: FxHashMap<Location, Vec<BorrowIndex>>,
@@ -150,18 +143,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
150143
tcx: TyCtxt<'a, 'gcx, 'tcx>,
151144
mir: &'a Mir<'tcx>,
152145
nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
153-
def_id: DefId,
154-
body_id: Option<hir::BodyId>,
155146
borrow_set: &Rc<BorrowSet<'tcx>>,
156147
) -> Self {
157-
let scope_tree = tcx.region_scope_tree(def_id);
158-
let root_scope = body_id.map(|body_id| {
159-
region::Scope {
160-
id: tcx.hir.body(body_id).value.hir_id.local_id,
161-
data: region::ScopeData::CallSite
162-
}
163-
});
164-
165148
let mut borrows_out_of_scope_at_location = FxHashMap::default();
166149
for (borrow_index, borrow_data) in borrow_set.borrows.iter_enumerated() {
167150
let borrow_region = borrow_data.region.to_region_vid();
@@ -177,8 +160,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
177160
mir: mir,
178161
borrow_set: borrow_set.clone(),
179162
borrows_out_of_scope_at_location,
180-
scope_tree,
181-
root_scope,
182163
_nonlexical_regioncx: nonlexical_regioncx,
183164
}
184165
}
@@ -277,22 +258,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
277258
panic!("could not find BorrowIndex for location {:?}", location);
278259
});
279260

280-
if let RegionKind::ReEmpty = region {
281-
// If the borrowed value dies before the borrow is used, the region for
282-
// the borrow can be empty. Don't track the borrow in that case.
283-
debug!("Borrows::statement_effect_on_borrows \
284-
location: {:?} stmt: {:?} has empty region, killing {:?}",
285-
location, stmt.kind, index);
286-
sets.kill(*index);
287-
return
288-
} else {
289-
debug!("Borrows::statement_effect_on_borrows location: {:?} stmt: {:?}",
290-
location, stmt.kind);
291-
}
292-
293-
assert!(self.borrow_set.region_map.get(region).unwrap_or_else(|| {
294-
panic!("could not find BorrowIndexs for region {:?}", region);
295-
}).contains(&index));
261+
assert!(self.borrow_set.region_map
262+
.get(&region.to_region_vid())
263+
.unwrap_or_else(|| {
264+
panic!("could not find BorrowIndexs for RegionVid {:?}", region);
265+
})
266+
.contains(&index)
267+
);
296268
sets.gen(*index);
297269

298270
// Issue #46746: Two-phase borrows handles
@@ -349,52 +321,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
349321
self.kill_loans_out_of_scope_at_location(sets, location);
350322
}
351323

352-
fn terminator_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location) {
353-
debug!("Borrows::terminator_effect sets: {:?} location: {:?}", sets, location);
354-
355-
let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
356-
panic!("could not find block at location {:?}", location);
357-
});
358-
359-
let term = block.terminator();
360-
match term.kind {
361-
mir::TerminatorKind::Resume |
362-
mir::TerminatorKind::Return |
363-
mir::TerminatorKind::GeneratorDrop => {
364-
// When we return from the function, then all `ReScope`-style regions
365-
// are guaranteed to have ended.
366-
// Normally, there would be `EndRegion` statements that come before,
367-
// and hence most of these loans will already be dead -- but, in some cases
368-
// like unwind paths, we do not always emit `EndRegion` statements, so we
369-
// add some kills here as a "backup" and to avoid spurious error messages.
370-
for (borrow_index, borrow_data) in self.borrow_set.borrows.iter_enumerated() {
371-
if let ReScope(scope) = borrow_data.region {
372-
// Check that the scope is not actually a scope from a function that is
373-
// a parent of our closure. Note that the CallSite scope itself is
374-
// *outside* of the closure, for some weird reason.
375-
if let Some(root_scope) = self.root_scope {
376-
if *scope != root_scope &&
377-
self.scope_tree.is_subscope_of(*scope, root_scope)
378-
{
379-
sets.kill(borrow_index);
380-
}
381-
}
382-
}
383-
}
384-
}
385-
mir::TerminatorKind::Abort |
386-
mir::TerminatorKind::SwitchInt {..} |
387-
mir::TerminatorKind::Drop {..} |
388-
mir::TerminatorKind::DropAndReplace {..} |
389-
mir::TerminatorKind::Call {..} |
390-
mir::TerminatorKind::Assert {..} |
391-
mir::TerminatorKind::Yield {..} |
392-
mir::TerminatorKind::Goto {..} |
393-
mir::TerminatorKind::FalseEdges {..} |
394-
mir::TerminatorKind::FalseUnwind {..} |
395-
mir::TerminatorKind::Unreachable => {}
396-
}
397-
}
324+
fn terminator_effect(&self, _: &mut BlockSets<BorrowIndex>, _: Location) {}
398325

399326
fn propagate_call_return(&self,
400327
_in_out: &mut BitSet<BorrowIndex>,

0 commit comments

Comments
 (0)