Skip to content

Commit b772827

Browse files
committed
encapsulate the Region struct within region inference
1 parent bfc696a commit b772827

File tree

3 files changed

+62
-44
lines changed

3 files changed

+62
-44
lines changed

src/librustc_mir/dataflow/impls/borrows.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,21 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
139139
location: Location) {
140140
if let Some(regioncx) = self.nonlexical_regioncx {
141141
for (borrow_index, borrow_data) in self.borrows.iter_enumerated() {
142-
let borrow_region = regioncx.region_value(borrow_data.region.to_region_index());
143-
if !borrow_region.may_contain_point(location) && location != borrow_data.location {
144-
debug!("kill_loans_out_of_scope_at_location: kill{:?} \
145-
location={:?} borrow_data={:?}", borrow_index, location, borrow_data);
146-
sets.kill(&borrow_index);
142+
let borrow_region = borrow_data.region.to_region_index();
143+
if !regioncx.region_contains_point(borrow_region, location) {
144+
// The region checker really considers the borrow
145+
// to start at the point **after** the location of
146+
// the borrow, but the borrow checker puts the gen
147+
// directly **on** the location of the
148+
// borrow. This results in a gen/kill both being
149+
// generated for same point if we are not
150+
// careful. Probably we should change the point of
151+
// the gen, but for now we hackily account for the
152+
// mismatch here by not generating a kill for the
153+
// location on the borrow itself.
154+
if location != borrow_data.location {
155+
sets.kill(&borrow_index);
156+
}
147157
}
148158
}
149159
}

src/librustc_mir/transform/nll/mod.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99
// except according to those terms.
1010

1111
use rustc::ty::{self, RegionKind};
12-
use rustc::mir::{Location, Mir};
12+
use rustc::mir::Mir;
1313
use rustc::mir::transform::MirSource;
1414
use rustc::infer::InferCtxt;
1515
use rustc::util::nodemap::FxHashMap;
1616
use rustc_data_structures::indexed_vec::Idx;
1717
use std::collections::BTreeSet;
18-
use std::fmt;
1918
use util::liveness::{self, LivenessMode, LivenessResult, LocalSet};
2019

2120
use util as mir_util;
@@ -151,39 +150,6 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
151150
});
152151
}
153152

154-
#[derive(Clone, Default, PartialEq, Eq)]
155-
pub struct Region {
156-
points: BTreeSet<Location>,
157-
free_regions: BTreeSet<RegionIndex>,
158-
}
159-
160-
impl fmt::Debug for Region {
161-
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
162-
formatter.debug_set()
163-
.entries(&self.points)
164-
.entries(&self.free_regions)
165-
.finish()
166-
}
167-
}
168-
169-
impl Region {
170-
pub fn add_point(&mut self, point: Location) -> bool {
171-
self.points.insert(point)
172-
}
173-
174-
pub fn add_free_region(&mut self, region: RegionIndex) -> bool {
175-
self.free_regions.insert(region)
176-
}
177-
178-
pub fn may_contain_point(&self, point: Location) -> bool {
179-
self.points.contains(&point)
180-
}
181-
182-
pub fn may_contain_free_region(&self, region: RegionIndex) -> bool {
183-
self.free_regions.contains(&region)
184-
}
185-
}
186-
187153
newtype_index!(RegionIndex {
188154
DEBUG_FORMAT = "'_#{}r",
189155
});

src/librustc_mir/transform/nll/region_infer.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::{Region, RegionIndex};
11+
use super::RegionIndex;
1212
use super::free_regions::FreeRegions;
1313
use rustc::infer::InferCtxt;
1414
use rustc::mir::{Location, Mir};
1515
use rustc::ty;
1616
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
1717
use rustc_data_structures::fx::FxHashSet;
18+
use std::collections::BTreeSet;
19+
use std::fmt;
1820

1921
pub struct RegionInferenceContext<'tcx> {
2022
/// Contains the definition for every region variable. Region
@@ -54,6 +56,41 @@ struct RegionDefinition<'tcx> {
5456
value: Region,
5557
}
5658

59+
/// The value of an individual region variable. Region variables
60+
/// consist of a set of points in the CFG as well as a set of "free
61+
/// regions", which are sometimes written as `end(R)`. These
62+
/// correspond to the named lifetimes and refer to portions of the
63+
/// caller's control-flow graph -- specifically some portion that can
64+
/// be reached after we return.
65+
#[derive(Clone, Default, PartialEq, Eq)]
66+
struct Region {
67+
points: BTreeSet<Location>,
68+
free_regions: BTreeSet<RegionIndex>,
69+
}
70+
71+
impl fmt::Debug for Region {
72+
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
73+
formatter.debug_set()
74+
.entries(&self.points)
75+
.entries(&self.free_regions)
76+
.finish()
77+
}
78+
}
79+
80+
impl Region {
81+
fn add_point(&mut self, point: Location) -> bool {
82+
self.points.insert(point)
83+
}
84+
85+
fn add_free_region(&mut self, region: RegionIndex) -> bool {
86+
self.free_regions.insert(region)
87+
}
88+
89+
fn contains_point(&self, point: Location) -> bool {
90+
self.points.contains(&point)
91+
}
92+
}
93+
5794
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
5895
pub struct Constraint {
5996
sub: RegionIndex,
@@ -157,10 +194,15 @@ impl<'a, 'gcx, 'tcx> RegionInferenceContext<'tcx> {
157194
self.definitions.indices()
158195
}
159196

160-
/// Returns the inferred value for the region `r`.
197+
/// Returns true if the region `r` contains the point `p`.
161198
///
162199
/// Until `solve()` executes, this value is not particularly meaningful.
163-
pub fn region_value(&self, r: RegionIndex) -> &Region {
200+
pub fn region_contains_point(&self, r: RegionIndex, p: Location) -> bool {
201+
self.definitions[r].value.contains_point(p)
202+
}
203+
204+
/// Returns access to the value of `r` for debugging purposes.
205+
pub(super) fn region_value(&self, r: RegionIndex) -> &fmt::Debug {
164206
&self.definitions[r].value
165207
}
166208

@@ -235,7 +277,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> Dfs<'a, 'gcx, 'tcx> {
235277
while let Some(p) = stack.pop() {
236278
debug!(" dfs: p={:?}", p);
237279

238-
if !from_region.may_contain_point(p) {
280+
if !from_region.contains_point(p) {
239281
debug!(" not in from-region");
240282
continue;
241283
}

0 commit comments

Comments
 (0)