encapsulate the Region struct within region inference
This commit is contained in:
parent
bfc696ad8a
commit
b772827350
3 changed files with 62 additions and 44 deletions
|
|
@ -139,11 +139,21 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
|||
location: Location) {
|
||||
if let Some(regioncx) = self.nonlexical_regioncx {
|
||||
for (borrow_index, borrow_data) in self.borrows.iter_enumerated() {
|
||||
let borrow_region = regioncx.region_value(borrow_data.region.to_region_index());
|
||||
if !borrow_region.may_contain_point(location) && location != borrow_data.location {
|
||||
debug!("kill_loans_out_of_scope_at_location: kill{:?} \
|
||||
location={:?} borrow_data={:?}", borrow_index, location, borrow_data);
|
||||
sets.kill(&borrow_index);
|
||||
let borrow_region = borrow_data.region.to_region_index();
|
||||
if !regioncx.region_contains_point(borrow_region, location) {
|
||||
// The region checker really considers the borrow
|
||||
// to start at the point **after** the location of
|
||||
// the borrow, but the borrow checker puts the gen
|
||||
// directly **on** the location of the
|
||||
// borrow. This results in a gen/kill both being
|
||||
// generated for same point if we are not
|
||||
// careful. Probably we should change the point of
|
||||
// the gen, but for now we hackily account for the
|
||||
// mismatch here by not generating a kill for the
|
||||
// location on the borrow itself.
|
||||
if location != borrow_data.location {
|
||||
sets.kill(&borrow_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,12 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::ty::{self, RegionKind};
|
||||
use rustc::mir::{Location, Mir};
|
||||
use rustc::mir::Mir;
|
||||
use rustc::mir::transform::MirSource;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt;
|
||||
use util::liveness::{self, LivenessMode, LivenessResult, LocalSet};
|
||||
|
||||
use util as mir_util;
|
||||
|
|
@ -151,39 +150,6 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
|||
});
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Region {
|
||||
points: BTreeSet<Location>,
|
||||
free_regions: BTreeSet<RegionIndex>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Region {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.debug_set()
|
||||
.entries(&self.points)
|
||||
.entries(&self.free_regions)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Region {
|
||||
pub fn add_point(&mut self, point: Location) -> bool {
|
||||
self.points.insert(point)
|
||||
}
|
||||
|
||||
pub fn add_free_region(&mut self, region: RegionIndex) -> bool {
|
||||
self.free_regions.insert(region)
|
||||
}
|
||||
|
||||
pub fn may_contain_point(&self, point: Location) -> bool {
|
||||
self.points.contains(&point)
|
||||
}
|
||||
|
||||
pub fn may_contain_free_region(&self, region: RegionIndex) -> bool {
|
||||
self.free_regions.contains(®ion)
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index!(RegionIndex {
|
||||
DEBUG_FORMAT = "'_#{}r",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,13 +8,15 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::{Region, RegionIndex};
|
||||
use super::RegionIndex;
|
||||
use super::free_regions::FreeRegions;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::{Location, Mir};
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt;
|
||||
|
||||
pub struct RegionInferenceContext<'tcx> {
|
||||
/// Contains the definition for every region variable. Region
|
||||
|
|
@ -54,6 +56,41 @@ struct RegionDefinition<'tcx> {
|
|||
value: Region,
|
||||
}
|
||||
|
||||
/// The value of an individual region variable. Region variables
|
||||
/// consist of a set of points in the CFG as well as a set of "free
|
||||
/// regions", which are sometimes written as `end(R)`. These
|
||||
/// correspond to the named lifetimes and refer to portions of the
|
||||
/// caller's control-flow graph -- specifically some portion that can
|
||||
/// be reached after we return.
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
struct Region {
|
||||
points: BTreeSet<Location>,
|
||||
free_regions: BTreeSet<RegionIndex>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Region {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.debug_set()
|
||||
.entries(&self.points)
|
||||
.entries(&self.free_regions)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Region {
|
||||
fn add_point(&mut self, point: Location) -> bool {
|
||||
self.points.insert(point)
|
||||
}
|
||||
|
||||
fn add_free_region(&mut self, region: RegionIndex) -> bool {
|
||||
self.free_regions.insert(region)
|
||||
}
|
||||
|
||||
fn contains_point(&self, point: Location) -> bool {
|
||||
self.points.contains(&point)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Constraint {
|
||||
sub: RegionIndex,
|
||||
|
|
@ -157,10 +194,15 @@ impl<'a, 'gcx, 'tcx> RegionInferenceContext<'tcx> {
|
|||
self.definitions.indices()
|
||||
}
|
||||
|
||||
/// Returns the inferred value for the region `r`.
|
||||
/// Returns true if the region `r` contains the point `p`.
|
||||
///
|
||||
/// Until `solve()` executes, this value is not particularly meaningful.
|
||||
pub fn region_value(&self, r: RegionIndex) -> &Region {
|
||||
pub fn region_contains_point(&self, r: RegionIndex, p: Location) -> bool {
|
||||
self.definitions[r].value.contains_point(p)
|
||||
}
|
||||
|
||||
/// Returns access to the value of `r` for debugging purposes.
|
||||
pub(super) fn region_value(&self, r: RegionIndex) -> &fmt::Debug {
|
||||
&self.definitions[r].value
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +277,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> Dfs<'a, 'gcx, 'tcx> {
|
|||
while let Some(p) = stack.pop() {
|
||||
debug!(" dfs: p={:?}", p);
|
||||
|
||||
if !from_region.may_contain_point(p) {
|
||||
if !from_region.contains_point(p) {
|
||||
debug!(" not in from-region");
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue