Auto merge of #41702 - frewsxcv:rollup, r=frewsxcv

Rollup of 6 pull requests

- Successful merges: #41661, #41662, #41673, #41688, #41692, #41693
- Failed merges:
This commit is contained in:
bors 2017-05-02 14:56:11 +00:00
commit ed1f26ddda
108 changed files with 1391 additions and 1236 deletions

View file

@ -414,8 +414,8 @@ class RustBuild(object):
# The goal here is to come up with the same triple as LLVM would,
# at least for the subset of platforms we're willing to target.
if ostype == 'Linux':
os = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding)
if os == 'Android':
os_from_sp = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding)
if os_from_sp == 'Android':
ostype = 'linux-android'
else:
ostype = 'unknown-linux-gnu'

View file

@ -276,7 +276,7 @@ pub trait Into<T>: Sized {
pub trait From<T>: Sized {
/// Performs the conversion.
#[stable(feature = "rust1", since = "1.0.0")]
fn from(T) -> Self;
fn from(_: T) -> Self;
}
/// An attempted conversion that consumes `self`, which may or may not be

View file

@ -403,8 +403,8 @@ impl<S: Sip> Default for Hasher<S> {
#[doc(hidden)]
trait Sip {
fn c_rounds(&mut State);
fn d_rounds(&mut State);
fn c_rounds(_: &mut State);
fn d_rounds(_: &mut State);
}
#[derive(Debug, Clone, Default)]

View file

@ -2878,10 +2878,10 @@ pub trait Carrier {
type Error;
/// Create a `Carrier` from a success value.
fn from_success(Self::Success) -> Self;
fn from_success(_: Self::Success) -> Self;
/// Create a `Carrier` from an error value.
fn from_error(Self::Error) -> Self;
fn from_error(_: Self::Error) -> Self;
/// Translate this `Carrier` to another implementation of `Carrier` with the
/// same associated types.

View file

@ -53,7 +53,7 @@ pub trait Sample<Support> {
// trait called `Sample` and the other should be `DependentSample`.
pub trait IndependentSample<Support>: Sample<Support> {
/// Generate a random value.
fn ind_sample<R: Rng>(&self, &mut R) -> Support;
fn ind_sample<R: Rng>(&self, _: &mut R) -> Support;
}
/// A wrapper for generating types that implement `Rand` via the

View file

@ -329,7 +329,7 @@ impl<'a, R: fmt::Debug> fmt::Debug for AsciiGenerator<'a, R> {
/// the same stream of randomness multiple times.
pub trait SeedableRng<Seed>: Rng {
/// Reseed an RNG with the given seed.
fn reseed(&mut self, Seed);
fn reseed(&mut self, _: Seed);
/// Create a new RNG with the given seed.
fn from_seed(seed: Seed) -> Self;

View file

@ -15,9 +15,11 @@ use syntax::ast;
use syntax::ptr::P;
use hir::{self, PatKind};
use hir::def_id::DefId;
struct CFGBuilder<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
owner_def_id: DefId,
tables: &'a ty::TypeckTables<'tcx>,
graph: CFGGraph,
fn_exit: CFGIndex,
@ -56,6 +58,7 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut cfg_builder = CFGBuilder {
tcx: tcx,
owner_def_id,
tables: tables,
graph: graph,
fn_exit: fn_exit,
@ -583,11 +586,12 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
scope_id: ast::NodeId,
to_index: CFGIndex) {
let mut data = CFGEdgeData { exiting_scopes: vec![] };
let mut scope = self.tcx.region_maps.node_extent(from_expr.id);
let target_scope = self.tcx.region_maps.node_extent(scope_id);
let mut scope = self.tcx.node_extent(from_expr.id);
let target_scope = self.tcx.node_extent(scope_id);
let region_maps = self.tcx.region_maps(self.owner_def_id);
while scope != target_scope {
data.exiting_scopes.push(scope.node_id(&self.tcx.region_maps));
scope = self.tcx.region_maps.encl_scope(scope);
data.exiting_scopes.push(scope.node_id());
scope = region_maps.encl_scope(scope);
}
self.graph.add_edge(from_index, to_index, data);
}

View file

@ -56,7 +56,7 @@ pub enum DepNode<D: Clone + Debug> {
WorkProduct(Arc<WorkProductId>),
// Represents different phases in the compiler.
RegionResolveCrate,
RegionMaps(D),
Coherence,
Resolve,
CoherenceCheckTrait(D),
@ -197,7 +197,6 @@ impl<D: Clone + Debug> DepNode<D> {
BorrowCheckKrate => Some(BorrowCheckKrate),
MirKrate => Some(MirKrate),
TypeckBodiesKrate => Some(TypeckBodiesKrate),
RegionResolveCrate => Some(RegionResolveCrate),
Coherence => Some(Coherence),
Resolve => Some(Resolve),
Variance => Some(Variance),
@ -223,6 +222,7 @@ impl<D: Clone + Debug> DepNode<D> {
def_ids.map(MirShim)
}
BorrowCheck(ref d) => op(d).map(BorrowCheck),
RegionMaps(ref d) => op(d).map(RegionMaps),
RvalueCheck(ref d) => op(d).map(RvalueCheck),
TransCrateItem(ref d) => op(d).map(TransCrateItem),
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),

View file

@ -39,7 +39,7 @@ use syntax::codemap::Spanned;
use syntax_pos::Span;
use hir::*;
use hir::def::Def;
use hir::map::Map;
use hir::map::{self, Map};
use super::itemlikevisit::DeepVisitor;
use std::cmp;
@ -140,6 +140,23 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> {
/// to monitor future changes to `Visitor` in case a new method with a
/// new default implementation gets introduced.)
pub trait Visitor<'v> : Sized {
/// Invokes the suitable visitor method for the given `Node`
/// extracted from the hir map.
fn visit_hir_map_node(&mut self, node: map::Node<'v>) {
match node {
map::NodeItem(a) => self.visit_item(a),
map::NodeForeignItem(a) => self.visit_foreign_item(a),
map::NodeTraitItem(a) => self.visit_trait_item(a),
map::NodeImplItem(a) => self.visit_impl_item(a),
map::NodeExpr(a) => self.visit_expr(a),
map::NodeStmt(a) => self.visit_stmt(a),
map::NodeTy(a) => self.visit_ty(a),
map::NodePat(a) => self.visit_pat(a),
map::NodeBlock(a) => self.visit_block(a),
_ => bug!("Visitor::visit_hir_map_node() not yet impl for node `{:?}`", node)
}
}
///////////////////////////////////////////////////////////////////////////
// Nested items.

View file

@ -39,7 +39,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'t
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Region {
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionKind<'tcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
@ -432,17 +432,6 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
FnPtrAddrCast
});
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtent
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
hcx.tcx().region_maps.code_extent_data(*self).hash_stable(hcx, hasher);
});
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtentData
{
fn hash_stable<W: StableHasherResult>(&self,
@ -477,7 +466,7 @@ impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
custom_kind
});
impl_stable_hash_for!(struct ty::FreeRegion {
impl_stable_hash_for!(struct ty::FreeRegion<'tcx> {
scope,
bound_region
});

View file

@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
}
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
// Never make variables for regions bound within the type itself,
// nor for erased regions.

View file

@ -78,8 +78,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
}
}
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region> {
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})",
self.tag(),
a,

View file

@ -69,6 +69,7 @@ use traits::{ObligationCause, ObligationCauseCode};
use ty::{self, TyCtxt, TypeFoldable};
use ty::{Region, Issue32330};
use ty::error::TypeError;
use syntax::ast::DUMMY_NODE_ID;
use syntax_pos::{Pos, Span};
use errors::{DiagnosticBuilder, DiagnosticStyledString};
@ -78,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn note_and_explain_region(self,
err: &mut DiagnosticBuilder,
prefix: &str,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
suffix: &str) {
fn item_scope_tag(item: &hir::Item) -> &'static str {
match item.node {
@ -123,14 +124,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
format!("{}unknown scope: {:?}{}. Please report a bug.",
prefix, scope, suffix)
};
let span = match scope.span(&self.region_maps, &self.hir) {
let span = match scope.span(&self.hir) {
Some(s) => s,
None => {
err.note(&unknown_scope());
return;
}
};
let tag = match self.hir.find(scope.node_id(&self.region_maps)) {
let tag = match self.hir.find(scope.node_id()) {
Some(hir_map::NodeBlock(_)) => "block",
Some(hir_map::NodeExpr(expr)) => match expr.node {
hir::ExprCall(..) => "call",
@ -150,7 +151,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
return;
}
};
let scope_decorated_tag = match self.region_maps.code_extent_data(scope) {
let scope_decorated_tag = match *scope {
region::CodeExtentData::Misc(_) => tag,
region::CodeExtentData::CallSiteScope { .. } => {
"scope of call-site for function"
@ -183,7 +184,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
};
let node = fr.scope.node_id(&self.region_maps);
let node = fr.scope.map(|s| s.node_id())
.unwrap_or(DUMMY_NODE_ID);
let unknown;
let tag = match self.hir.find(node) {
Some(hir_map::NodeBlock(_)) |
@ -515,7 +517,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
values.1.push_normal("<");
}
fn lifetime_display(lifetime: &Region) -> String {
fn lifetime_display(lifetime: Region) -> String {
let s = format!("{}", lifetime);
if s.is_empty() {
"'_".to_string()
@ -767,7 +769,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn report_generic_bound_failure(&self,
origin: SubregionOrigin<'tcx>,
bound_kind: GenericKind<'tcx>,
sub: &'tcx Region)
sub: Region<'tcx>)
{
// FIXME: it would be better to report the first error message
// with the span of the parameter itself, rather than the span
@ -846,9 +848,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn report_sub_sup_conflict(&self,
var_origin: RegionVariableOrigin,
sub_origin: SubregionOrigin<'tcx>,
sub_region: &'tcx Region,
sub_region: Region<'tcx>,
sup_origin: SubregionOrigin<'tcx>,
sup_region: &'tcx Region) {
sup_region: Region<'tcx>) {
let mut err = self.report_inference_failure(var_origin);
self.tcx.note_and_explain_region(&mut err,

View file

@ -146,8 +146,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub(super) fn report_concrete_failure(&self,
origin: SubregionOrigin<'tcx>,
sub: &'tcx Region,
sup: &'tcx Region)
sub: Region<'tcx>,
sup: Region<'tcx>)
-> DiagnosticBuilder<'tcx> {
match origin {
infer::Subtype(trace) => {

View file

@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
self.infcx.tcx
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReEarlyBound(..) |
ty::ReLateBound(..) => {

View file

@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
}
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReVar(v) if self.region_vars.contains(&v) => {
self.infcx.next_region_var(self.origin.clone())

View file

@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
lattice::super_lattice_tys(self, a, b)
}
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region> {
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})",
self.tag(),
a,

View file

@ -269,9 +269,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
snapshot: &CombinedSnapshot,
debruijn: ty::DebruijnIndex,
new_vars: &[ty::RegionVid],
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
r0: &'tcx ty::Region)
-> &'tcx ty::Region {
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
r0: ty::Region<'tcx>)
-> ty::Region<'tcx> {
// Regions that pre-dated the LUB computation stay as they are.
if !is_var_in_set(new_vars, r0) {
assert!(!r0.is_bound());
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
// Variables created during LUB computation which are
// *related* to regions that pre-date the LUB computation
// stay as they are.
if !tainted.iter().all(|r| is_var_in_set(new_vars, *r)) {
if !tainted.iter().all(|&r| is_var_in_set(new_vars, r)) {
debug!("generalize_region(r0={:?}): \
non-new-variables found in {:?}",
r0, tainted);
@ -365,11 +365,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
snapshot: &CombinedSnapshot,
debruijn: ty::DebruijnIndex,
new_vars: &[ty::RegionVid],
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
a_vars: &[ty::RegionVid],
b_vars: &[ty::RegionVid],
r0: &'tcx ty::Region)
-> &'tcx ty::Region {
r0: ty::Region<'tcx>)
-> ty::Region<'tcx> {
if !is_var_in_set(new_vars, r0) {
assert!(!r0.is_bound());
return r0;
@ -434,8 +434,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
span: Span,
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
r: &'tcx ty::Region) -> &'tcx ty::Region
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
r: ty::Region<'tcx>) -> ty::Region<'tcx>
{
for (a_br, a_r) in a_map {
if *a_r == r {
@ -450,14 +450,14 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
debruijn: ty::DebruijnIndex)
-> &'tcx ty::Region {
-> ty::Region<'tcx> {
infcx.region_vars.new_bound(debruijn)
}
}
}
fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
-> Vec<ty::RegionVid> {
map.iter()
.map(|(_, &r)| match *r {
@ -472,7 +472,7 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
.collect()
}
fn is_var_in_set(new_vars: &[ty::RegionVid], r: &ty::Region) -> bool {
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
match *r {
ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
_ => false
@ -484,7 +484,7 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
mut fldr: F)
-> T
where T: TypeFoldable<'tcx>,
F: FnMut(&'tcx ty::Region, ty::DebruijnIndex) -> &'tcx ty::Region,
F: FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
{
tcx.fold_regions(unbound_value, &mut false, |region, current_depth| {
// we should only be encountering "escaping" late-bound regions here,
@ -502,9 +502,9 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn tainted_regions(&self,
snapshot: &CombinedSnapshot,
r: &'tcx ty::Region,
r: ty::Region<'tcx>,
directions: TaintDirections)
-> FxHashSet<&'tcx ty::Region> {
-> FxHashSet<ty::Region<'tcx>> {
self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions)
}
@ -731,7 +731,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// region back to the `ty::BoundRegion` that it originally
// represented. Because `leak_check` passed, we know that
// these taint sets are mutually disjoint.
let inv_skol_map: FxHashMap<&'tcx ty::Region, ty::BoundRegion> =
let inv_skol_map: FxHashMap<ty::Region<'tcx>, ty::BoundRegion> =
skol_map
.iter()
.flat_map(|(&skol_br, &skol)| {

View file

@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
lattice::super_lattice_tys(self, a, b)
}
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region> {
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})",
self.tag(),
a,

View file

@ -20,7 +20,8 @@ pub use self::region_inference::{GenericKind, VerifyBound};
use hir::def_id::DefId;
use hir;
use middle::free_region::FreeRegionMap;
use middle::free_region::{FreeRegionMap, RegionRelations};
use middle::region::RegionMaps;
use middle::mem_categorization as mc;
use middle::mem_categorization::McResult;
use middle::lang_items;
@ -205,7 +206,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
/// region that each late-bound region was replaced with.
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, ty::Region<'tcx>>;
/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
@ -1008,7 +1009,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn add_given(&self,
sub: ty::FreeRegion,
sub: ty::FreeRegion<'tcx>,
sup: ty::RegionVid)
{
self.region_vars.add_given(sub, sup);
@ -1107,8 +1108,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn sub_regions(&self,
origin: SubregionOrigin<'tcx>,
a: &'tcx ty::Region,
b: &'tcx ty::Region) {
a: ty::Region<'tcx>,
b: ty::Region<'tcx>) {
debug!("sub_regions({:?} <: {:?})", a, b);
self.region_vars.make_subregion(origin, a, b);
}
@ -1210,7 +1211,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn next_region_var(&self, origin: RegionVariableOrigin)
-> &'tcx ty::Region {
-> ty::Region<'tcx> {
self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
}
@ -1219,7 +1220,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn region_var_for_def(&self,
span: Span,
def: &ty::RegionParameterDef)
-> &'tcx ty::Region {
-> ty::Region<'tcx> {
self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
}
@ -1270,7 +1271,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
})
}
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region {
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region<'tcx> {
self.region_vars.new_bound(debruijn)
}
@ -1322,9 +1323,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn resolve_regions_and_report_errors(&self,
free_regions: &FreeRegionMap,
subject_node_id: ast::NodeId) {
let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
region_context: DefId,
region_map: &RegionMaps<'tcx>,
free_regions: &FreeRegionMap<'tcx>) {
let region_rels = RegionRelations::new(self.tcx,
region_context,
region_map,
free_regions);
let errors = self.region_vars.resolve_regions(&region_rels);
if !self.is_tainted_by_errors() {
// As a heuristic, just skip reporting region errors
// altogether if other errors have been reported while
@ -1531,7 +1537,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span,
lbrct: LateBoundRegionConversionTime,
value: &ty::Binder<T>)
-> (T, FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
-> (T, FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
where T : TypeFoldable<'tcx>
{
self.tcx.replace_late_bound_regions(
@ -1577,7 +1583,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn verify_generic_bound(&self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
a: &'tcx ty::Region,
a: ty::Region<'tcx>,
bound: VerifyBound<'tcx>) {
debug!("verify_generic_bound({:?}, {:?} <: {:?})",
kind,

View file

@ -18,7 +18,9 @@
/// For clarity, rename the graphviz crate locally to dot.
use graphviz as dot;
use ty::{self, TyCtxt};
use hir::def_id::DefIndex;
use ty;
use middle::free_region::RegionRelations;
use middle::region::CodeExtent;
use super::Constraint;
use infer::SubregionOrigin;
@ -32,7 +34,6 @@ use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering};
use syntax::ast;
fn print_help_message() {
println!("\
@ -55,18 +56,18 @@ graphs will be printed. \n\
pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>,
subject_node: ast::NodeId)
region_rels: &RegionRelations<'a, 'gcx, 'tcx>)
{
let tcx = region_vars.tcx;
let context = region_rels.context;
if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph {
return;
}
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
.ok().and_then(|s| s.parse().map(ast::NodeId::new).ok());
.ok().and_then(|s| s.parse().map(DefIndex::new).ok());
if requested_node.is_some() && requested_node != Some(subject_node) {
if requested_node.is_some() && requested_node != Some(context.index) {
return;
}
@ -98,7 +99,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
let mut new_str = String::new();
for c in output_template.chars() {
if c == '%' {
new_str.push_str(&subject_node.to_string());
new_str.push_str(&context.index.as_usize().to_string());
} else {
new_str.push(c);
}
@ -110,7 +111,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
};
let constraints = &*region_vars.constraints.borrow();
match dump_region_constraints_to(tcx, constraints, &output_path) {
match dump_region_constraints_to(region_rels, constraints, &output_path) {
Ok(()) => {}
Err(e) => {
let msg = format!("io error dumping region constraints: {}", e);
@ -120,28 +121,28 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
}
struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
graph_name: String,
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
node_ids: FxHashMap<Node, usize>,
node_ids: FxHashMap<Node<'tcx>, usize>,
}
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
enum Node {
enum Node<'tcx> {
RegionVid(ty::RegionVid),
Region(ty::Region),
Region(ty::RegionKind<'tcx>),
}
// type Edge = Constraint;
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
enum Edge<'tcx> {
Constraint(Constraint<'tcx>),
EnclScope(CodeExtent, CodeExtent),
EnclScope(CodeExtent<'tcx>, CodeExtent<'tcx>),
}
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
name: String,
fn new(name: String,
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
map: &'a ConstraintMap<'tcx>)
-> ConstraintGraph<'a, 'gcx, 'tcx> {
let mut i = 0;
@ -159,23 +160,23 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
add_node(n2);
}
tcx.region_maps.each_encl_scope(|sub, sup| {
add_node(Node::Region(ty::ReScope(*sub)));
add_node(Node::Region(ty::ReScope(*sup)));
region_rels.region_maps.each_encl_scope(|sub, sup| {
add_node(Node::Region(ty::ReScope(sub)));
add_node(Node::Region(ty::ReScope(sup)));
});
}
ConstraintGraph {
tcx: tcx,
map,
node_ids,
region_rels,
graph_name: name,
map: map,
node_ids: node_ids,
}
}
}
impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
type Node = Node;
type Node = Node<'tcx>;
type Edge = Edge<'tcx>;
fn graph_id(&self) -> dot::Id {
dot::Id::new(&*self.graph_name).unwrap()
@ -208,7 +209,7 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
}
}
fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
fn constraint_to_nodes<'tcx>(c: &Constraint<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
match *c {
Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
(Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
@ -221,7 +222,7 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
}
}
fn edge_to_nodes(e: &Edge) -> (Node, Node) {
fn edge_to_nodes<'tcx>(e: &Edge<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
match *e {
Edge::Constraint(ref c) => constraint_to_nodes(c),
Edge::EnclScope(sub, sup) => {
@ -232,9 +233,9 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) {
}
impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
type Node = Node;
type Node = Node<'tcx>;
type Edge = Edge<'tcx>;
fn nodes(&self) -> dot::Nodes<Node> {
fn nodes(&self) -> dot::Nodes<Node<'tcx>> {
let mut set = FxHashSet();
for node in self.node_ids.keys() {
set.insert(*node);
@ -245,16 +246,16 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
fn edges(&self) -> dot::Edges<Edge<'tcx>> {
debug!("constraint graph has {} edges", self.map.len());
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
self.region_rels.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
debug!("region graph has {} edges", v.len());
Cow::Owned(v)
}
fn source(&self, edge: &Edge<'tcx>) -> Node {
fn source(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
let (n1, _) = edge_to_nodes(edge);
debug!("edge {:?} has source {:?}", edge, n1);
n1
}
fn target(&self, edge: &Edge<'tcx>) -> Node {
fn target(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
let (_, n2) = edge_to_nodes(edge);
debug!("edge {:?} has target {:?}", edge, n2);
n2
@ -263,14 +264,14 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
pub type ConstraintMap<'tcx> = FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
fn dump_region_constraints_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
map: &ConstraintMap<'tcx>,
path: &str)
-> io::Result<()> {
debug!("dump_region_constraints map (len: {}) path: {}",
map.len(),
path);
let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
let g = ConstraintGraph::new(format!("region_constraints"), region_rels, map);
debug!("dump_region_constraints calling render");
let mut v = Vec::new();
dot::render(&g, &mut v).unwrap();

View file

@ -22,7 +22,7 @@ use super::unify_key;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
use rustc_data_structures::unify::{self, UnificationTable};
use middle::free_region::FreeRegionMap;
use middle::free_region::RegionRelations;
use ty::{self, Ty, TyCtxt};
use ty::{Region, RegionVid};
use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased};
@ -33,7 +33,6 @@ use std::cmp::Ordering::{self, Less, Greater, Equal};
use std::fmt;
use std::mem;
use std::u32;
use syntax::ast;
mod graphviz;
@ -44,17 +43,17 @@ pub enum Constraint<'tcx> {
ConstrainVarSubVar(RegionVid, RegionVid),
// Concrete region is subregion of region variable
ConstrainRegSubVar(&'tcx Region, RegionVid),
ConstrainRegSubVar(Region<'tcx>, RegionVid),
// Region variable is subregion of concrete region. This does not
// directly affect inference, but instead is checked after
// inference is complete.
ConstrainVarSubReg(RegionVid, &'tcx Region),
ConstrainVarSubReg(RegionVid, Region<'tcx>),
// A constraint where neither side is a variable. This does not
// directly affect inference, but instead is checked after
// inference is complete.
ConstrainRegSubReg(&'tcx Region, &'tcx Region),
ConstrainRegSubReg(Region<'tcx>, Region<'tcx>),
}
// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
@ -66,7 +65,7 @@ pub enum Constraint<'tcx> {
pub struct Verify<'tcx> {
kind: GenericKind<'tcx>,
origin: SubregionOrigin<'tcx>,
region: &'tcx Region,
region: Region<'tcx>,
bound: VerifyBound<'tcx>,
}
@ -86,14 +85,14 @@ pub enum VerifyBound<'tcx> {
// Put another way, the subject value is known to outlive all
// regions in {R}, so if any of those outlives 'min, then the
// bound is met.
AnyRegion(Vec<&'tcx Region>),
AnyRegion(Vec<Region<'tcx>>),
// B = forall {R} --> all 'r in {R} must outlive 'min
//
// Put another way, the subject value is known to outlive some
// region in {R}, so if all of those outlives 'min, then the bound
// is met.
AllRegions(Vec<&'tcx Region>),
AllRegions(Vec<Region<'tcx>>),
// B = exists {B} --> 'min must meet some bound b in {B}
AnyBound(Vec<VerifyBound<'tcx>>),
@ -104,8 +103,8 @@ pub enum VerifyBound<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct TwoRegions<'tcx> {
a: &'tcx Region,
b: &'tcx Region,
a: Region<'tcx>,
b: Region<'tcx>,
}
#[derive(Copy, Clone, PartialEq)]
@ -128,7 +127,7 @@ pub enum UndoLogEntry<'tcx> {
AddVerify(usize),
/// We added the given `given`
AddGiven(ty::FreeRegion, ty::RegionVid),
AddGiven(ty::FreeRegion<'tcx>, ty::RegionVid),
/// We added a GLB/LUB "combinaton variable"
AddCombination(CombineMapType, TwoRegions<'tcx>),
@ -153,13 +152,13 @@ pub enum RegionResolutionError<'tcx> {
/// `ConcreteFailure(o, a, b)`:
///
/// `o` requires that `a <= b`, but this does not hold
ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>),
/// `GenericBoundFailure(p, s, a)
///
/// The parameter/associated-type `p` must be known to outlive the lifetime
/// `a` (but none of the known bounds are sufficient).
GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, &'tcx Region),
GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region<'tcx>),
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
///
@ -168,14 +167,14 @@ pub enum RegionResolutionError<'tcx> {
/// `sub_r <= sup_r` does not hold.
SubSupConflict(RegionVariableOrigin,
SubregionOrigin<'tcx>,
&'tcx Region,
Region<'tcx>,
SubregionOrigin<'tcx>,
&'tcx Region),
Region<'tcx>),
}
#[derive(Clone, Debug)]
pub enum ProcessedErrorOrigin<'tcx> {
ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>),
VariableFailure(RegionVariableOrigin),
}
@ -214,7 +213,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
// record the fact that `'a <= 'b` is implied by the fn signature,
// and then ignore the constraint when solving equations. This is
// a bit of a hack but seems to work.
givens: RefCell<FxHashSet<(ty::FreeRegion, ty::RegionVid)>>,
givens: RefCell<FxHashSet<(ty::FreeRegion<'tcx>, ty::RegionVid)>>,
lubs: RefCell<CombineMap<'tcx>>,
glbs: RefCell<CombineMap<'tcx>>,
@ -271,12 +270,12 @@ impl TaintDirections {
struct TaintSet<'tcx> {
directions: TaintDirections,
regions: FxHashSet<&'tcx ty::Region>
regions: FxHashSet<ty::Region<'tcx>>
}
impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
fn new(directions: TaintDirections,
initial_region: &'tcx ty::Region)
initial_region: ty::Region<'tcx>)
-> Self {
let mut regions = FxHashSet();
regions.insert(initial_region);
@ -328,7 +327,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
}
}
fn into_set(self) -> FxHashSet<&'tcx ty::Region> {
fn into_set(self) -> FxHashSet<ty::Region<'tcx>> {
self.regions
}
@ -337,8 +336,8 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
}
fn add_edge(&mut self,
source: &'tcx ty::Region,
target: &'tcx ty::Region) {
source: ty::Region<'tcx>,
target: ty::Region<'tcx>) {
if self.directions.incoming {
if self.regions.contains(&target) {
self.regions.insert(source);
@ -499,7 +498,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// it's just there to make it explicit which snapshot bounds the
/// skolemized region that results. It should always be the top-most snapshot.
pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot)
-> &'tcx Region {
-> Region<'tcx> {
assert!(self.in_snapshot());
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
@ -513,7 +512,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// completes to remove all trace of the skolemized regions
/// created in that time.
pub fn pop_skolemized(&self,
skols: &FxHashSet<&'tcx ty::Region>,
skols: &FxHashSet<ty::Region<'tcx>>,
snapshot: &RegionSnapshot) {
debug!("pop_skolemized_regions(skols={:?})", skols);
@ -567,7 +566,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
self.skolemization_count.set(snapshot.skolemization_count);
return;
fn kill_constraint<'tcx>(skols: &FxHashSet<&'tcx ty::Region>,
fn kill_constraint<'tcx>(skols: &FxHashSet<ty::Region<'tcx>>,
undo_entry: &UndoLogEntry<'tcx>)
-> bool {
match undo_entry {
@ -596,7 +595,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> &'tcx Region {
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region<'tcx> {
// Creates a fresh bound variable for use in GLB computations.
// See discussion of GLB computation in the large comment at
// the top of this file for more details.
@ -662,7 +661,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
pub fn add_given(&self, sub: ty::FreeRegion<'tcx>, sup: ty::RegionVid) {
// cannot add givens once regions are resolved
assert!(self.values_are_none());
@ -676,8 +675,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn make_eqregion(&self,
origin: SubregionOrigin<'tcx>,
sub: &'tcx Region,
sup: &'tcx Region) {
sub: Region<'tcx>,
sup: Region<'tcx>) {
if sub != sup {
// Eventually, it would be nice to add direct support for
// equating regions.
@ -692,8 +691,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn make_subregion(&self,
origin: SubregionOrigin<'tcx>,
sub: &'tcx Region,
sup: &'tcx Region) {
sub: Region<'tcx>,
sup: Region<'tcx>) {
// cannot add constraints once regions are resolved
assert!(self.values_are_none());
@ -734,7 +733,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn verify_generic_bound(&self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
sub: &'tcx Region,
sub: Region<'tcx>,
bound: VerifyBound<'tcx>) {
self.add_verify(Verify {
kind: kind,
@ -746,9 +745,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn lub_regions(&self,
origin: SubregionOrigin<'tcx>,
a: &'tcx Region,
b: &'tcx Region)
-> &'tcx Region {
a: Region<'tcx>,
b: Region<'tcx>)
-> Region<'tcx> {
// cannot add constraints once regions are resolved
assert!(self.values_are_none());
@ -772,9 +771,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn glb_regions(&self,
origin: SubregionOrigin<'tcx>,
a: &'tcx Region,
b: &'tcx Region)
-> &'tcx Region {
a: Region<'tcx>,
b: Region<'tcx>)
-> Region<'tcx> {
// cannot add constraints once regions are resolved
assert!(self.values_are_none());
@ -796,7 +795,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
pub fn resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
match *self.values.borrow() {
None => {
span_bug!((*self.var_origins.borrow())[rid.index as usize].span(),
@ -811,7 +810,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
self.tcx.mk_region(ty::ReVar(vid))
}
@ -825,12 +824,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
pub fn combine_vars<F>(&self,
t: CombineMapType,
a: &'tcx Region,
b: &'tcx Region,
a: Region<'tcx>,
b: Region<'tcx>,
origin: SubregionOrigin<'tcx>,
mut relate: F)
-> &'tcx Region
where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, &'tcx Region, &'tcx Region)
-> Region<'tcx>
where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region<'tcx>, Region<'tcx>)
{
let vars = TwoRegions { a: a, b: b };
if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
@ -869,9 +868,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// related to other regions.
pub fn tainted(&self,
mark: &RegionSnapshot,
r0: &'tcx Region,
r0: Region<'tcx>,
directions: TaintDirections)
-> FxHashSet<&'tcx ty::Region> {
-> FxHashSet<ty::Region<'tcx>> {
debug!("tainted(mark={:?}, r0={:?}, directions={:?})",
mark, r0, directions);
@ -892,21 +891,20 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// constraints, assuming such values can be found; if they cannot,
/// errors are reported.
pub fn resolve_regions(&self,
free_regions: &FreeRegionMap,
subject_node: ast::NodeId)
region_rels: &RegionRelations<'a, 'gcx, 'tcx>)
-> Vec<RegionResolutionError<'tcx>> {
debug!("RegionVarBindings: resolve_regions()");
let mut errors = vec![];
let v = self.infer_variable_values(free_regions, &mut errors, subject_node);
let v = self.infer_variable_values(region_rels, &mut errors);
*self.values.borrow_mut() = Some(v);
errors
}
fn lub_concrete_regions(&self,
free_regions: &FreeRegionMap,
a: &'tcx Region,
b: &'tcx Region)
-> &'tcx Region {
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
a: Region<'tcx>,
b: Region<'tcx>)
-> Region<'tcx> {
match (a, b) {
(&ReLateBound(..), _) |
(_, &ReLateBound(..)) |
@ -938,30 +936,31 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// A "free" region can be interpreted as "some region
// at least as big as the block fr.scope_id". So, we can
// reasonably compare free regions and scopes:
let r_id = self.tcx.region_maps.nearest_common_ancestor(fr.scope, s_id);
if r_id == fr.scope {
// if the free region's scope `fr.scope_id` is bigger than
// the scope region `s_id`, then the LUB is the free
// region itself:
self.tcx.mk_region(ReFree(fr))
} else {
// otherwise, we don't know what the free region is,
// so we must conservatively say the LUB is static:
self.tcx.types.re_static
if let Some(fr_scope) = fr.scope {
let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id);
if r_id == fr_scope {
// if the free region's scope `fr.scope_id` is bigger than
// the scope region `s_id`, then the LUB is the free
// region itself:
return self.tcx.mk_region(ReFree(fr));
}
}
// otherwise, we don't know what the free region is,
// so we must conservatively say the LUB is static:
self.tcx.types.re_static
}
(&ReScope(a_id), &ReScope(b_id)) => {
// The region corresponding to an outer block is a
// subtype of the region corresponding to an inner
// block.
self.tcx.mk_region(ReScope(
self.tcx.region_maps.nearest_common_ancestor(a_id, b_id)))
let lub = region_rels.region_maps.nearest_common_ancestor(a_id, b_id);
self.tcx.mk_region(ReScope(lub))
}
(&ReFree(a_fr), &ReFree(b_fr)) => {
self.tcx.mk_region(free_regions.lub_free_regions(a_fr, b_fr))
(&ReFree(_), &ReFree(_)) => {
region_rels.lub_free_regions(a, b)
}
// For these types, we cannot define any additional
@ -982,12 +981,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
#[derive(Copy, Clone, Debug)]
pub enum VarValue<'tcx> {
Value(&'tcx Region),
Value(Region<'tcx>),
ErrorValue,
}
struct RegionAndOrigin<'tcx> {
region: &'tcx Region,
region: Region<'tcx>,
origin: SubregionOrigin<'tcx>,
}
@ -995,24 +994,23 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>;
impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn infer_variable_values(&self,
free_regions: &FreeRegionMap,
errors: &mut Vec<RegionResolutionError<'tcx>>,
subject: ast::NodeId)
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>)
-> Vec<VarValue<'tcx>> {
let mut var_data = self.construct_var_data();
// Dorky hack to cause `dump_constraints` to only get called
// if debug mode is enabled:
debug!("----() End constraint listing (subject={}) {:?}---",
subject,
self.dump_constraints(subject));
graphviz::maybe_print_constraints_for(self, subject);
debug!("----() End constraint listing (context={:?}) {:?}---",
region_rels.context,
self.dump_constraints(region_rels));
graphviz::maybe_print_constraints_for(self, region_rels);
let graph = self.construct_graph();
self.expand_givens(&graph);
self.expansion(free_regions, &mut var_data);
self.collect_errors(free_regions, &mut var_data, errors);
self.collect_var_errors(free_regions, &var_data, &graph, errors);
self.expansion(region_rels, &mut var_data);
self.collect_errors(region_rels, &mut var_data, errors);
self.collect_var_errors(region_rels, &var_data, &graph, errors);
var_data
}
@ -1022,9 +1020,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
.collect()
}
fn dump_constraints(&self, subject: ast::NodeId) {
debug!("----() Start constraint listing (subject={}) ()----",
subject);
fn dump_constraints(&self, free_regions: &RegionRelations<'a, 'gcx, 'tcx>) {
debug!("----() Start constraint listing (context={:?}) ()----",
free_regions.context);
for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() {
debug!("Constraint {} => {:?}", idx, constraint);
}
@ -1055,21 +1053,23 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
}
fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue<'tcx>]) {
fn expansion(&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
var_values: &mut [VarValue<'tcx>]) {
self.iterate_until_fixed_point("Expansion", |constraint, origin| {
debug!("expansion: constraint={:?} origin={:?}",
constraint, origin);
match *constraint {
ConstrainRegSubVar(a_region, b_vid) => {
let b_data = &mut var_values[b_vid.index as usize];
self.expand_node(free_regions, a_region, b_vid, b_data)
self.expand_node(region_rels, a_region, b_vid, b_data)
}
ConstrainVarSubVar(a_vid, b_vid) => {
match var_values[a_vid.index as usize] {
ErrorValue => false,
Value(a_region) => {
let b_node = &mut var_values[b_vid.index as usize];
self.expand_node(free_regions, a_region, b_vid, b_node)
self.expand_node(region_rels, a_region, b_vid, b_node)
}
}
}
@ -1084,8 +1084,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
fn expand_node(&self,
free_regions: &FreeRegionMap,
a_region: &'tcx Region,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
a_region: Region<'tcx>,
b_vid: RegionVid,
b_data: &mut VarValue<'tcx>)
-> bool {
@ -1107,7 +1107,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
match *b_data {
Value(cur_region) => {
let lub = self.lub_concrete_regions(free_regions, a_region, cur_region);
let lub = self.lub_concrete_regions(region_rels, a_region, cur_region);
if lub == cur_region {
return false;
}
@ -1131,7 +1131,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// cases where the region cannot grow larger than a fixed point)
/// and check that they are satisfied.
fn collect_errors(&self,
free_regions: &FreeRegionMap,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
var_data: &mut Vec<VarValue<'tcx>>,
errors: &mut Vec<RegionResolutionError<'tcx>>) {
let constraints = self.constraints.borrow();
@ -1145,7 +1145,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
ConstrainRegSubReg(sub, sup) => {
if free_regions.is_subregion_of(self.tcx, sub, sup) {
if region_rels.is_subregion_of(sub, sup) {
continue;
}
@ -1173,7 +1173,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// Do not report these errors immediately:
// instead, set the variable value to error and
// collect them later.
if !free_regions.is_subregion_of(self.tcx, a_region, b_region) {
if !region_rels.is_subregion_of(a_region, b_region) {
debug!("collect_errors: region error at {:?}: \
cannot verify that {:?}={:?} <= {:?}",
origin,
@ -1189,7 +1189,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
for verify in self.verifys.borrow().iter() {
debug!("collect_errors: verify={:?}", verify);
let sub = normalize(self.tcx, var_data, verify.region);
if verify.bound.is_met(self.tcx, free_regions, var_data, sub) {
if verify.bound.is_met(region_rels, var_data, sub) {
continue;
}
@ -1208,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
/// Go over the variables that were declared to be error variables
/// and create a `RegionResolutionError` for each of them.
fn collect_var_errors(&self,
free_regions: &FreeRegionMap,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
var_data: &[VarValue<'tcx>],
graph: &RegionGraph<'tcx>,
errors: &mut Vec<RegionResolutionError<'tcx>>) {
@ -1257,7 +1257,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
this portion of the code and think hard about it. =) */
let node_vid = RegionVid { index: idx as u32 };
self.collect_error_for_expanding_node(free_regions,
self.collect_error_for_expanding_node(region_rels,
graph,
&mut dup_vec,
node_vid,
@ -1310,7 +1310,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
}
fn collect_error_for_expanding_node(&self,
free_regions: &FreeRegionMap,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
graph: &RegionGraph<'tcx>,
dup_vec: &mut [u32],
node_idx: RegionVid,
@ -1346,7 +1346,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
for lower_bound in &lower_bounds {
for upper_bound in &upper_bounds {
if !free_regions.is_subregion_of(self.tcx, lower_bound.region, upper_bound.region) {
if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) {
let origin = (*self.var_origins.borrow())[node_idx.index as usize].clone();
debug!("region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
sup: {:?}",
@ -1479,8 +1479,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
values: &Vec<VarValue<'tcx>>,
r: &'tcx ty::Region)
-> &'tcx ty::Region {
r: ty::Region<'tcx>)
-> ty::Region<'tcx> {
match *r {
ty::ReVar(rid) => lookup(tcx, values, rid),
_ => r,
@ -1490,7 +1490,7 @@ fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
values: &Vec<VarValue<'tcx>>,
rid: ty::RegionVid)
-> &'tcx ty::Region {
-> ty::Region<'tcx> {
match values[rid.index as usize] {
Value(r) => r,
ErrorValue => tcx.types.re_static, // Previously reported error.
@ -1538,7 +1538,7 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
}
impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
fn for_each_region(&self, f: &mut FnMut(&'tcx ty::Region)) {
fn for_each_region(&self, f: &mut FnMut(ty::Region<'tcx>)) {
match self {
&VerifyBound::AnyRegion(ref rs) |
&VerifyBound::AllRegions(ref rs) => for &r in rs {
@ -1590,29 +1590,30 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
}
}
fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
free_regions: &FreeRegionMap,
fn is_met(&self,
region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
var_values: &Vec<VarValue<'tcx>>,
min: &'tcx ty::Region)
min: ty::Region<'tcx>)
-> bool {
let tcx = region_rels.tcx;
match self {
&VerifyBound::AnyRegion(ref rs) =>
rs.iter()
.map(|&r| normalize(tcx, var_values, r))
.any(|r| free_regions.is_subregion_of(tcx, min, r)),
.any(|r| region_rels.is_subregion_of(min, r)),
&VerifyBound::AllRegions(ref rs) =>
rs.iter()
.map(|&r| normalize(tcx, var_values, r))
.all(|r| free_regions.is_subregion_of(tcx, min, r)),
.all(|r| region_rels.is_subregion_of(min, r)),
&VerifyBound::AnyBound(ref bs) =>
bs.iter()
.any(|b| b.is_met(tcx, free_regions, var_values, min)),
.any(|b| b.is_met(region_rels, var_values, min)),
&VerifyBound::AllBounds(ref bs) =>
bs.iter()
.all(|b| b.is_met(tcx, free_regions, var_values, min)),
.all(|b| b.is_met(region_rels, var_values, min)),
}
}
}

View file

@ -72,7 +72,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
}
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
_ => r,
@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
}
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
_ => r,

View file

@ -127,8 +127,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
}
}
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region> {
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?}) self.cause={:?}",
self.tag(), a, b, self.fields.cause);

View file

@ -23,6 +23,7 @@ use hir::def::Def;
use hir::def_id::{DefId};
use infer::InferCtxt;
use middle::mem_categorization as mc;
use middle::region::RegionMaps;
use ty::{self, TyCtxt, adjustment};
use hir::{self, PatKind};
@ -75,7 +76,7 @@ pub trait Delegate<'tcx> {
borrow_id: ast::NodeId,
borrow_span: Span,
cmt: mc::cmt<'tcx>,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
bk: ty::BorrowKind,
loan_cause: LoanCause);
@ -270,19 +271,24 @@ enum PassArgs {
impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
pub fn new(delegate: &'a mut (Delegate<'tcx>+'a),
region_maps: &'a RegionMaps<'tcx>,
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>)
-> Self
{
ExprUseVisitor::with_options(delegate, infcx, mc::MemCategorizationOptions::default())
ExprUseVisitor::with_options(delegate,
infcx,
region_maps,
mc::MemCategorizationOptions::default())
}
pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a),
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a RegionMaps<'tcx>,
options: mc::MemCategorizationOptions)
-> Self
{
ExprUseVisitor {
mc: mc::MemCategorizationContext::with_options(infcx, options),
mc: mc::MemCategorizationContext::with_options(infcx, region_maps, options),
delegate: delegate
}
}
@ -347,7 +353,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
fn borrow_expr(&mut self,
expr: &hir::Expr,
r: &'tcx ty::Region,
r: ty::Region<'tcx>,
bk: ty::BorrowKind,
cause: LoanCause) {
debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})",

View file

@ -15,18 +15,119 @@
//! `TransitiveRelation` type and use that to decide when one free
//! region outlives another and so forth.
use ty::{self, TyCtxt, FreeRegion, Region};
use hir::def_id::DefId;
use middle::region::RegionMaps;
use ty::{self, Lift, TyCtxt, Region};
use ty::wf::ImpliedBound;
use rustc_data_structures::transitive_relation::TransitiveRelation;
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct FreeRegionMap {
// Stores the relation `a < b`, where `a` and `b` are regions.
relation: TransitiveRelation<Region>
/// Combines a `RegionMaps` (which governs relationships between
/// scopes) and a `FreeRegionMap` (which governs relationships between
/// free regions) to yield a complete relation between concrete
/// regions.
///
/// This stuff is a bit convoluted and should be refactored, but as we
/// move to NLL it'll all go away anyhow.
pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
/// context used to fetch the region maps
pub context: DefId,
/// region maps for the given context
pub region_maps: &'a RegionMaps<'tcx>,
/// free-region relationships
pub free_regions: &'a FreeRegionMap<'tcx>,
}
impl FreeRegionMap {
pub fn new() -> FreeRegionMap {
impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
pub fn new(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
context: DefId,
region_maps: &'a RegionMaps<'tcx>,
free_regions: &'a FreeRegionMap<'tcx>,
) -> Self {
Self {
tcx,
context,
region_maps,
free_regions,
}
}
/// Determines whether one region is a subregion of another. This is intended to run *after
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
pub fn is_subregion_of(&self,
sub_region: ty::Region<'tcx>,
super_region: ty::Region<'tcx>)
-> bool {
let result = sub_region == super_region || {
match (sub_region, super_region) {
(&ty::ReEmpty, _) |
(_, &ty::ReStatic) =>
true,
(&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
self.region_maps.is_subscope_of(sub_scope, super_scope),
(&ty::ReScope(sub_scope), &ty::ReFree(fr)) => {
// 1. It is safe to unwrap `fr.scope` because we
// should only ever wind up comparing against
// `ReScope` in the context of a method or
// body, where `fr.scope` should be `Some`.
self.region_maps.is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) ||
self.is_static(super_region)
}
(&ty::ReFree(_), &ty::ReFree(_)) =>
self.free_regions.relation.contains(&sub_region, &super_region) ||
self.is_static(super_region),
(&ty::ReStatic, &ty::ReFree(_)) =>
self.is_static(super_region),
_ =>
false,
}
};
debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}",
sub_region, super_region, result);
result
}
/// Determines whether this free-region is required to be 'static
fn is_static(&self, super_region: ty::Region<'tcx>) -> bool {
debug!("is_static(super_region={:?})", super_region);
match *super_region {
ty::ReStatic => true,
ty::ReFree(_) => {
let re_static = self.tcx.mk_region(ty::ReStatic);
self.free_regions.relation.contains(&re_static, &super_region)
}
_ => bug!("only free regions should be given to `is_static`")
}
}
pub fn lub_free_regions(&self,
r_a: Region<'tcx>,
r_b: Region<'tcx>)
-> Region<'tcx> {
self.free_regions.lub_free_regions(self.tcx, r_a, r_b)
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct FreeRegionMap<'tcx> {
// Stores the relation `a < b`, where `a` and `b` are regions.
//
// Invariant: only free regions like `'x` or `'static` are stored
// in this relation, not scopes.
relation: TransitiveRelation<Region<'tcx>>
}
impl<'tcx> FreeRegionMap<'tcx> {
pub fn new() -> Self {
FreeRegionMap { relation: TransitiveRelation::new() }
}
@ -34,15 +135,16 @@ impl FreeRegionMap {
self.relation.is_empty()
}
pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
implied_bounds: &[ImpliedBound<'tcx>])
pub fn relate_free_regions_from_implied_bounds(&mut self,
implied_bounds: &[ImpliedBound<'tcx>])
{
debug!("relate_free_regions_from_implied_bounds()");
for implied_bound in implied_bounds {
debug!("implied bound: {:?}", implied_bound);
match *implied_bound {
ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
self.relate_free_regions(free_a, free_b);
ImpliedBound::RegionSubRegion(a @ &ty::ReFree(_), b @ &ty::ReFree(_)) |
ImpliedBound::RegionSubRegion(a @ &ty::ReStatic, b @ &ty::ReFree(_)) => {
self.relate_regions(a, b);
}
ImpliedBound::RegionSubRegion(..) |
ImpliedBound::RegionSubParam(..) |
@ -53,7 +155,7 @@ impl FreeRegionMap {
}
pub fn relate_free_regions_from_predicates(&mut self,
predicates: &[ty::Predicate]) {
predicates: &[ty::Predicate<'tcx>]) {
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
for predicate in predicates {
match *predicate {
@ -69,12 +171,15 @@ impl FreeRegionMap {
}
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
match (r_a, r_b) {
// `'static: 'x` is not notable
(&ty::ReStatic, &ty::ReFree(_)) => {},
(&ty::ReFree(fr_a), &ty::ReStatic) => self.relate_to_static(fr_a),
(&ty::ReFree(fr_a), &ty::ReFree(fr_b)) => {
(&ty::ReFree(_), &ty::ReStatic) |
(&ty::ReFree(_), &ty::ReFree(_)) => {
// Record that `'a:'b`. Or, put another way, `'b <= 'a`.
self.relate_free_regions(fr_b, fr_a);
self.relate_regions(r_b, r_a);
}
_ => {
// All named regions are instantiated with free regions.
bug!("record_region_bounds: non free region: {:?} / {:?}",
@ -87,101 +192,38 @@ impl FreeRegionMap {
}
}
fn relate_to_static(&mut self, sup: FreeRegion) {
self.relation.add(ty::ReStatic, ty::ReFree(sup));
fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
assert!(match *sub { ty::ReFree(_) | ty::ReStatic => true, _ => false });
assert!(match *sup { ty::ReFree(_) | ty::ReStatic => true, _ => false });
self.relation.add(sub, sup)
}
fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) {
self.relation.add(ty::ReFree(sub), ty::ReFree(sup))
}
/// Determines whether two free regions have a subregion relationship
/// by walking the graph encoded in `map`. Note that
/// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
/// (that is, the user can give two different names to the same lifetime).
pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool {
let result = sub == sup || {
let sub = ty::ReFree(sub);
let sup = ty::ReFree(sup);
self.relation.contains(&sub, &sup) || self.relation.contains(&ty::ReStatic, &sup)
};
debug!("sub_free_region(sub={:?}, sup={:?}) = {:?}", sub, sup, result);
result
}
pub fn lub_free_regions(&self, fr_a: FreeRegion, fr_b: FreeRegion) -> Region {
let r_a = ty::ReFree(fr_a);
let r_b = ty::ReFree(fr_b);
let result = if fr_a == fr_b { r_a } else {
pub fn lub_free_regions<'a, 'gcx>(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
r_a: Region<'tcx>,
r_b: Region<'tcx>)
-> Region<'tcx> {
assert!(match *r_a { ty::ReFree(_) => true, _ => false });
assert!(match *r_b { ty::ReFree(_) => true, _ => false });
let result = if r_a == r_b { r_a } else {
match self.relation.postdom_upper_bound(&r_a, &r_b) {
None => ty::ReStatic,
None => tcx.mk_region(ty::ReStatic),
Some(r) => *r,
}
};
debug!("lub_free_regions(fr_a={:?}, fr_b={:?}) = {:?}", fr_a, fr_b, result);
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
result
}
/// Determines whether one region is a subregion of another. This is intended to run *after
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
pub fn is_subregion_of(&self,
tcx: TyCtxt,
sub_region: &ty::Region,
super_region: &ty::Region)
-> bool {
let result = sub_region == super_region || {
match (sub_region, super_region) {
(&ty::ReEmpty, _) |
(_, &ty::ReStatic) =>
true,
(&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
tcx.region_maps.is_subscope_of(sub_scope, super_scope),
(&ty::ReScope(sub_scope), &ty::ReFree(fr)) =>
tcx.region_maps.is_subscope_of(sub_scope, fr.scope) ||
self.is_static(fr),
(&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) =>
self.sub_free_region(sub_fr, super_fr),
(&ty::ReStatic, &ty::ReFree(sup_fr)) =>
self.is_static(sup_fr),
_ =>
false,
}
};
debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}",
sub_region, super_region, result);
result
}
/// Determines whether this free-region is required to be 'static
pub fn is_static(&self, super_region: ty::FreeRegion) -> bool {
debug!("is_static(super_region={:?})", super_region);
self.relation.contains(&ty::ReStatic, &ty::ReFree(super_region))
}
}
#[cfg(test)]
fn free_region(index: u32) -> FreeRegion {
use middle::region::DUMMY_CODE_EXTENT;
FreeRegion { scope: DUMMY_CODE_EXTENT,
bound_region: ty::BoundRegion::BrAnon(index) }
}
#[test]
fn lub() {
// a very VERY basic test, but see the tests in
// TransitiveRelation, which are much more thorough.
let frs: Vec<_> = (0..3).map(|i| free_region(i)).collect();
let mut map = FreeRegionMap::new();
map.relate_free_regions(frs[0], frs[2]);
map.relate_free_regions(frs[1], frs[2]);
assert_eq!(map.lub_free_regions(frs[0], frs[1]), ty::ReFree(frs[2]));
}
impl_stable_hash_for!(struct FreeRegionMap {
impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
relation
});
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
type Lifted = FreeRegionMap<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
.map(|relation| FreeRegionMap { relation })
}
}

View file

@ -1441,7 +1441,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// and must outlive the *call-site* of the function.
let fn_ret =
self.ir.tcx.liberate_late_bound_regions(
self.ir.tcx.region_maps.call_site_extent(id, body.value.id),
Some(self.ir.tcx.call_site_extent(id, body.value.id)),
&fn_ret);
if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {

View file

@ -70,6 +70,7 @@ pub use self::Note::*;
use self::Aliasability::*;
use middle::region::RegionMaps;
use hir::def_id::DefId;
use hir::map as hir_map;
use infer::InferCtxt;
@ -89,7 +90,7 @@ use std::rc::Rc;
#[derive(Clone, PartialEq)]
pub enum Categorization<'tcx> {
// temporary val, argument is its scope
Rvalue(&'tcx ty::Region, &'tcx ty::Region),
Rvalue(ty::Region<'tcx>, ty::Region<'tcx>),
StaticItem,
Upvar(Upvar), // upvar referenced by closure env
Local(ast::NodeId), // local variable
@ -114,13 +115,13 @@ pub enum PointerKind<'tcx> {
Unique,
/// `&T`
BorrowedPtr(ty::BorrowKind, &'tcx ty::Region),
BorrowedPtr(ty::BorrowKind, ty::Region<'tcx>),
/// `*T`
UnsafePtr(hir::Mutability),
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
Implicit(ty::BorrowKind, &'tcx ty::Region),
Implicit(ty::BorrowKind, ty::Region<'tcx>),
}
// We use the term "interior" to mean "something reachable from the
@ -286,9 +287,10 @@ impl ast_node for hir::Pat {
fn span(&self) -> Span { self.span }
}
#[derive(Copy, Clone)]
#[derive(Clone)]
pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
pub region_maps: &'a RegionMaps<'tcx>,
options: MemCategorizationOptions,
}
@ -402,16 +404,22 @@ impl MutabilityCategory {
}
impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>)
/// Context should be the `DefId` we use to fetch region-maps.
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a RegionMaps<'tcx>)
-> MemCategorizationContext<'a, 'gcx, 'tcx> {
MemCategorizationContext::with_options(infcx, MemCategorizationOptions::default())
MemCategorizationContext::with_options(infcx,
region_maps,
MemCategorizationOptions::default())
}
pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a RegionMaps<'tcx>,
options: MemCategorizationOptions)
-> MemCategorizationContext<'a, 'gcx, 'tcx> {
MemCategorizationContext {
infcx: infcx,
region_maps: region_maps,
options: options,
}
}
@ -786,7 +794,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
};
match fn_expr.node {
hir::ExprClosure(.., body_id, _) => body_id.node_id,
hir::ExprClosure(.., body_id, _) => body_id,
_ => bug!()
}
};
@ -796,7 +804,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// The environment of a closure is guaranteed to
// outlive any bindings introduced in the body of the
// closure itself.
scope: self.tcx().region_maps.item_extent(fn_body_id),
scope: Some(self.tcx().item_extent(fn_body_id.node_id)),
bound_region: ty::BrEnv
}));
@ -842,10 +850,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
/// Returns the lifetime of a temporary created by expr with id `id`.
/// This could be `'static` if `id` is part of a constant expression.
pub fn temporary_scope(&self, id: ast::NodeId) -> (&'tcx ty::Region, &'tcx ty::Region)
pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>)
{
let (scope, old_scope) =
self.tcx().region_maps.old_and_new_temporary_scope(id);
self.region_maps.old_and_new_temporary_scope(self.tcx(), id);
(self.tcx().mk_region(match scope {
Some(scope) => ty::ReScope(scope),
None => ty::ReStatic
@ -887,8 +895,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
pub fn cat_rvalue(&self,
cmt_id: ast::NodeId,
span: Span,
temp_scope: &'tcx ty::Region,
old_temp_scope: &'tcx ty::Region,
temp_scope: ty::Region<'tcx>,
old_temp_scope: ty::Region<'tcx>,
expr_ty: Ty<'tcx>) -> cmt<'tcx> {
let ret = Rc::new(cmt_ {
id:cmt_id,

View file

@ -16,50 +16,27 @@
//! Most of the documentation on regions can be found in
//! `middle/infer/region_inference/README.md`
use dep_graph::DepNode;
use hir::map as hir_map;
use session::Session;
use util::nodemap::{FxHashMap, NodeMap, NodeSet};
use ty;
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt;
use std::mem;
use std::rc::Rc;
use serialize;
use syntax::codemap;
use syntax::ast::{self, NodeId};
use syntax_pos::Span;
use ty::TyCtxt;
use ty::maps::Providers;
use hir;
use hir; use hir::def_id::DefId;
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
RustcDecodable, Copy)]
pub struct CodeExtent(u32);
pub type CodeExtent<'tcx> = &'tcx CodeExtentData;
impl fmt::Debug for CodeExtent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CodeExtent({:?}", self.0)?;
ty::tls::with_opt(|opt_tcx| {
if let Some(tcx) = opt_tcx {
if let Some(data) = tcx.region_maps.code_extents.borrow().get(self.0 as usize) {
write!(f, "/{:?}", data)?;
}
}
Ok(())
})?;
write!(f, ")")
}
}
/// The root of everything. I should be using NonZero or profiling
/// instead of this (probably).
pub const ROOT_CODE_EXTENT : CodeExtent = CodeExtent(0);
/// A placeholder used in trans to stand for real code extents
pub const DUMMY_CODE_EXTENT : CodeExtent = CodeExtent(1);
impl<'tcx> serialize::UseSpecializedEncodable for CodeExtent<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for CodeExtent<'tcx> {}
/// CodeExtent represents a statically-describable extent that can be
/// used to bound the lifetime/region for values.
@ -122,7 +99,7 @@ pub const DUMMY_CODE_EXTENT : CodeExtent = CodeExtent(1);
/// placate the same deriving in `ty::FreeRegion`, but we may want to
/// actually attach a more meaningful ordering to scopes than the one
/// generated via deriving here.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy)]
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub enum CodeExtentData {
Misc(ast::NodeId),
@ -149,8 +126,8 @@ pub struct CallSiteScopeData {
}
impl CallSiteScopeData {
pub fn to_code_extent(&self, region_maps: &RegionMaps) -> CodeExtent {
region_maps.lookup_code_extent(
pub fn to_code_extent<'a, 'tcx, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CodeExtent<'tcx> {
tcx.intern_code_extent(
match *self {
CallSiteScopeData { fn_id, body_id } =>
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id },
@ -199,28 +176,14 @@ impl CodeExtentData {
CodeExtentData::ParameterScope { fn_id: _, body_id } => body_id,
}
}
}
impl CodeExtent {
#[inline]
fn into_option(self) -> Option<CodeExtent> {
if self == ROOT_CODE_EXTENT {
None
} else {
Some(self)
}
}
pub fn node_id(&self, region_maps: &RegionMaps) -> ast::NodeId {
region_maps.code_extent_data(*self).node_id()
}
/// Returns the span of this CodeExtent. Note that in general the
/// returned span may not correspond to the span of any node id in
/// the AST.
pub fn span(&self, region_maps: &RegionMaps, hir_map: &hir_map::Map) -> Option<Span> {
match hir_map.find(self.node_id(region_maps)) {
pub fn span(&self, hir_map: &hir_map::Map) -> Option<Span> {
match hir_map.find(self.node_id()) {
Some(hir_map::NodeBlock(ref blk)) => {
match region_maps.code_extent_data(*self) {
match *self {
CodeExtentData::CallSiteScope { .. } |
CodeExtentData::ParameterScope { .. } |
CodeExtentData::Misc(_) |
@ -249,20 +212,21 @@ impl CodeExtent {
}
/// The region maps encode information about region relationships.
pub struct RegionMaps {
code_extents: RefCell<Vec<CodeExtentData>>,
code_extent_interner: RefCell<FxHashMap<CodeExtentData, CodeExtent>>,
pub struct RegionMaps<'tcx> {
/// `scope_map` maps from a scope id to the enclosing scope id;
/// this is usually corresponding to the lexical nesting, though
/// in the case of closures the parent scope is the innermost
/// conditional expression or repeating block. (Note that the
/// enclosing scope id for the block associated with a closure is
/// the closure itself.)
scope_map: RefCell<Vec<CodeExtent>>,
scope_map: FxHashMap<CodeExtent<'tcx>, CodeExtent<'tcx>>,
/// `var_map` maps from a variable or binding id to the block in
/// which that variable is declared.
var_map: RefCell<NodeMap<CodeExtent>>,
var_map: NodeMap<CodeExtent<'tcx>>,
/// maps from a node-id to the associated destruction scope (if any)
destruction_scopes: NodeMap<CodeExtent<'tcx>>,
/// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
/// larger than the default. The map goes from the expression id
@ -270,14 +234,14 @@ pub struct RegionMaps {
/// table, the appropriate cleanup scope is the innermost
/// enclosing statement, conditional expression, or repeating
/// block (see `terminating_scopes`).
rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
rvalue_scopes: NodeMap<CodeExtent<'tcx>>,
/// Records the value of rvalue scopes before they were shrunk by
/// #36082, for error reporting.
///
/// FIXME: this should be temporary. Remove this by 1.18.0 or
/// so.
shrunk_rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
shrunk_rvalue_scopes: NodeMap<CodeExtent<'tcx>>,
/// Encodes the hierarchy of fn bodies. Every fn body (including
/// closures) forms its own distinct region hierarchy, rooted in
@ -289,11 +253,11 @@ pub struct RegionMaps {
/// closure defined by that fn. See the "Modeling closures"
/// section of the README in infer::region_inference for
/// more details.
fn_tree: RefCell<NodeMap<ast::NodeId>>,
fn_tree: NodeMap<ast::NodeId>,
}
#[derive(Debug, Copy, Clone)]
pub struct Context {
pub struct Context<'tcx> {
/// the root of the current region tree. This is typically the id
/// of the innermost fn body. Each fn forms its own disjoint tree
/// in the region hierarchy. These fn bodies are themselves
@ -303,21 +267,21 @@ pub struct Context {
root_id: Option<ast::NodeId>,
/// the scope that contains any new variables declared
var_parent: CodeExtent,
var_parent: Option<CodeExtent<'tcx>>,
/// region parent of expressions etc
parent: CodeExtent
parent: Option<CodeExtent<'tcx>>,
}
struct RegionResolutionVisitor<'hir: 'a, 'a> {
sess: &'a Session,
struct RegionResolutionVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Generated maps:
region_maps: &'a RegionMaps,
region_maps: &'a mut RegionMaps<'tcx>,
cx: Context,
cx: Context<'tcx>,
map: &'a hir_map::Map<'hir>,
map: &'a hir_map::Map<'tcx>,
/// `terminating_scopes` is a set containing the ids of each
/// statement, or conditional/repeating expression. These scopes
@ -339,155 +303,117 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> {
/// arbitrary amounts of stack space. Terminating scopes end
/// up being contained in a DestructionScope that contains the
/// destructor's execution.
terminating_scopes: NodeSet
terminating_scopes: NodeSet,
}
impl RegionMaps {
/// create a bogus code extent for the regions in astencode types. Nobody
/// really cares about the contents of these.
pub fn bogus_code_extent(&self, e: CodeExtentData) -> CodeExtent {
self.intern_code_extent(e, DUMMY_CODE_EXTENT)
}
pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent {
match self.code_extent_interner.borrow().get(&e) {
Some(&d) => d,
None => bug!("unknown code extent {:?}", e)
impl<'tcx> RegionMaps<'tcx> {
pub fn new() -> Self {
RegionMaps {
scope_map: FxHashMap(),
destruction_scopes: FxHashMap(),
var_map: NodeMap(),
rvalue_scopes: NodeMap(),
shrunk_rvalue_scopes: NodeMap(),
fn_tree: NodeMap(),
}
}
pub fn node_extent(&self, n: ast::NodeId) -> CodeExtent {
self.lookup_code_extent(CodeExtentData::Misc(n))
}
// Returns the code extent for an item - the destruction scope.
pub fn item_extent(&self, n: ast::NodeId) -> CodeExtent {
self.lookup_code_extent(CodeExtentData::DestructionScope(n))
}
pub fn call_site_extent(&self, fn_id: ast::NodeId, body_id: ast::NodeId) -> CodeExtent {
assert!(fn_id != body_id);
self.lookup_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id })
}
pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option<CodeExtent> {
self.code_extent_interner.borrow().get(&CodeExtentData::DestructionScope(n)).cloned()
}
pub fn intern_code_extent(&self,
e: CodeExtentData,
parent: CodeExtent) -> CodeExtent {
match self.code_extent_interner.borrow_mut().entry(e) {
Entry::Occupied(o) => {
// this can happen when the bogus code extents from tydecode
// have (bogus) NodeId-s that overlap items created during
// inlining.
// We probably shouldn't be creating bogus code extents
// though.
let idx = *o.get();
if parent == DUMMY_CODE_EXTENT {
info!("CodeExtent({}) = {:?} [parent={}] BOGUS!",
idx.0, e, parent.0);
} else {
assert_eq!(self.scope_map.borrow()[idx.0 as usize],
DUMMY_CODE_EXTENT);
info!("CodeExtent({}) = {:?} [parent={}] RECLAIMED!",
idx.0, e, parent.0);
self.scope_map.borrow_mut()[idx.0 as usize] = parent;
}
idx
}
Entry::Vacant(v) => {
if self.code_extents.borrow().len() > 0xffffffffusize {
bug!() // should pass a sess,
// but this isn't the only place
}
let idx = CodeExtent(self.code_extents.borrow().len() as u32);
debug!("CodeExtent({}) = {:?} [parent={}]", idx.0, e, parent.0);
self.code_extents.borrow_mut().push(e);
self.scope_map.borrow_mut().push(parent);
*v.insert(idx)
}
pub fn record_code_extent(&mut self,
child: CodeExtent<'tcx>,
parent: Option<CodeExtent<'tcx>>) {
debug!("{:?}.parent = {:?}", child, parent);
if let Some(p) = parent {
let prev = self.scope_map.insert(child, p);
assert!(prev.is_none());
}
// record the destruction scopes for later so we can query them
if let &CodeExtentData::DestructionScope(n) = child {
self.destruction_scopes.insert(n, child);
}
}
pub fn intern_node(&self,
n: ast::NodeId,
parent: CodeExtent) -> CodeExtent {
self.intern_code_extent(CodeExtentData::Misc(n), parent)
}
pub fn code_extent_data(&self, e: CodeExtent) -> CodeExtentData {
self.code_extents.borrow()[e.0 as usize]
}
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) {
for child_id in 1..self.code_extents.borrow().len() {
let child = CodeExtent(child_id as u32);
if let Some(parent) = self.opt_encl_scope(child) {
e(&child, &parent)
}
}
}
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
for (child, parent) in self.var_map.borrow().iter() {
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(CodeExtent<'tcx>, CodeExtent<'tcx>) {
for (&child, &parent) in &self.scope_map {
e(child, parent)
}
}
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, CodeExtent<'tcx>) {
for (child, parent) in self.var_map.iter() {
e(child, parent)
}
}
pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option<CodeExtent<'tcx>> {
self.destruction_scopes.get(&n).cloned()
}
/// Records that `sub_fn` is defined within `sup_fn`. These ids
/// should be the id of the block that is the fn body, which is
/// also the root of the region hierarchy for that fn.
fn record_fn_parent(&self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) {
fn record_fn_parent(&mut self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) {
debug!("record_fn_parent(sub_fn={:?}, sup_fn={:?})", sub_fn, sup_fn);
assert!(sub_fn != sup_fn);
let previous = self.fn_tree.borrow_mut().insert(sub_fn, sup_fn);
let previous = self.fn_tree.insert(sub_fn, sup_fn);
assert!(previous.is_none());
}
fn fn_is_enclosed_by(&self, mut sub_fn: ast::NodeId, sup_fn: ast::NodeId) -> bool {
let fn_tree = self.fn_tree.borrow();
loop {
if sub_fn == sup_fn { return true; }
match fn_tree.get(&sub_fn) {
match self.fn_tree.get(&sub_fn) {
Some(&s) => { sub_fn = s; }
None => { return false; }
}
}
}
fn record_var_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
fn record_var_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
self.var_map.borrow_mut().insert(var, lifetime);
assert!(var != lifetime.node_id());
self.var_map.insert(var, lifetime);
}
fn record_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
fn record_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
self.rvalue_scopes.borrow_mut().insert(var, lifetime);
assert!(var != lifetime.node_id());
self.rvalue_scopes.insert(var, lifetime);
}
fn record_shrunk_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
self.shrunk_rvalue_scopes.borrow_mut().insert(var, lifetime);
assert!(var != lifetime.node_id());
self.shrunk_rvalue_scopes.insert(var, lifetime);
}
pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
pub fn opt_encl_scope(&self, id: CodeExtent<'tcx>) -> Option<CodeExtent<'tcx>> {
//! Returns the narrowest scope that encloses `id`, if any.
self.scope_map.borrow()[id.0 as usize].into_option()
self.scope_map.get(&id).cloned()
}
#[allow(dead_code)] // used in cfg
pub fn encl_scope(&self, id: CodeExtent) -> CodeExtent {
pub fn encl_scope(&self, id: CodeExtent<'tcx>) -> CodeExtent<'tcx> {
//! Returns the narrowest scope that encloses `id`, if any.
self.opt_encl_scope(id).unwrap()
}
/// Returns the lifetime of the local variable `var_id`
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent {
match self.var_map.borrow().get(&var_id) {
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent<'tcx> {
match self.var_map.get(&var_id) {
Some(&r) => r,
None => { bug!("no enclosing scope for id {:?}", var_id); }
}
}
pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option<CodeExtent>, bool) {
let temporary_scope = self.temporary_scope(expr_id);
let was_shrunk = match self.shrunk_rvalue_scopes.borrow().get(&expr_id) {
pub fn temporary_scope2<'a, 'gcx: 'tcx>(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
expr_id: ast::NodeId)
-> (Option<CodeExtent<'tcx>>, bool) {
let temporary_scope = self.temporary_scope(tcx, expr_id);
let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) {
Some(&s) => {
info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})",
expr_id, temporary_scope, s);
@ -499,36 +425,39 @@ impl RegionMaps {
(temporary_scope, was_shrunk)
}
pub fn old_and_new_temporary_scope(&self, expr_id: ast::NodeId) ->
(Option<CodeExtent>, Option<CodeExtent>)
pub fn old_and_new_temporary_scope<'a, 'gcx: 'tcx>(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
expr_id: ast::NodeId)
-> (Option<CodeExtent<'tcx>>,
Option<CodeExtent<'tcx>>)
{
let temporary_scope = self.temporary_scope(expr_id);
let temporary_scope = self.temporary_scope(tcx, expr_id);
(temporary_scope,
self.shrunk_rvalue_scopes
.borrow().get(&expr_id).cloned()
.get(&expr_id).cloned()
.or(temporary_scope))
}
pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option<CodeExtent> {
pub fn temporary_scope<'a, 'gcx: 'tcx>(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
expr_id: ast::NodeId)
-> Option<CodeExtent<'tcx>> {
//! Returns the scope when temp created by expr_id will be cleaned up
// check for a designated rvalue scope
if let Some(&s) = self.rvalue_scopes.borrow().get(&expr_id) {
if let Some(&s) = self.rvalue_scopes.get(&expr_id) {
debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
return Some(s);
}
let scope_map : &[CodeExtent] = &self.scope_map.borrow();
let code_extents: &[CodeExtentData] = &self.code_extents.borrow();
// else, locate the innermost terminating scope
// if there's one. Static items, for instance, won't
// have an enclosing scope, hence no scope will be
// returned.
let mut id = self.node_extent(expr_id);
let mut id = tcx.node_extent(expr_id);
while let Some(p) = scope_map[id.0 as usize].into_option() {
match code_extents[p.0 as usize] {
while let Some(&p) = self.scope_map.get(id) {
match *p {
CodeExtentData::DestructionScope(..) => {
debug!("temporary_scope({:?}) = {:?} [enclosing]",
expr_id, id);
@ -542,7 +471,7 @@ impl RegionMaps {
return None;
}
pub fn var_region(&self, id: ast::NodeId) -> ty::Region {
pub fn var_region(&self, id: ast::NodeId) -> ty::RegionKind<'tcx> {
//! Returns the lifetime of the variable `id`.
let scope = ty::ReScope(self.var_scope(id));
@ -584,20 +513,22 @@ impl RegionMaps {
/// Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest
/// scope which is greater than or equal to both `scope_a` and `scope_b`.
pub fn nearest_common_ancestor(&self,
scope_a: CodeExtent,
scope_b: CodeExtent)
-> CodeExtent {
scope_a: CodeExtent<'tcx>,
scope_b: CodeExtent<'tcx>)
-> CodeExtent<'tcx> {
if scope_a == scope_b { return scope_a; }
let mut a_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32];
let mut a_vec: Vec<CodeExtent> = vec![];
let mut b_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32];
let mut b_vec: Vec<CodeExtent> = vec![];
let scope_map : &[CodeExtent] = &self.scope_map.borrow();
let a_ancestors = ancestors_of(scope_map,
scope_a, &mut a_buf, &mut a_vec);
let b_ancestors = ancestors_of(scope_map,
scope_b, &mut b_buf, &mut b_vec);
/// [1] The initial values for `a_buf` and `b_buf` are not used.
/// The `ancestors_of` function will return some prefix that
/// is re-initialized with new values (or else fallback to a
/// heap-allocated vector).
let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32];
let mut a_vec: Vec<CodeExtent<'tcx>> = vec![];
let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32];
let mut b_vec: Vec<CodeExtent<'tcx>> = vec![];
let scope_map = &self.scope_map;
let a_ancestors = ancestors_of(scope_map, scope_a, &mut a_buf, &mut a_vec);
let b_ancestors = ancestors_of(scope_map, scope_b, &mut b_buf, &mut b_vec);
let mut a_index = a_ancestors.len() - 1;
let mut b_index = b_ancestors.len() - 1;
@ -615,11 +546,11 @@ impl RegionMaps {
// nesting. The reasoning behind this is subtle. See the
// "Modeling closures" section of the README in
// infer::region_inference for more details.
let a_root_scope = self.code_extent_data(a_ancestors[a_index]);
let b_root_scope = self.code_extent_data(a_ancestors[a_index]);
let a_root_scope = a_ancestors[a_index];
let b_root_scope = a_ancestors[a_index];
return match (a_root_scope, b_root_scope) {
(CodeExtentData::DestructionScope(a_root_id),
CodeExtentData::DestructionScope(b_root_id)) => {
(&CodeExtentData::DestructionScope(a_root_id),
&CodeExtentData::DestructionScope(b_root_id)) => {
if self.fn_is_enclosed_by(a_root_id, b_root_id) {
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
scope_b
@ -650,17 +581,18 @@ impl RegionMaps {
}
}
fn ancestors_of<'a>(scope_map: &[CodeExtent],
scope: CodeExtent,
buf: &'a mut [CodeExtent; 32],
vec: &'a mut Vec<CodeExtent>) -> &'a [CodeExtent] {
fn ancestors_of<'a, 'tcx>(scope_map: &FxHashMap<CodeExtent<'tcx>, CodeExtent<'tcx>>,
scope: CodeExtent<'tcx>,
buf: &'a mut [CodeExtent<'tcx>; 32],
vec: &'a mut Vec<CodeExtent<'tcx>>)
-> &'a [CodeExtent<'tcx>] {
// debug!("ancestors_of(scope={:?})", scope);
let mut scope = scope;
let mut i = 0;
while i < 32 {
buf[i] = scope;
match scope_map[scope.0 as usize].into_option() {
match scope_map.get(&scope) {
Some(superscope) => scope = superscope,
_ => return &buf[..i+1]
}
@ -671,7 +603,7 @@ impl RegionMaps {
vec.extend_from_slice(buf);
loop {
vec.push(scope);
match scope_map[scope.0 as usize].into_option() {
match scope_map.get(&scope) {
Some(superscope) => scope = superscope,
_ => return &*vec
}
@ -685,17 +617,17 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
var_id: ast::NodeId,
_sp: Span) {
match visitor.cx.var_parent {
ROOT_CODE_EXTENT => {
None => {
// this can happen in extern fn declarations like
//
// extern fn isalnum(c: c_int) -> c_int
}
parent_scope =>
Some(parent_scope) =>
visitor.region_maps.record_var_scope(var_id, parent_scope),
}
}
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: &'tcx hir::Block) {
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk: &'tcx hir::Block) {
debug!("resolve_block(blk.id={:?})", blk.id);
let prev_cx = visitor.cx;
@ -728,8 +660,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk:
visitor.cx = Context {
root_id: prev_cx.root_id,
var_parent: block_extent,
parent: block_extent,
var_parent: Some(block_extent),
parent: Some(block_extent),
};
{
@ -754,8 +686,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk:
);
visitor.cx = Context {
root_id: prev_cx.root_id,
var_parent: stmt_extent,
parent: stmt_extent,
var_parent: Some(stmt_extent),
parent: Some(stmt_extent),
};
}
visitor.visit_stmt(statement)
@ -766,7 +698,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk:
visitor.cx = prev_cx;
}
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) {
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
visitor.terminating_scopes.insert(arm.body.id);
if let Some(ref expr) = arm.guard {
@ -776,7 +708,7 @@ fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &
intravisit::walk_arm(visitor, arm);
}
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) {
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: &'tcx hir::Pat) {
visitor.new_node_extent(pat.id);
// If this is a binding then record the lifetime of that binding.
@ -787,7 +719,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &
intravisit::walk_pat(visitor, pat);
}
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) {
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) {
let stmt_id = stmt.node.id();
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
@ -800,17 +732,17 @@ fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt:
let stmt_extent = visitor.new_node_extent_with_dtor(stmt_id);
let prev_parent = visitor.cx.parent;
visitor.cx.parent = stmt_extent;
visitor.cx.parent = Some(stmt_extent);
intravisit::walk_stmt(visitor, stmt);
visitor.cx.parent = prev_parent;
}
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) {
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr: &'tcx hir::Expr) {
debug!("resolve_expr(expr.id={:?})", expr.id);
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
let prev_cx = visitor.cx;
visitor.cx.parent = expr_extent;
visitor.cx.parent = Some(expr_extent);
{
let terminating_scopes = &mut visitor.terminating_scopes;
@ -850,7 +782,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr:
}
hir::ExprMatch(..) => {
visitor.cx.var_parent = expr_extent;
visitor.cx.var_parent = Some(expr_extent);
}
hir::ExprAssignOp(..) | hir::ExprIndex(..) |
@ -883,7 +815,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr:
visitor.cx = prev_cx;
}
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
local: &'tcx hir::Local) {
debug!("resolve_local(local.id={:?},local.init={:?})",
local.id,local.init.is_some());
@ -892,7 +824,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
// scope that will be used for any bindings declared in this
// pattern.
let blk_scope = visitor.cx.var_parent;
assert!(blk_scope != ROOT_CODE_EXTENT); // locals must be within a block
let blk_scope = blk_scope.expect("locals must be within a block");
visitor.region_maps.record_var_scope(local.id, blk_scope);
// As an exception to the normal rules governing temporary
@ -1024,9 +956,11 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
/// | box E&
/// | E& as ...
/// | ( E& )
fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor,
expr: &hir::Expr,
blk_id: CodeExtent) {
fn record_rvalue_scope_if_borrow_expr<'a, 'tcx>(
visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
expr: &hir::Expr,
blk_id: CodeExtent<'tcx>)
{
match expr.node {
hir::ExprAddrOf(_, ref subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
@ -1073,10 +1007,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
/// | <rvalue>
///
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor,
expr: &'a hir::Expr,
blk_scope: CodeExtent,
is_shrunk: bool) {
fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
expr: &hir::Expr,
blk_scope: CodeExtent<'tcx>,
is_shrunk: bool) {
let mut expr = expr;
loop {
// Note: give all the expressions matching `ET` with the
@ -1107,43 +1041,40 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
}
}
fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
id: ast::NodeId,
walk: F)
where F: FnOnce(&mut RegionResolutionVisitor<'tcx, 'a>)
fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, walk: F)
where F: FnOnce(&mut RegionResolutionVisitor<'a, 'tcx>)
{
// Items create a new outer block scope as far as we're concerned.
let prev_cx = visitor.cx;
let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
visitor.cx = Context {
root_id: None,
var_parent: ROOT_CODE_EXTENT,
parent: ROOT_CODE_EXTENT
var_parent: None,
parent: None,
};
walk(visitor);
visitor.create_item_scope_if_needed(id);
visitor.cx = prev_cx;
visitor.terminating_scopes = prev_ts;
}
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
kind: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::BodyId,
sp: Span,
id: ast::NodeId) {
visitor.cx.parent = Some(visitor.new_code_extent(
CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }));
debug!("region::resolve_fn(id={:?}, \
span={:?}, \
body.id={:?}, \
cx.parent={:?})",
span={:?}, \
body.id={:?}, \
cx.parent={:?})",
id,
visitor.sess.codemap().span_to_string(sp),
visitor.tcx.sess.codemap().span_to_string(sp),
body_id,
visitor.cx.parent);
visitor.cx.parent = visitor.new_code_extent(
CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
let fn_decl_scope = visitor.new_code_extent(
CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id });
@ -1158,8 +1089,8 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
// The arguments and `self` are parented to the fn.
visitor.cx = Context {
root_id: Some(body_id.node_id),
parent: ROOT_CODE_EXTENT,
var_parent: fn_decl_scope,
parent: None,
var_parent: Some(fn_decl_scope),
};
intravisit::walk_fn_decl(visitor, decl);
@ -1168,8 +1099,8 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
// The body of the every fn is a root scope.
visitor.cx = Context {
root_id: Some(body_id.node_id),
parent: fn_decl_scope,
var_parent: fn_decl_scope
parent: Some(fn_decl_scope),
var_parent: Some(fn_decl_scope),
};
visitor.visit_nested_body(body_id);
@ -1178,17 +1109,33 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
visitor.terminating_scopes = outer_ts;
}
impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> {
/// Records the current parent (if any) as the parent of `child_scope`.
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent {
self.region_maps.intern_code_extent(child_scope, self.cx.parent)
impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> {
pub fn intern_code_extent(&mut self,
data: CodeExtentData,
parent: Option<CodeExtent<'tcx>>)
-> CodeExtent<'tcx> {
let code_extent = self.tcx.intern_code_extent(data);
self.region_maps.record_code_extent(code_extent, parent);
code_extent
}
fn new_node_extent(&mut self, child_scope: ast::NodeId) -> CodeExtent {
pub fn intern_node(&mut self,
n: ast::NodeId,
parent: Option<CodeExtent<'tcx>>) -> CodeExtent<'tcx> {
self.intern_code_extent(CodeExtentData::Misc(n), parent)
}
/// Records the current parent (if any) as the parent of `child_scope`.
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent<'tcx> {
let parent = self.cx.parent;
self.intern_code_extent(child_scope, parent)
}
fn new_node_extent(&mut self, child_scope: ast::NodeId) -> CodeExtent<'tcx> {
self.new_code_extent(CodeExtentData::Misc(child_scope))
}
fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent {
fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent<'tcx> {
// If node was previously marked as a terminating scope during the
// recursive visit of its parent node in the AST, then we need to
// account for the destruction scope representing the extent of
@ -1196,98 +1143,90 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> {
if self.terminating_scopes.contains(&id) {
let ds = self.new_code_extent(
CodeExtentData::DestructionScope(id));
self.region_maps.intern_node(id, ds)
self.intern_node(id, Some(ds))
} else {
self.new_node_extent(id)
}
}
fn create_item_scope_if_needed(&mut self, id: ast::NodeId) {
// create a region for the destruction scope - this is needed
// for constructing parameter environments based on the item.
// functions put their destruction scopes *inside* their parameter
// scopes.
let scope = CodeExtentData::DestructionScope(id);
if !self.region_maps.code_extent_interner.borrow().contains_key(&scope) {
self.region_maps.intern_code_extent(scope, ROOT_CODE_EXTENT);
}
}
}
impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.map)
}
fn visit_block(&mut self, b: &'hir Block) {
fn visit_block(&mut self, b: &'tcx Block) {
resolve_block(self, b);
}
fn visit_item(&mut self, i: &'hir Item) {
resolve_item_like(self, i.id, |this| intravisit::walk_item(this, i));
fn visit_item(&mut self, i: &'tcx Item) {
resolve_item_like(self, |this| intravisit::walk_item(this, i));
}
fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) {
resolve_item_like(self, ii.id, |this| intravisit::walk_impl_item(this, ii));
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
resolve_item_like(self, |this| intravisit::walk_impl_item(this, ii));
}
fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) {
resolve_item_like(self, ti.id, |this| intravisit::walk_trait_item(this, ti));
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
resolve_item_like(self, |this| intravisit::walk_trait_item(this, ti));
}
fn visit_fn(&mut self, fk: FnKind<'hir>, fd: &'hir FnDecl,
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx FnDecl,
b: hir::BodyId, s: Span, n: NodeId) {
resolve_fn(self, fk, fd, b, s, n);
}
fn visit_arm(&mut self, a: &'hir Arm) {
fn visit_arm(&mut self, a: &'tcx Arm) {
resolve_arm(self, a);
}
fn visit_pat(&mut self, p: &'hir Pat) {
fn visit_pat(&mut self, p: &'tcx Pat) {
resolve_pat(self, p);
}
fn visit_stmt(&mut self, s: &'hir Stmt) {
fn visit_stmt(&mut self, s: &'tcx Stmt) {
resolve_stmt(self, s);
}
fn visit_expr(&mut self, ex: &'hir Expr) {
fn visit_expr(&mut self, ex: &'tcx Expr) {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &'hir Local) {
fn visit_local(&mut self, l: &'tcx Local) {
resolve_local(self, l);
}
}
pub fn resolve_crate(sess: &Session, map: &hir_map::Map) -> RegionMaps {
let _task = map.dep_graph.in_task(DepNode::RegionResolveCrate);
let krate = map.krate();
fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_id: DefId)
-> Rc<RegionMaps<'tcx>>
{
let closure_base_def_id = tcx.closure_base_def_id(fn_id);
if closure_base_def_id != fn_id {
return tcx.region_maps(closure_base_def_id);
}
let mut maps = RegionMaps::new();
let fn_node_id = tcx.hir.as_local_node_id(fn_id)
.expect("fn DefId should be for LOCAL_CRATE");
let node = tcx.hir.get(fn_node_id);
let maps = RegionMaps {
code_extents: RefCell::new(vec![]),
code_extent_interner: RefCell::new(FxHashMap()),
scope_map: RefCell::new(vec![]),
var_map: RefCell::new(NodeMap()),
rvalue_scopes: RefCell::new(NodeMap()),
shrunk_rvalue_scopes: RefCell::new(NodeMap()),
fn_tree: RefCell::new(NodeMap()),
};
let root_extent = maps.bogus_code_extent(
CodeExtentData::DestructionScope(ast::DUMMY_NODE_ID));
assert_eq!(root_extent, ROOT_CODE_EXTENT);
let bogus_extent = maps.bogus_code_extent(
CodeExtentData::Misc(ast::DUMMY_NODE_ID));
assert_eq!(bogus_extent, DUMMY_CODE_EXTENT);
{
let mut visitor = RegionResolutionVisitor {
sess: sess,
region_maps: &maps,
map: map,
tcx: tcx,
region_maps: &mut maps,
map: &tcx.hir,
cx: Context {
root_id: None,
parent: ROOT_CODE_EXTENT,
var_parent: ROOT_CODE_EXTENT
parent: None,
var_parent: None,
},
terminating_scopes: NodeSet()
terminating_scopes: NodeSet(),
};
krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
visitor.visit_hir_map_node(node);
}
return maps;
Rc::new(maps)
}
pub fn provide(providers: &mut Providers) {
*providers = Providers {
region_maps,
..*providers
};
}

View file

@ -1034,7 +1034,7 @@ pub enum Rvalue<'tcx> {
Repeat(Operand<'tcx>, ConstUsize),
/// &x or &mut x
Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>),
Ref(Region<'tcx>, BorrowKind, Lvalue<'tcx>),
/// length of a [X] or [X;n] value
Len(Lvalue<'tcx>),

View file

@ -747,7 +747,7 @@ pub enum LvalueContext<'tcx> {
Inspect,
// Being borrowed
Borrow { region: &'tcx Region, kind: BorrowKind },
Borrow { region: Region<'tcx>, kind: BorrowKind },
// Used as base for another lvalue, e.g. `x` in `x.y`.
//

View file

@ -1804,7 +1804,7 @@ mod dep_tracking {
use rustc_back::PanicStrategy;
pub trait DepTrackingHash {
fn hash(&self, &mut DefaultHasher, ErrorOutputType);
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
}
macro_rules! impl_dep_tracking_hash_via_hash {

View file

@ -84,7 +84,7 @@ pub struct FulfillmentContext<'tcx> {
#[derive(Clone)]
pub struct RegionObligation<'tcx> {
pub sub_region: &'tcx ty::Region,
pub sub_region: ty::Region<'tcx>,
pub sup_type: Ty<'tcx>,
pub cause: ObligationCause<'tcx>,
}
@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
pub fn register_region_obligation(&mut self,
t_a: Ty<'tcx>,
r_b: &'tcx ty::Region,
r_b: ty::Region<'tcx>,
cause: ObligationCause<'tcx>)
{
register_region_obligation(t_a, r_b, cause, &mut self.region_obligations);
@ -566,7 +566,7 @@ fn coinductive_obligation<'a,'gcx,'tcx>(selcx: &SelectionContext<'a,'gcx,'tcx>,
}
fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
r_b: &'tcx ty::Region,
r_b: ty::Region<'tcx>,
cause: ObligationCause<'tcx>,
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
{

View file

@ -17,6 +17,7 @@ pub use self::ObligationCauseCode::*;
use hir;
use hir::def_id::DefId;
use middle::region::RegionMaps;
use middle::free_region::FreeRegionMap;
use ty::subst::Substs;
use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate};
@ -112,7 +113,7 @@ pub enum ObligationCauseCode<'tcx> {
ReferenceOutlivesReferent(Ty<'tcx>),
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
ObjectTypeBound(Ty<'tcx>, &'tcx ty::Region),
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
/// Obligation incurred due to an object cast.
ObjectCastObligation(/* Object type */ Ty<'tcx>),
@ -435,9 +436,10 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx
// FIXME: this is gonna need to be removed ...
/// Normalizes the parameter environment, reporting errors if they occur.
pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
unnormalized_env: ty::ParameterEnvironment<'tcx>,
cause: ObligationCause<'tcx>)
-> ty::ParameterEnvironment<'tcx>
region_context: DefId,
unnormalized_env: ty::ParameterEnvironment<'tcx>,
cause: ObligationCause<'tcx>)
-> ty::ParameterEnvironment<'tcx>
{
// I'm not wild about reporting errors here; I'd prefer to
// have the errors get reported at a defined place (e.g.,
@ -455,7 +457,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// can be sure that no errors should occur.
let span = cause.span;
let body_id = cause.body_id;
debug!("normalize_param_env_or_error(unnormalized_env={:?})",
unnormalized_env);
@ -492,8 +493,9 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("normalize_param_env_or_error: normalized predicates={:?}",
predicates);
let region_maps = RegionMaps::new();
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(&free_regions, body_id);
infcx.resolve_regions_and_report_errors(region_context, &region_maps, &free_regions);
let predicates = match infcx.fully_resolve(&predicates) {
Ok(predicates) => predicates,
Err(fixup_err) => {

View file

@ -206,8 +206,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
};
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let free_substs = self.construct_free_substs(def_id,
self.region_maps.node_extent(ast::DUMMY_NODE_ID));
let free_substs = self.construct_free_substs(def_id, None);
let predicates = self.predicates_of(def_id);
let predicates = predicates.instantiate(self, free_substs).predicates;
elaborate_predicates(self, predicates)

View file

@ -23,7 +23,6 @@ use super::util::impl_trait_ref_and_oblig;
use rustc_data_structures::fx::FxHashMap;
use hir::def_id::DefId;
use infer::{InferCtxt, InferOk};
use middle::region;
use ty::subst::{Subst, Substs};
use traits::{self, Reveal, ObligationCause};
use ty::{self, TyCtxt, TypeFoldable};
@ -182,7 +181,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// create a parameter environment corresponding to a (skolemized) instantiation of impl1
let penv = tcx.construct_parameter_environment(DUMMY_SP,
impl1_def_id,
region::DUMMY_CODE_EXTENT);
None);
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id)
.unwrap()
.subst(tcx, &penv.free_substs);

View file

@ -52,8 +52,8 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
self.relate(a, b)
}
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region> {
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("{}.regions({:?}, {:?})",
self.tag(),
a,

View file

@ -133,7 +133,7 @@ impl<'tcx> Adjustment<'tcx> {
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub enum AutoBorrow<'tcx> {
/// Convert from T to &T.
Ref(&'tcx ty::Region, hir::Mutability),
Ref(ty::Region<'tcx>, hir::Mutability),
/// Convert from T to *T.
RawPtr(hir::Mutability),

View file

@ -21,7 +21,7 @@ use hir::map as hir_map;
use hir::map::DisambiguatedDefPathData;
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::region::RegionMaps;
use middle::region::{CodeExtent, CodeExtentData};
use middle::resolve_lifetime;
use middle::stability;
use mir::Mir;
@ -33,6 +33,7 @@ use ty::{TyS, TypeVariants, Slice};
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
use hir::FreevarMap;
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
use ty::RegionKind;
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
use ty::TypeVariants::*;
use ty::layout::{Layout, TargetDataLayout};
@ -93,7 +94,7 @@ pub struct CtxtInterners<'tcx> {
type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
region: RefCell<FxHashSet<Interned<'tcx, Region>>>,
region: RefCell<FxHashSet<Interned<'tcx, RegionKind<'tcx>>>>,
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
}
@ -191,9 +192,9 @@ pub struct CommonTypes<'tcx> {
pub never: Ty<'tcx>,
pub err: Ty<'tcx>,
pub re_empty: &'tcx Region,
pub re_static: &'tcx Region,
pub re_erased: &'tcx Region,
pub re_empty: Region<'tcx>,
pub re_static: Region<'tcx>,
pub re_erased: Region<'tcx>,
}
#[derive(RustcEncodable, RustcDecodable)]
@ -256,7 +257,7 @@ pub struct TypeckTables<'tcx> {
/// Stores the free-region relationships that were deduced from
/// its where clauses and parameter types. These are then
/// read-again by borrowck.
pub free_region_map: FreeRegionMap,
pub free_region_map: FreeRegionMap<'tcx>,
}
impl<'tcx> TypeckTables<'tcx> {
@ -392,9 +393,9 @@ impl<'tcx> CommonTypes<'tcx> {
f32: mk(TyFloat(ast::FloatTy::F32)),
f64: mk(TyFloat(ast::FloatTy::F64)),
re_empty: mk_region(Region::ReEmpty),
re_static: mk_region(Region::ReStatic),
re_erased: mk_region(Region::ReErased),
re_empty: mk_region(RegionKind::ReEmpty),
re_static: mk_region(RegionKind::ReStatic),
re_erased: mk_region(RegionKind::ReErased),
}
}
}
@ -439,8 +440,6 @@ pub struct GlobalCtxt<'tcx> {
pub named_region_map: resolve_lifetime::NamedRegionMap,
pub region_maps: RegionMaps,
pub hir: hir_map::Map<'tcx>,
pub maps: maps::Maps<'tcx>,
@ -550,6 +549,8 @@ pub struct GlobalCtxt<'tcx> {
layout_interner: RefCell<FxHashSet<&'tcx Layout>>,
code_extent_interner: RefCell<FxHashSet<CodeExtent<'tcx>>>,
/// A vector of every trait accessible in the whole crate
/// (i.e. including those from subcrates). This is used only for
/// error reporting, and so is lazily initialised and generally
@ -650,6 +651,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
interned
}
pub fn node_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
self.intern_code_extent(CodeExtentData::Misc(n))
}
// Returns the code extent for an item - the destruction scope.
pub fn item_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
self.intern_code_extent(CodeExtentData::DestructionScope(n))
}
pub fn call_site_extent(self, fn_id: ast::NodeId, body_id: ast::NodeId) -> CodeExtent<'gcx> {
assert!(fn_id != body_id);
self.intern_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id })
}
pub fn intern_code_extent(self, data: CodeExtentData) -> CodeExtent<'gcx> {
if let Some(st) = self.code_extent_interner.borrow().get(&data) {
return st;
}
let interned = self.global_interners.arena.alloc(data);
if let Some(prev) = self.code_extent_interner.borrow_mut().replace(interned) {
bug!("Tried to overwrite interned code-extent: {:?}", prev)
}
interned
}
pub fn intern_layout(self, layout: Layout) -> &'gcx Layout {
if let Some(layout) = self.layout_interner.borrow().get(&layout) {
return layout;
@ -690,7 +717,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
resolutions: ty::Resolutions,
named_region_map: resolve_lifetime::NamedRegionMap,
hir: hir_map::Map<'tcx>,
region_maps: RegionMaps,
lang_items: middle::lang_items::LanguageItems,
stability: stability::Index<'tcx>,
crate_name: &str,
@ -714,7 +740,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
dep_graph: dep_graph.clone(),
types: common_types,
named_region_map: named_region_map,
region_maps: region_maps,
variance_computed: Cell::new(false),
trait_map: resolutions.trait_map,
export_map: resolutions.export_map,
@ -740,6 +765,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
data_layout: data_layout,
layout_cache: RefCell::new(FxHashMap()),
layout_interner: RefCell::new(FxHashSet()),
code_extent_interner: RefCell::new(FxHashSet()),
layout_depth: Cell::new(0),
derive_macros: RefCell::new(NodeMap()),
stability_interner: RefCell::new(FxHashSet()),
@ -819,9 +845,18 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
}
}
impl<'a, 'tcx> Lift<'tcx> for &'a Region {
type Lifted = &'tcx Region;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Region> {
impl<'a, 'tcx> Lift<'tcx> for ty::FreeRegion<'a> {
type Lifted = ty::FreeRegion<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
let scope = self.scope.map(|code_extent| tcx.intern_code_extent(*code_extent));
let bound_region = self.bound_region;
Some(ty::FreeRegion { scope, bound_region })
}
}
impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
type Lifted = Region<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
if tcx.interners.arena.in_arena(*self as *const _) {
return Some(unsafe { mem::transmute(*self) });
}
@ -1082,9 +1117,9 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, Substs<'tcx>> {
}
}
impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
fn borrow<'a>(&'a self) -> &'a Region {
self.0
impl<'tcx> Borrow<RegionKind<'tcx>> for Interned<'tcx, RegionKind<'tcx>> {
fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> {
&self.0
}
}
@ -1175,7 +1210,7 @@ direct_interners!('tcx,
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
_ => false
}
}) -> Region
}) -> RegionKind<'tcx>
);
macro_rules! slice_interners {
@ -1267,15 +1302,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.mk_ty(TyRawPtr(tm))
}
pub fn mk_ref(self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyRef(r, tm))
}
pub fn mk_mut_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
}
pub fn mk_imm_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
}
@ -1337,7 +1372,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn mk_dynamic(
self,
obj: ty::Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>,
reg: &'tcx ty::Region
reg: ty::Region<'tcx>
) -> Ty<'tcx> {
self.mk_ty(TyDynamic(obj, reg))
}
@ -1467,7 +1502,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub trait InternAs<T: ?Sized, R> {
type Output;
fn intern_with<F>(self, F) -> Self::Output
fn intern_with<F>(self, f: F) -> Self::Output
where F: FnOnce(&T) -> R;
}

View file

@ -36,11 +36,11 @@ pub enum TypeError<'tcx> {
TupleSize(ExpectedFound<usize>),
FixedArraySize(ExpectedFound<usize>),
ArgCount,
RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
RegionsNotSame(&'tcx Region, &'tcx Region),
RegionsNoOverlap(&'tcx Region, &'tcx Region),
RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
RegionsNotSame(Region<'tcx>, Region<'tcx>),
RegionsNoOverlap(Region<'tcx>, Region<'tcx>),
RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
Sorts(ExpectedFound<Ty<'tcx>>),
IntMismatch(ExpectedFound<ty::IntVarValue>),
FloatMismatch(ExpectedFound<ast::FloatTy>),

View file

@ -186,7 +186,7 @@ impl FlagComputation {
self.add_bound_computation(&computation);
}
fn add_region(&mut self, r: &ty::Region) {
fn add_region(&mut self, r: ty::Region) {
self.add_flags(r.type_flags());
if let ty::ReLateBound(debruijn, _) = *r {
self.add_depth(debruijn.depth);

View file

@ -159,7 +159,7 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized {
sig.super_fold_with(self)
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
r.super_fold_with(self)
}
@ -182,7 +182,7 @@ pub trait TypeVisitor<'tcx> : Sized {
trait_ref.super_visit_with(self)
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
r.super_visit_with(self)
}
}
@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// whether any late-bound regions were skipped
pub fn collect_regions<T>(self,
value: &T,
region_set: &mut FxHashSet<&'tcx ty::Region>)
region_set: &mut FxHashSet<ty::Region<'tcx>>)
-> bool
where T : TypeFoldable<'tcx>
{
@ -236,7 +236,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
skipped_regions: &mut bool,
mut f: F)
-> T
where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region,
where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx>,
T : TypeFoldable<'tcx>,
{
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
@ -256,14 +256,14 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
skipped_regions: &'a mut bool,
current_depth: u32,
fld_r: &'a mut (FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + 'a),
fld_r: &'a mut (FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> + 'a),
}
impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
pub fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
skipped_regions: &'a mut bool,
fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx>
where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region
where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx>
{
RegionFolder {
tcx: tcx,
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
t
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => {
debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})",
@ -309,16 +309,16 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
current_depth: u32,
fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a),
map: FxHashMap<ty::BoundRegion, &'tcx ty::Region>
fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn replace_late_bound_regions<T,F>(self,
value: &Binder<T>,
mut f: F)
-> (T, FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region,
-> (T, FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
T : TypeFoldable<'tcx>,
{
let mut replacer = RegionReplacer::new(self, &mut f);
@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
/// `scope_id`.
pub fn liberate_late_bound_regions<T>(self,
all_outlive_scope: region::CodeExtent,
all_outlive_scope: Option<region::CodeExtent<'tcx>>,
value: &Binder<T>)
-> T
where T : TypeFoldable<'tcx>
@ -435,7 +435,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> {
fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F)
-> RegionReplacer<'a, 'gcx, 'tcx>
where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region
where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>
{
RegionReplacer {
tcx: tcx,
@ -464,7 +464,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
t.super_fold_with(self)
}
fn fold_region(&mut self, r:&'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
let fld_r = &mut self.fld_r;
@ -527,7 +527,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
u.super_fold_with(self)
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
// because late-bound regions affect subtyping, we can't
// erase the bound/free distinction, but we can replace
// all free regions with 'erased.
@ -554,7 +554,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// regions. See comment on `shift_regions_through_binders` method in
// `subst.rs` for more details.
pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
pub fn shift_region<'tcx>(region: ty::RegionKind<'tcx>, amount: u32) -> ty::RegionKind<'tcx> {
match region {
ty::ReLateBound(debruijn, br) => {
ty::ReLateBound(debruijn.shifted(amount), br)
@ -567,9 +567,9 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
amount: u32)
-> &'tcx ty::Region
-> ty::Region<'tcx>
{
match region {
&ty::ReLateBound(debruijn, br) if amount > 0 => {
@ -582,7 +582,8 @@ pub fn shift_region_ref<'a, 'gcx, 'tcx>(
}
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
amount: u32, value: &T) -> T
amount: u32,
value: &T) -> T
where T: TypeFoldable<'tcx>
{
debug!("shift_regions(value={:?}, amount={})",
@ -631,7 +632,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
t.region_depth > self.depth
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
r.escapes_depth(self.depth)
}
}
@ -647,7 +648,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
flags.intersects(self.flags)
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
let flags = r.type_flags();
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
flags.intersects(self.flags)
@ -693,7 +694,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
t.super_visit_with(self)
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
match *r {
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
self.regions.insert(br);

View file

@ -1268,9 +1268,8 @@ impl<'a, 'gcx, 'tcx> Layout {
let kind = if def.is_enum() || def.variants[0].fields.len() == 0{
StructKind::AlwaysSizedUnivariant
} else {
use middle::region::ROOT_CODE_EXTENT;
let param_env = tcx.construct_parameter_environment(DUMMY_SP,
def.did, ROOT_CODE_EXTENT);
def.did, None);
let fields = &def.variants[0].fields;
let last_field = &fields[fields.len()-1];
let always_sized = last_field.ty(tcx, param_env.free_substs)

View file

@ -14,6 +14,7 @@ use hir::def::Def;
use hir;
use middle::const_val;
use middle::privacy::AccessLevels;
use middle::region::RegionMaps;
use mir;
use session::CompileResult;
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
@ -592,6 +593,11 @@ define_maps! { <'tcx>
[] reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
/// Per-function `RegionMaps`. The `DefId` should be the owner-def-id for the fn body;
/// in the case of closures or "inline" expressions, this will be redirected to the enclosing
/// fn item.
[] region_maps: RegionMaps(DefId) -> Rc<RegionMaps<'tcx>>,
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
[] def_symbol_name: SymbolName(DefId) -> ty::SymbolName,

View file

@ -23,7 +23,7 @@ use ich::StableHashingContext;
use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::privacy::AccessLevels;
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use middle::region::CodeExtent;
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
use traits;
@ -46,7 +46,7 @@ use std::rc::Rc;
use std::slice;
use std::vec::IntoIter;
use std::mem;
use syntax::ast::{self, Name, NodeId};
use syntax::ast::{self, DUMMY_NODE_ID, Name, NodeId};
use syntax::attr;
use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{DUMMY_SP, Span};
@ -67,11 +67,12 @@ pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::RegionKind;
pub use self::sty::Issue32330;
pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
pub use self::sty::BoundRegion::*;
pub use self::sty::InferTy::*;
pub use self::sty::Region::*;
pub use self::sty::RegionKind::*;
pub use self::sty::TypeVariants::*;
pub use self::context::{TyCtxt, GlobalArenas, tls};
@ -601,7 +602,7 @@ pub struct UpvarBorrow<'tcx> {
pub kind: BorrowKind,
/// Region of the resulting reference.
pub region: &'tcx ty::Region,
pub region: ty::Region<'tcx>,
}
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
@ -934,9 +935,9 @@ pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
&'tcx ty::Region>;
pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>;
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<ty::Region<'tcx>,
ty::Region<'tcx>>;
pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct SubtypePredicate<'tcx> {
@ -1164,22 +1165,24 @@ pub struct ParameterEnvironment<'tcx> {
/// Each type parameter has an implicit region bound that
/// indicates it must outlive at least the function body (the user
/// may specify stronger requirements). This field indicates the
/// region of the callee.
pub implicit_region_bound: &'tcx ty::Region,
/// region of the callee. If it is `None`, then the parameter
/// environment is for an item or something where the "callee" is
/// not clear.
pub implicit_region_bound: Option<ty::Region<'tcx>>,
/// Obligations that the caller must satisfy. This is basically
/// the set of bounds on the in-scope type parameters, translated
/// into Obligations, and elaborated and normalized.
pub caller_bounds: Vec<ty::Predicate<'tcx>>,
/// Scope that is attached to free regions for this scope. This
/// is usually the id of the fn body, but for more abstract scopes
/// like structs we often use the node-id of the struct.
/// Scope that is attached to free regions for this scope. This is
/// usually the id of the fn body, but for more abstract scopes
/// like structs we use None or the item extent.
///
/// FIXME(#3696). It would be nice to refactor so that free
/// regions don't have this implicit scope and instead introduce
/// relationships in the environment.
pub free_id_outlive: CodeExtent,
pub free_id_outlive: Option<CodeExtent<'tcx>>,
/// A cache for `moves_by_default`.
pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
@ -1220,13 +1223,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
let impl_def_id = tcx.hir.local_def_id(impl_id);
tcx.construct_parameter_environment(impl_item.span,
impl_def_id,
tcx.region_maps.item_extent(id))
Some(tcx.item_extent(id)))
}
hir::ImplItemKind::Method(_, ref body) => {
tcx.construct_parameter_environment(
impl_item.span,
tcx.hir.local_def_id(id),
tcx.region_maps.call_site_extent(id, body.node_id))
Some(tcx.call_site_extent(id, body.node_id)))
}
}
}
@ -1239,7 +1242,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
let trait_def_id = tcx.hir.local_def_id(trait_id);
tcx.construct_parameter_environment(trait_item.span,
trait_def_id,
tcx.region_maps.item_extent(id))
Some(tcx.item_extent(id)))
}
hir::TraitItemKind::Method(_, ref body) => {
// Use call-site for extent (unless this is a
@ -1247,15 +1250,15 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
// to the method id).
let extent = if let hir::TraitMethod::Provided(body_id) = *body {
// default impl: use call_site extent as free_id_outlive bound.
tcx.region_maps.call_site_extent(id, body_id.node_id)
tcx.call_site_extent(id, body_id.node_id)
} else {
// no default impl: use item extent as free_id_outlive bound.
tcx.region_maps.item_extent(id)
tcx.item_extent(id)
};
tcx.construct_parameter_environment(
trait_item.span,
tcx.hir.local_def_id(id),
extent)
Some(extent))
}
}
}
@ -1268,7 +1271,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
tcx.construct_parameter_environment(
item.span,
fn_def_id,
tcx.region_maps.call_site_extent(id, body_id.node_id))
Some(tcx.call_site_extent(id, body_id.node_id)))
}
hir::ItemEnum(..) |
hir::ItemStruct(..) |
@ -1280,13 +1283,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
let def_id = tcx.hir.local_def_id(id);
tcx.construct_parameter_environment(item.span,
def_id,
tcx.region_maps.item_extent(id))
Some(tcx.item_extent(id)))
}
hir::ItemTrait(..) => {
let def_id = tcx.hir.local_def_id(id);
tcx.construct_parameter_environment(item.span,
def_id,
tcx.region_maps.item_extent(id))
Some(tcx.item_extent(id)))
}
_ => {
span_bug!(item.span,
@ -1304,7 +1307,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
tcx.construct_parameter_environment(
expr.span,
base_def_id,
tcx.region_maps.call_site_extent(id, body.node_id))
Some(tcx.call_site_extent(id, body.node_id)))
} else {
tcx.empty_parameter_environment()
}
@ -1313,14 +1316,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
let def_id = tcx.hir.local_def_id(id);
tcx.construct_parameter_environment(item.span,
def_id,
ROOT_CODE_EXTENT)
None)
}
Some(hir_map::NodeStructCtor(..)) |
Some(hir_map::NodeVariant(..)) => {
let def_id = tcx.hir.local_def_id(id);
tcx.construct_parameter_environment(tcx.hir.span(id),
def_id,
ROOT_CODE_EXTENT)
None)
}
it => {
bug!("ParameterEnvironment::from_item(): \
@ -2439,10 +2442,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
ty::ParameterEnvironment {
free_substs: self.intern_substs(&[]),
caller_bounds: Vec::new(),
implicit_region_bound: self.types.re_empty,
// for an empty parameter environment, there ARE no free
// regions, so it shouldn't matter what we use for the free id
free_id_outlive: ROOT_CODE_EXTENT,
implicit_region_bound: None,
free_id_outlive: None,
is_copy_cache: RefCell::new(FxHashMap()),
is_sized_cache: RefCell::new(FxHashMap()),
is_freeze_cache: RefCell::new(FxHashMap()),
@ -2454,8 +2455,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// In general, this means converting from bound parameters to
/// free parameters. Since we currently represent bound/free type
/// parameters in the same way, this only has an effect on regions.
pub fn construct_free_substs(self, def_id: DefId,
free_id_outlive: CodeExtent)
pub fn construct_free_substs(self,
def_id: DefId,
free_id_outlive: Option<CodeExtent<'gcx>>)
-> &'gcx Substs<'gcx> {
let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
@ -2474,12 +2476,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
/// See `ParameterEnvironment` struct def'n for details.
/// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)`
/// If you were using `free_id: NodeId`, you might try `self.region_maps().item_extent(free_id)`
/// for the `free_id_outlive` parameter. (But note that this is not always quite right.)
pub fn construct_parameter_environment(self,
span: Span,
def_id: DefId,
free_id_outlive: CodeExtent)
free_id_outlive: Option<CodeExtent<'gcx>>)
-> ParameterEnvironment<'gcx>
{
//
@ -2513,7 +2515,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let unnormalized_env = ty::ParameterEnvironment {
free_substs: free_substs,
implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)),
implicit_region_bound: free_id_outlive.map(|f| tcx.mk_region(ty::ReScope(f))),
caller_bounds: predicates,
free_id_outlive: free_id_outlive,
is_copy_cache: RefCell::new(FxHashMap()),
@ -2521,12 +2523,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
is_freeze_cache: RefCell::new(FxHashMap()),
};
let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps));
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
let body_id = free_id_outlive.map(|f| f.node_id())
.unwrap_or(DUMMY_NODE_ID);
let cause = traits::ObligationCause::misc(span, body_id);
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
}
pub fn node_scope_region(self, id: NodeId) -> &'tcx Region {
self.mk_region(ty::ReScope(self.region_maps.node_extent(id)))
pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> {
self.mk_region(ty::ReScope(self.node_extent(id)))
}
pub fn visit_all_item_likes_in_krate<V,F>(self,

View file

@ -16,7 +16,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable};
#[derive(Debug)]
pub enum Component<'tcx> {
Region(&'tcx ty::Region),
Region(ty::Region<'tcx>),
Param(ty::ParamTy),
UnresolvedInferenceVariable(ty::InferTy),
@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<&'tcx ty::Region>) {
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region<'tcx>>) {
for r in regions {
if !r.is_bound() {
out.push(Component::Region(r));

View file

@ -67,8 +67,8 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>)
-> RelateResult<'tcx, Ty<'tcx>>;
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region>;
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>>;
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> RelateResult<'tcx, ty::Binder<T>>
@ -529,11 +529,11 @@ impl<'tcx> Relate<'tcx> for &'tcx Substs<'tcx> {
}
}
impl<'tcx> Relate<'tcx> for &'tcx ty::Region {
impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
fn relate<'a, 'gcx, R>(relation: &mut R,
a: &&'tcx ty::Region,
b: &&'tcx ty::Region)
-> RelateResult<'tcx, &'tcx ty::Region>
a: &ty::Region<'tcx>,
b: &ty::Region<'tcx>)
-> RelateResult<'tcx, ty::Region<'tcx>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
relation.regions(*a, *b)

View file

@ -624,7 +624,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
*self
}

View file

@ -43,8 +43,12 @@ pub struct TypeAndMut<'tcx> {
RustcEncodable, RustcDecodable, Copy)]
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
pub struct FreeRegion {
pub scope: region::CodeExtent,
///
/// If `fr.scope` is None, then this is in some context (e.g., an
/// impl) where lifetimes are more abstract and the notion of the
/// caller/callee stack frames are not applicable.
pub struct FreeRegion<'tcx> {
pub scope: Option<region::CodeExtent<'tcx>>,
pub bound_region: BoundRegion,
}
@ -133,7 +137,7 @@ pub enum TypeVariants<'tcx> {
/// A reference; a pointer with an associated lifetime. Written as
/// `&'a mut T` or `&'a T`.
TyRef(&'tcx Region, TypeAndMut<'tcx>),
TyRef(Region<'tcx>, TypeAndMut<'tcx>),
/// The anonymous type of a function declaration/definition. Each
/// function has a unique type.
@ -145,7 +149,7 @@ pub enum TypeVariants<'tcx> {
TyFnPtr(PolyFnSig<'tcx>),
/// A trait, defined with `trait`.
TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, &'tcx ty::Region),
TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
/// The anonymous type of a closure. Used to represent the type of
/// `|a| a`.
@ -684,6 +688,8 @@ pub struct DebruijnIndex {
pub depth: u32,
}
pub type Region<'tcx> = &'tcx RegionKind<'tcx>;
/// Representation of regions.
///
/// Unlike types, most region variants are "fictitious", not concrete,
@ -741,7 +747,7 @@ pub struct DebruijnIndex {
/// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
pub enum Region {
pub enum RegionKind<'tcx> {
// Region bound in a type or fn declaration which will be
// substituted 'early' -- that is, at the same time when type
// parameters are substituted.
@ -754,12 +760,12 @@ pub enum Region {
/// When checking a function body, the types of all arguments and so forth
/// that refer to bound region parameters are modified to refer to free
/// region parameters.
ReFree(FreeRegion),
ReFree(FreeRegion<'tcx>),
/// A concrete region naming some statically determined extent
/// (e.g. an expression or sequence of statements) within the
/// current function.
ReScope(region::CodeExtent),
ReScope(region::CodeExtent<'tcx>),
/// Static data that has an "infinite" lifetime. Top in the region lattice.
ReStatic,
@ -784,7 +790,7 @@ pub enum Region {
ReErased,
}
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Region {}
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub struct EarlyBoundRegion {
@ -903,7 +909,7 @@ impl DebruijnIndex {
}
// Region utilities
impl Region {
impl<'tcx> RegionKind<'tcx> {
pub fn is_bound(&self) -> bool {
match *self {
ty::ReEarlyBound(..) => true,
@ -927,7 +933,7 @@ impl Region {
}
/// Returns the depth of `self` from the (1-based) binding level `depth`
pub fn from_depth(&self, depth: u32) -> Region {
pub fn from_depth(&self, depth: u32) -> RegionKind<'tcx> {
match *self {
ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex {
depth: debruijn.depth - (depth - 1)
@ -1346,7 +1352,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
/// Returns the regions directly referenced from this type (but
/// not types reachable from this type via `walk_tys`). This
/// ignores late-bound regions binders.
pub fn regions(&self) -> Vec<&'tcx ty::Region> {
pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
match self.sty {
TyRef(region, _) => {
vec![region]

View file

@ -11,7 +11,7 @@
// Type substitutions.
use hir::def_id::DefId;
use ty::{self, Slice, Ty, TyCtxt};
use ty::{self, Slice, Region, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
@ -32,7 +32,7 @@ use std::mem;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Kind<'tcx> {
ptr: NonZero<usize>,
marker: PhantomData<(Ty<'tcx>, &'tcx ty::Region)>
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)>
}
const TAG_MASK: usize = 0b11;
@ -54,8 +54,8 @@ impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Region> for Kind<'tcx> {
fn from(r: &'tcx ty::Region) -> Kind<'tcx> {
impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
fn from(r: ty::Region<'tcx>) -> Kind<'tcx> {
// Ensure we can use the tag bits.
assert_eq!(mem::align_of_val(r) & TAG_MASK, 0);
@ -88,7 +88,7 @@ impl<'tcx> Kind<'tcx> {
}
#[inline]
pub fn as_region(self) -> Option<&'tcx ty::Region> {
pub fn as_region(self) -> Option<ty::Region<'tcx>> {
unsafe {
self.downcast(REGION_TAG)
}
@ -153,7 +153,7 @@ impl<'tcx> Decodable for Kind<'tcx> {
d.read_enum_variant(&["Ty", "Region"], |d, tag| {
match tag {
TYPE_TAG => Ty::decode(d).map(Kind::from),
REGION_TAG => <&ty::Region>::decode(d).map(Kind::from),
REGION_TAG => Region::decode(d).map(Kind::from),
_ => Err(d.error("invalid Kind tag"))
}
})
@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
mut mk_region: FR,
mut mk_type: FT)
-> &'tcx Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
let defs = tcx.generics_of(def_id);
let mut substs = Vec::with_capacity(defs.count());
@ -197,7 +197,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
mut mk_region: FR,
mut mk_type: FT)
-> &'tcx Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx>
{
let defs = tcx.generics_of(def_id);
@ -212,7 +212,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
defs: &ty::Generics,
mk_region: &mut FR,
mk_type: &mut FT)
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
if let Some(def_id) = defs.parent {
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
defs: &ty::Generics,
mk_region: &mut FR,
mk_type: &mut FT)
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
// Handle Self first, before all regions.
let mut types = defs.types.iter();
@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
#[inline]
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=&'tcx ty::Region> + 'a {
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
self.iter().filter_map(|k| k.as_region())
}
@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
#[inline]
pub fn region_at(&self, i: usize) -> &'tcx ty::Region {
pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
self[i].as_region().unwrap_or_else(|| {
bug!("expected region for param #{} in {:?}", i, self);
})
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
#[inline]
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> &'tcx ty::Region {
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region<'tcx> {
self.region_at(def.index as usize)
}
@ -396,7 +396,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
t
}
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
// Note: This routine only handles regions that are bound on
// type declarations and other outer declarations, not those
// bound in *fn types*. Region substitution of the bound
@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
result
}
fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region {
fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
if self.region_binders_passed == 0 || !region.has_escaping_regions() {
return region;
}

View file

@ -316,7 +316,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn required_region_bounds(self,
erased_self_ty: Ty<'tcx>,
predicates: Vec<ty::Predicate<'tcx>>)
-> Vec<&'tcx ty::Region> {
-> Vec<ty::Region<'tcx>> {
debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
erased_self_ty,
predicates);
@ -457,7 +457,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let result = item_substs.iter().zip(impl_substs.iter())
.filter(|&(_, &k)| {
if let Some(&ty::Region::ReEarlyBound(ref ebr)) = k.as_region() {
if let Some(&ty::RegionKind::ReEarlyBound(ref ebr)) = k.as_region() {
!impl_generics.region_param(ebr).pure_wrt_drop
} else if let Some(&ty::TyS {
sty: ty::TypeVariants::TyParam(ref pt), ..
@ -673,7 +673,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
ty.super_visit_with(self)
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
self.hash_discriminant_u8(r);
match *r {
ty::ReErased |

View file

@ -116,9 +116,9 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
#[derive(Debug)]
pub enum ImpliedBound<'tcx> {
RegionSubRegion(&'tcx ty::Region, &'tcx ty::Region),
RegionSubParam(&'tcx ty::Region, ty::ParamTy),
RegionSubProjection(&'tcx ty::Region, ty::ProjectionTy<'tcx>),
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),
}
/// Compute the implied bounds that a callee/impl can assume based on
@ -198,7 +198,7 @@ pub fn implied_bounds<'a, 'gcx, 'tcx>(
/// this down to determine what relationships would have to hold for
/// `T: 'a` to hold. We get to assume that the caller has validated
/// those relationships.
fn implied_bounds_from_components<'tcx>(sub_region: &'tcx ty::Region,
fn implied_bounds_from_components<'tcx>(sub_region: ty::Region<'tcx>,
sup_components: Vec<Component<'tcx>>)
-> Vec<ImpliedBound<'tcx>>
{
@ -455,7 +455,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
fn from_object_ty(&mut self, ty: Ty<'tcx>,
data: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>,
region: &'tcx ty::Region) {
region: ty::Region<'tcx>) {
// Imagine a type like this:
//
// trait Foo { }
@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
pub fn object_region_bounds<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
-> Vec<&'tcx ty::Region>
-> Vec<ty::Region<'tcx>>
{
// Since we don't actually *know* the self type for an object,
// this "open(err)" serves as a kind of dummy standin -- basically

View file

@ -177,12 +177,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| {
// Don't print any regions if they're all erased.
let regions = || substs.regions().skip(skip).take(count);
if regions().all(|r: &ty::Region| *r == ty::ReErased) {
if regions().all(|r: ty::Region| *r == ty::ReErased) {
return Ok(());
}
for region in regions() {
let region: &ty::Region = region;
let region: ty::Region = region;
start_or_continue(f, start, ", ")?;
if verbose {
write!(f, "{:?}", region)?;
@ -458,7 +458,7 @@ impl fmt::Debug for ty::BoundRegion {
}
}
impl fmt::Debug for ty::Region {
impl<'tcx> fmt::Debug for ty::RegionKind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ty::ReEarlyBound(ref data) => {
@ -516,7 +516,7 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
}
}
impl fmt::Display for ty::Region {
impl<'tcx> fmt::Display for ty::RegionKind<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if verbose() {
return write!(f, "{:?}", *self);
@ -544,7 +544,7 @@ impl fmt::Display for ty::Region {
}
}
impl fmt::Debug for ty::FreeRegion {
impl<'tcx> fmt::Debug for ty::FreeRegion<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ReFree({:?}, {:?})",
self.scope, self.bound_region)
@ -689,14 +689,14 @@ impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
}
}
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>> {
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
}
}
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region,
&'tcx ty::Region>> {
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>,
ty::Region<'tcx>>> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
}

View file

@ -126,7 +126,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
borrow_id: ast::NodeId,
borrow_span: Span,
cmt: mc::cmt<'tcx>,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
bk: ty::BorrowKind,
loan_cause: euv::LoanCause)
{
@ -199,7 +199,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
all_loans: all_loans,
param_env: &infcx.parameter_environment
};
euv::ExprUseVisitor::new(&mut clcx, &infcx).consume_body(body);
euv::ExprUseVisitor::new(&mut clcx, &bccx.region_maps, &infcx).consume_body(body);
}
#[derive(PartialEq)]
@ -232,15 +232,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
})
}
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent<'tcx>, mut op: F) -> bool where
F: FnMut(&Loan<'tcx>) -> bool,
{
//! Like `each_issued_loan()`, but only considers loans that are
//! currently in scope.
let tcx = self.tcx();
self.each_issued_loan(scope.node_id(&tcx.region_maps), |loan| {
if tcx.region_maps.is_subscope_of(scope, loan.kill_scope) {
self.each_issued_loan(scope.node_id(), |loan| {
if self.bccx.region_maps.is_subscope_of(scope, loan.kill_scope) {
op(loan)
} else {
true
@ -249,7 +248,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
}
fn each_in_scope_loan_affecting_path<F>(&self,
scope: region::CodeExtent,
scope: region::CodeExtent<'tcx>,
loan_path: &LoanPath<'tcx>,
mut op: F)
-> bool where
@ -379,8 +378,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
new_loan);
// Should only be called for loans that are in scope at the same time.
assert!(self.tcx().region_maps.scopes_intersect(old_loan.kill_scope,
new_loan.kill_scope));
assert!(self.bccx.region_maps.scopes_intersect(old_loan.kill_scope,
new_loan.kill_scope));
self.report_error_if_loan_conflicts_with_restriction(
old_loan, new_loan, old_loan, new_loan) &&
@ -460,8 +459,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
// 3. Where does old loan expire.
let previous_end_span =
self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps))
.end_point();
self.tcx().hir.span(old_loan.kill_scope.node_id()).end_point();
let mut err = match (new_loan.kind, old_loan.kind) {
(ty::MutBorrow, ty::MutBorrow) => {
@ -710,7 +708,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
let mut ret = UseOk;
self.each_in_scope_loan_affecting_path(
self.tcx().region_maps.node_extent(expr_id), use_path, |loan| {
self.tcx().node_extent(expr_id), use_path, |loan| {
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
false
@ -824,7 +822,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
// Check that we don't invalidate any outstanding loans
if let Some(loan_path) = opt_loan_path(&assignee_cmt) {
let scope = self.tcx().region_maps.node_extent(assignment_id);
let scope = self.tcx().node_extent(assignment_id);
self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| {
self.report_illegal_mutation(assignment_span, &loan_path, loan);
false

View file

@ -24,11 +24,11 @@ use syntax_pos::Span;
type R = Result<(),()>;
pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
item_scope: region::CodeExtent,
item_scope: region::CodeExtent<'tcx>,
span: Span,
cause: euv::LoanCause,
cmt: mc::cmt<'tcx>,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
_: ty::BorrowKind)
-> Result<(),()> {
//! Reports error if `loan_region` is larger than S
@ -52,11 +52,11 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>,
// the scope of the function body for the enclosing item
item_scope: region::CodeExtent,
item_scope: region::CodeExtent<'tcx>,
span: Span,
cause: euv::LoanCause,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
cmt_original: mc::cmt<'tcx>
}
@ -92,7 +92,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
}
}
fn check_scope(&self, max_scope: &'tcx ty::Region) -> R {
fn check_scope(&self, max_scope: ty::Region<'tcx>) -> R {
//! Reports an error if `loan_region` is larger than `max_scope`
if !self.bccx.is_subregion_of(self.loan_region, max_scope) {
@ -102,7 +102,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
}
}
fn scope(&self, cmt: &mc::cmt<'tcx>) -> &'tcx ty::Region {
fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'tcx> {
//! Returns the maximal region scope for the which the
//! lvalue `cmt` is guaranteed to be valid without any
//! rooting etc, and presuming `cmt` is not mutated.
@ -116,7 +116,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
}
Categorization::Local(local_id) => {
self.bccx.tcx.mk_region(ty::ReScope(
self.bccx.tcx.region_maps.var_scope(local_id)))
self.bccx.region_maps.var_scope(local_id)))
}
Categorization::StaticItem |
Categorization::Deref(.., mc::UnsafePtr(..)) => {

View file

@ -45,13 +45,13 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
bccx: bccx,
infcx: &infcx,
all_loans: Vec::new(),
item_ub: bccx.tcx.region_maps.node_extent(body.node_id),
item_ub: bccx.tcx.node_extent(body.node_id),
move_data: MoveData::new(),
move_error_collector: move_error::MoveErrorCollector::new(),
};
let body = glcx.bccx.tcx.hir.body(body);
euv::ExprUseVisitor::new(&mut glcx, &infcx).consume_body(body);
euv::ExprUseVisitor::new(&mut glcx, &bccx.region_maps, &infcx).consume_body(body);
glcx.report_potential_errors();
let GatherLoanCtxt { all_loans, move_data, .. } = glcx;
@ -66,7 +66,7 @@ struct GatherLoanCtxt<'a, 'tcx: 'a> {
all_loans: Vec<Loan<'tcx>>,
/// `item_ub` is used as an upper-bound on the lifetime whenever we
/// ask for the scope of an expression categorized as an upvar.
item_ub: region::CodeExtent,
item_ub: region::CodeExtent<'tcx>,
}
impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
@ -127,7 +127,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
borrow_id: ast::NodeId,
borrow_span: Span,
cmt: mc::cmt<'tcx>,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
bk: ty::BorrowKind,
loan_cause: euv::LoanCause)
{
@ -299,7 +299,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
borrow_span: Span,
cmt: mc::cmt<'tcx>,
req_kind: ty::BorrowKind,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
cause: euv::LoanCause) {
debug!("guarantee_valid(borrow_id={}, cmt={:?}, \
req_mutbl={:?}, loan_region={:?})",
@ -353,7 +353,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
let loan_scope = match *loan_region {
ty::ReScope(scope) => scope,
ty::ReFree(ref fr) => fr.scope,
ty::ReFree(ref fr) => fr.scope.unwrap_or(self.item_ub),
ty::ReStatic => self.item_ub,
@ -371,7 +371,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
};
debug!("loan_scope = {:?}", loan_scope);
let borrow_scope = self.tcx().region_maps.node_extent(borrow_id);
let borrow_scope = self.tcx().node_extent(borrow_id);
let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope);
debug!("gen_scope = {:?}", gen_scope);
@ -450,23 +450,23 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
}
pub fn compute_gen_scope(&self,
borrow_scope: region::CodeExtent,
loan_scope: region::CodeExtent)
-> region::CodeExtent {
borrow_scope: region::CodeExtent<'tcx>,
loan_scope: region::CodeExtent<'tcx>)
-> region::CodeExtent<'tcx> {
//! Determine when to introduce the loan. Typically the loan
//! is introduced at the point of the borrow, but in some cases,
//! notably method arguments, the loan may be introduced only
//! later, once it comes into scope.
if self.bccx.tcx.region_maps.is_subscope_of(borrow_scope, loan_scope) {
if self.bccx.region_maps.is_subscope_of(borrow_scope, loan_scope) {
borrow_scope
} else {
loan_scope
}
}
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent, lp: &LoanPath<'tcx>)
-> region::CodeExtent {
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent<'tcx>, lp: &LoanPath<'tcx>)
-> region::CodeExtent<'tcx> {
//! Determine when the loan restrictions go out of scope.
//! This is either when the lifetime expires or when the
//! local variable which roots the loan-path goes out of scope,
@ -488,12 +488,11 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
//! with immutable `&` pointers, because borrows of such pointers
//! do not require restrictions and hence do not cause a loan.
let lexical_scope = lp.kill_scope(self.bccx.tcx);
let rm = &self.bccx.tcx.region_maps;
if rm.is_subscope_of(lexical_scope, loan_scope) {
let lexical_scope = lp.kill_scope(self.bccx);
if self.bccx.region_maps.is_subscope_of(lexical_scope, loan_scope) {
lexical_scope
} else {
assert!(self.bccx.tcx.region_maps.is_subscope_of(loan_scope, lexical_scope));
assert!(self.bccx.region_maps.is_subscope_of(loan_scope, lexical_scope));
loan_scope
}
}

View file

@ -31,7 +31,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
span: Span,
cause: euv::LoanCause,
cmt: mc::cmt<'tcx>,
loan_region: &'tcx ty::Region)
loan_region: ty::Region<'tcx>)
-> RestrictionResult<'tcx> {
let ctxt = RestrictionsContext {
bccx: bccx,
@ -49,7 +49,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
struct RestrictionsContext<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>,
span: Span,
loan_region: &'tcx ty::Region,
loan_region: ty::Region<'tcx>,
cause: euv::LoanCause,
}

View file

@ -34,7 +34,8 @@ use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::mem_categorization::ImmutabilityBlame;
use rustc::middle::region;
use rustc::middle::region::{self, RegionMaps};
use rustc::middle::free_region::RegionRelations;
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::Providers;
@ -88,11 +89,8 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
let body_id = tcx.hir.body_owned_by(owner_id);
let attributes = tcx.get_attrs(owner_def_id);
let tables = tcx.typeck_tables_of(owner_def_id);
let mut bccx = &mut BorrowckCtxt {
tcx: tcx,
tables: tables,
};
let region_maps = tcx.region_maps(owner_def_id);
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
let body = bccx.tcx.hir.body(body_id);
@ -141,15 +139,15 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
id_range,
all_loans.len());
for (loan_idx, loan) in all_loans.iter().enumerate() {
loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps), loan_idx);
loan_dfcx.add_gen(loan.gen_scope.node_id(), loan_idx);
loan_dfcx.add_kill(KillFrom::ScopeEnd,
loan.kill_scope.node_id(&tcx.region_maps), loan_idx);
loan.kill_scope.node_id(), loan_idx);
}
loan_dfcx.add_kills_from_flow_exits(cfg);
loan_dfcx.propagate(cfg, body);
let flowed_moves = move_data::FlowedMoveData::new(move_data,
this.tcx,
this,
cfg,
id_range,
body);
@ -170,11 +168,8 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
let owner_id = tcx.hir.body_owner(body_id);
let owner_def_id = tcx.hir.local_def_id(owner_id);
let tables = tcx.typeck_tables_of(owner_def_id);
let mut bccx = BorrowckCtxt {
tcx: tcx,
tables: tables,
};
let region_maps = tcx.region_maps(owner_def_id);
let mut bccx = BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
let dataflow_data = build_borrowck_dataflow_data(&mut bccx, cfg, body_id);
(bccx, dataflow_data)
@ -189,6 +184,10 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
// tables for the current thing we are checking; set to
// Some in `borrowck_fn` and cleared later
tables: &'a ty::TypeckTables<'tcx>,
region_maps: Rc<RegionMaps<'tcx>>,
owner_def_id: DefId,
}
///////////////////////////////////////////////////////////////////////////
@ -206,13 +205,13 @@ pub struct Loan<'tcx> {
/// cases, notably method arguments, the loan may be introduced
/// only later, once it comes into scope. See also
/// `GatherLoanCtxt::compute_gen_scope`.
gen_scope: region::CodeExtent,
gen_scope: region::CodeExtent<'tcx>,
/// kill_scope indicates when the loan goes out of scope. This is
/// either when the lifetime expires or when the local variable
/// which roots the loan-path goes out of scope, whichever happens
/// faster. See also `GatherLoanCtxt::compute_kill_scope`.
kill_scope: region::CodeExtent,
kill_scope: region::CodeExtent<'tcx>,
span: Span,
cause: euv::LoanCause,
}
@ -312,15 +311,15 @@ pub fn closure_to_block(closure_id: ast::NodeId,
}
impl<'a, 'tcx> LoanPath<'tcx> {
pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent {
pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::CodeExtent<'tcx> {
match self.kind {
LpVar(local_id) => tcx.region_maps.var_scope(local_id),
LpVar(local_id) => bccx.region_maps.var_scope(local_id),
LpUpvar(upvar_id) => {
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
tcx.region_maps.node_extent(block_id)
let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx);
bccx.tcx.node_extent(block_id)
}
LpDowncast(ref base, _) |
LpExtend(ref base, ..) => base.kill_scope(tcx),
LpExtend(ref base, ..) => base.kill_scope(bccx),
}
}
@ -444,8 +443,8 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
pub enum bckerr_code<'tcx> {
err_mutbl,
/// superscope, subscope, loan cause
err_out_of_scope(&'tcx ty::Region, &'tcx ty::Region, euv::LoanCause),
err_borrowed_pointer_too_short(&'tcx ty::Region, &'tcx ty::Region), // loan, ptr
err_out_of_scope(ty::Region<'tcx>, ty::Region<'tcx>, euv::LoanCause),
err_borrowed_pointer_too_short(ty::Region<'tcx>, ty::Region<'tcx>), // loan, ptr
}
// Combination of an error code and the categorization of the expression
@ -475,11 +474,15 @@ pub enum MovedValueUseKind {
impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
pub fn is_subregion_of(&self,
r_sub: &'tcx ty::Region,
r_sup: &'tcx ty::Region)
r_sub: ty::Region<'tcx>,
r_sup: ty::Region<'tcx>)
-> bool
{
self.tables.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup)
let region_rels = RegionRelations::new(self.tcx,
self.owner_def_id,
&self.region_maps,
&self.tables.free_region_map);
region_rels.is_subregion_of(r_sub, r_sup)
}
pub fn report(&self, err: BckError<'tcx>) {
@ -963,10 +966,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
.emit();
}
fn region_end_span(&self, region: &'tcx ty::Region) -> Option<Span> {
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
match *region {
ty::ReScope(scope) => {
match scope.span(&self.tcx.region_maps, &self.tcx.hir) {
match scope.span(&self.tcx.hir) {
Some(s) => {
Some(s.end_point())
}
@ -1244,10 +1247,10 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \
}
}
fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option<Span> {
fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option<Span> {
match *region {
ty::ReScope(scope) => {
match tcx.hir.find(scope.node_id(&tcx.region_maps)) {
match tcx.hir.find(scope.node_id()) {
Some(hir_map::NodeStmt(stmt)) => Some(stmt.span),
_ => None
}

View file

@ -523,7 +523,8 @@ impl<'a, 'tcx> MoveData<'tcx> {
/// Moves are generated by moves and killed by assignments and
/// scoping. Assignments are generated by assignment to variables and
/// killed by scoping. See `README.md` for more details.
fn add_gen_kills(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn add_gen_kills(&self,
bccx: &BorrowckCtxt<'a, 'tcx>,
dfcx_moves: &mut MoveDataFlow,
dfcx_assign: &mut AssignDataFlow) {
for (i, the_move) in self.moves.borrow().iter().enumerate() {
@ -546,9 +547,9 @@ impl<'a, 'tcx> MoveData<'tcx> {
for path in self.paths.borrow().iter() {
match path.loan_path.kind {
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
let kill_scope = path.loan_path.kill_scope(tcx);
let kill_scope = path.loan_path.kill_scope(bccx);
let path = *self.path_map.borrow().get(&path.loan_path).unwrap();
self.kill_moves(path, kill_scope.node_id(&tcx.region_maps),
self.kill_moves(path, kill_scope.node_id(),
KillFrom::ScopeEnd, dfcx_moves);
}
LpExtend(..) => {}
@ -561,9 +562,9 @@ impl<'a, 'tcx> MoveData<'tcx> {
let lp = self.path_loan_path(assignment.path);
match lp.kind {
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
let kill_scope = lp.kill_scope(tcx);
let kill_scope = lp.kill_scope(bccx);
dfcx_assign.add_kill(KillFrom::ScopeEnd,
kill_scope.node_id(&tcx.region_maps),
kill_scope.node_id(),
assignment_index);
}
LpExtend(..) => {
@ -652,11 +653,13 @@ impl<'a, 'tcx> MoveData<'tcx> {
impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
pub fn new(move_data: MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
bccx: &BorrowckCtxt<'a, 'tcx>,
cfg: &cfg::CFG,
id_range: IdRange,
body: &hir::Body)
-> FlowedMoveData<'a, 'tcx> {
let tcx = bccx.tcx;
let mut dfcx_moves =
DataFlowContext::new(tcx,
"flowed_move_data_moves",
@ -676,7 +679,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
move_data.fixup_fragment_sets(tcx);
move_data.add_gen_kills(tcx,
move_data.add_gen_kills(bccx,
&mut dfcx_moves,
&mut dfcx_assign);

View file

@ -18,6 +18,7 @@ use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
use rustc::middle::expr_use_visitor::{LoanCause, MutateMode};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization::{cmt};
use rustc::middle::region::RegionMaps;
use rustc::session::Session;
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt};
@ -45,9 +46,13 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
b: hir::BodyId, s: Span, id: ast::NodeId) {
intravisit::walk_fn(self, fk, fd, b, s, id);
let region_context = self.tcx.hir.local_def_id(id);
let region_maps = self.tcx.region_maps(region_context);
MatchVisitor {
tcx: self.tcx,
tables: self.tcx.body_tables(b),
region_maps: &region_maps,
param_env: &ty::ParameterEnvironment::for_item(self.tcx, id)
}.visit_body(self.tcx.hir.body(b));
}
@ -65,7 +70,8 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn
struct MatchVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
param_env: &'a ty::ParameterEnvironment<'tcx>
param_env: &'a ty::ParameterEnvironment<'tcx>,
region_maps: &'a RegionMaps<'tcx>,
}
impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
@ -517,7 +523,7 @@ fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
let mut checker = MutationChecker {
cx: cx,
};
ExprUseVisitor::new(&mut checker, &infcx).walk_expr(guard);
ExprUseVisitor::new(&mut checker, cx.region_maps, &infcx).walk_expr(guard);
});
}
@ -533,7 +539,7 @@ impl<'a, 'gcx, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'gcx> {
_: ast::NodeId,
span: Span,
_: cmt,
_: &'tcx ty::Region,
_: ty::Region<'tcx>,
kind:ty:: BorrowKind,
_: LoanCause) {
match kind {

View file

@ -35,7 +35,7 @@ pub enum PatternError<'tcx> {
#[derive(Copy, Clone, Debug)]
pub enum BindingMode<'tcx> {
ByValue,
ByRef(&'tcx Region, BorrowKind),
ByRef(Region<'tcx>, BorrowKind),
}
#[derive(Clone, Debug)]
@ -811,7 +811,7 @@ macro_rules! CloneImpls {
}
CloneImpls!{ <'tcx>
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region,
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region<'tcx>,
Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>
}

View file

@ -24,7 +24,7 @@ use rustc_serialize as serialize;
///
/// (purpose: avoid mixing indexes for different bitvector domains.)
pub trait Idx: Copy + 'static + Eq + Debug {
fn new(usize) -> Self;
fn new(idx: usize) -> Self;
fn index(self) -> usize;
}

View file

@ -80,6 +80,27 @@ impl<T: Debug + PartialEq> TransitiveRelation<T> {
}
}
/// Applies the (partial) function to each edge and returns a new
/// relation. If `f` returns `None` for any end-point, returns
/// `None`.
pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelation<U>>
where F: FnMut(&T) -> Option<U>,
U: Debug + PartialEq,
{
let mut result = TransitiveRelation::new();
for edge in &self.edges {
let r = f(&self.elements[edge.source.0]).and_then(|source| {
f(&self.elements[edge.target.0]).and_then(|target| {
Some(result.add(source, target))
})
});
if r.is_none() {
return None;
}
}
Some(result)
}
/// Indicate that `a < b` (where `<` is this relation)
pub fn add(&mut self, a: T, b: T) {
let a = self.add_index(a);

View file

@ -874,10 +874,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
}));
sess.derive_registrar_fn.set(derive_registrar::find(&hir_map));
let region_map = time(time_passes,
"region resolution",
|| middle::region::resolve_crate(sess, &hir_map));
time(time_passes,
"loop checking",
|| loops::check_crate(sess, &hir_map));
@ -898,6 +894,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
ty::provide(&mut local_providers);
reachable::provide(&mut local_providers);
rustc_const_eval::provide(&mut local_providers);
middle::region::provide(&mut local_providers);
let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
@ -914,7 +911,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
resolutions,
named_region_map,
hir_map,
region_map,
lang_items,
index,
name,
@ -923,6 +919,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
time(time_passes,
"compute_incremental_hashes_map",
|| rustc_incremental::compute_incremental_hashes_map(tcx));
time(time_passes,
"load_dep_graph",
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));

View file

@ -343,7 +343,7 @@ pub trait CompilerCalls<'a> {
// Create a CompilController struct for controlling the behaviour of
// compilation.
fn build_controller(&mut self, &Session, &getopts::Matches) -> CompileController<'a>;
fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileController<'a>;
}
// CompilerCalls instance for a regular rustc build.

View file

@ -16,7 +16,7 @@ use rustc_lint;
use rustc_resolve::MakeGlobMap;
use rustc::middle::lang_items;
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::{self, CodeExtent};
use rustc::middle::region::{CodeExtent, RegionMaps};
use rustc::middle::region::CodeExtentData;
use rustc::middle::resolve_lifetime;
use rustc::middle::stability;
@ -44,6 +44,7 @@ use rustc::hir;
struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a mut RegionMaps<'tcx>,
}
struct RH<'a> {
@ -136,7 +137,6 @@ fn test_env<F>(source_string: &str,
// run just enough stuff to build a tcx:
let lang_items = lang_items::collect_language_items(&sess, &hir_map);
let named_region_map = resolve_lifetime::krate(&sess, &hir_map);
let region_map = region::resolve_crate(&sess, &hir_map);
let index = stability::Index::new(&hir_map);
TyCtxt::create_and_enter(&sess,
ty::maps::Providers::default(),
@ -146,16 +146,16 @@ fn test_env<F>(source_string: &str,
resolutions,
named_region_map.unwrap(),
hir_map,
region_map,
lang_items,
index,
"test_crate",
|tcx| {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
body(Env { infcx: &infcx });
let mut region_maps = RegionMaps::new();
body(Env { infcx: &infcx, region_maps: &mut region_maps });
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);
let def_id = tcx.hir.local_def_id(ast::CRATE_NODE_ID);
infcx.resolve_regions_and_report_errors(def_id, &region_maps, &free_regions);
assert_eq!(tcx.sess.err_count(), expected_err_count);
});
});
@ -166,23 +166,21 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
self.infcx.tcx
}
pub fn create_region_hierarchy(&self, rh: &RH, parent: CodeExtent) {
let me = self.infcx.tcx.region_maps.intern_node(rh.id, parent);
pub fn create_region_hierarchy(&mut self, rh: &RH, parent: CodeExtent<'tcx>) {
let me = self.tcx().intern_code_extent(CodeExtentData::Misc(rh.id));
self.region_maps.record_code_extent(me, Some(parent));
for child_rh in rh.sub {
self.create_region_hierarchy(child_rh, me);
}
}
pub fn create_simple_region_hierarchy(&self) {
pub fn create_simple_region_hierarchy(&mut self) {
// creates a region hierarchy where 1 is root, 10 and 11 are
// children of 1, etc
let node = ast::NodeId::from_u32;
let dscope = self.infcx
.tcx
.region_maps
.intern_code_extent(CodeExtentData::DestructionScope(node(1)),
region::ROOT_CODE_EXTENT);
let dscope = self.tcx().intern_code_extent(CodeExtentData::DestructionScope(node(1)));
self.region_maps.record_code_extent(dscope, None);
self.create_region_hierarchy(&RH {
id: node(1),
sub: &[RH {
@ -293,7 +291,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
self.infcx.tcx.mk_param(index, Symbol::intern(&name))
}
pub fn re_early_bound(&self, index: u32, name: &'static str) -> &'tcx ty::Region {
pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> {
let name = Symbol::intern(name);
self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
index: index,
@ -304,11 +302,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn re_late_bound_with_debruijn(&self,
id: u32,
debruijn: ty::DebruijnIndex)
-> &'tcx ty::Region {
-> ty::Region<'tcx> {
self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
}
pub fn t_rptr(&self, r: &'tcx ty::Region) -> Ty<'tcx> {
pub fn t_rptr(&self, r: ty::Region<'tcx>) -> Ty<'tcx> {
self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
}
@ -326,13 +324,13 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
}
pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> {
let r = ty::ReScope(self.tcx().region_maps.node_extent(ast::NodeId::from_u32(id)));
let r = ty::ReScope(self.tcx().node_extent(ast::NodeId::from_u32(id)));
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
}
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> &'tcx ty::Region {
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> {
self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: self.tcx().region_maps.item_extent(nid),
scope: Some(self.tcx().node_extent(nid)),
bound_region: ty::BrAnon(id),
}))
}
@ -430,7 +428,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
#[test]
fn contravariant_region_ptr_ok() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr1 = env.t_rptr_scope(1);
let t_rptr10 = env.t_rptr_scope(10);
@ -442,7 +440,7 @@ fn contravariant_region_ptr_ok() {
#[test]
fn contravariant_region_ptr_err() {
test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr1 = env.t_rptr_scope(1);
let t_rptr10 = env.t_rptr_scope(10);
@ -462,7 +460,7 @@ fn sub_free_bound_false() {
//!
//! does NOT hold.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_bound1 = env.t_rptr_late_bound(1);
@ -479,7 +477,7 @@ fn sub_bound_free_true() {
//!
//! DOES hold.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
@ -514,7 +512,7 @@ fn lub_free_bound_infer() {
//! that it yields `fn(&'x isize)` for some free `'x`,
//! anyhow.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP));
let t_rptr_bound1 = env.t_rptr_late_bound(1);
@ -538,7 +536,7 @@ fn lub_bound_bound() {
#[test]
fn lub_bound_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
@ -572,7 +570,7 @@ fn lub_bound_bound_inverse_order() {
#[test]
fn lub_free_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_free2 = env.t_rptr_free(1, 2);
@ -585,7 +583,7 @@ fn lub_free_free() {
#[test]
fn lub_returning_scope() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_scope10 = env.t_rptr_scope(10);
let t_rptr_scope11 = env.t_rptr_scope(11);
@ -598,7 +596,7 @@ fn lub_returning_scope() {
#[test]
fn glb_free_free_with_common_scope() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_free2 = env.t_rptr_free(1, 2);
@ -622,7 +620,7 @@ fn glb_bound_bound() {
#[test]
fn glb_bound_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
@ -744,7 +742,7 @@ fn subst_ty_renumber_some_bounds() {
#[test]
fn escaping() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
// Situation:
// Theta = [A -> &'a foo]
env.create_simple_region_hierarchy();

View file

@ -45,6 +45,7 @@ use syntax::ast;
use syntax::attr;
use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
use syntax_pos::Span;
use syntax::symbol::keywords;
use rustc::hir::{self, PatKind};
use rustc::hir::intravisit::FnKind;
@ -605,6 +606,44 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
}
}
declare_lint! {
pub ANONYMOUS_PARAMETERS,
Allow,
"detects anonymous parameters"
}
/// Checks for use of anonymous parameters (RFC 1685)
#[derive(Clone)]
pub struct AnonymousParameters;
impl LintPass for AnonymousParameters {
fn get_lints(&self) -> LintArray {
lint_array!(ANONYMOUS_PARAMETERS)
}
}
impl EarlyLintPass for AnonymousParameters {
fn check_trait_item(&mut self, cx: &EarlyContext, it: &ast::TraitItem) {
match it.node {
ast::TraitItemKind::Method(ref sig, _) => {
for arg in sig.decl.inputs.iter() {
match arg.pat.node {
ast::PatKind::Ident(_, ident, None) => {
if ident.node.name == keywords::Invalid.name() {
cx.span_lint(ANONYMOUS_PARAMETERS,
arg.pat.span,
"use of deprecated anonymous parameter");
}
}
_ => (),
}
}
},
_ => (),
}
}
}
declare_lint! {
DEPRECATED_ATTR,
Warn,

View file

@ -112,6 +112,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
add_early_builtin!(sess,
UnusedParens,
UnusedImportBraces,
AnonymousParameters,
);
add_early_builtin_with_new!(sess,
@ -244,6 +245,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
},
FutureIncompatibleInfo {
id: LintId::of(ANONYMOUS_PARAMETERS),
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
},
]);
// Register renamed and removed lints

View file

@ -20,6 +20,7 @@ use rustc::middle::cstore::LinkagePreference;
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::middle::lang_items;
use rustc::middle::region;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
@ -351,12 +352,18 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx
}
}
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::Region, Self::Error> {
impl<'a, 'tcx> SpecializedDecoder<ty::Region<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<ty::Region<'tcx>, Self::Error> {
Ok(self.tcx().mk_region(Decodable::decode(self)?))
}
}
impl<'a, 'tcx> SpecializedDecoder<region::CodeExtent<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<region::CodeExtent<'tcx>, Self::Error> {
Ok(self.tcx().intern_code_extent(Decodable::decode(self)?))
}
}
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)

View file

@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let_extent_stack.push(remainder_scope);
// Declare the bindings, which may create a visibility scope.
let remainder_span = remainder_scope.span(&tcx.region_maps, &tcx.hir);
let remainder_span = remainder_scope.span(&tcx.hir);
let remainder_span = remainder_span.unwrap_or(span);
let scope = this.declare_bindings(None, remainder_span, &pattern);

View file

@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// The operand is known to be live until the end of `scope`.
pub fn as_operand<M>(&mut self,
block: BasicBlock,
scope: Option<CodeExtent>,
scope: Option<CodeExtent<'tcx>>,
expr: M) -> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
@ -49,7 +49,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn expr_as_operand(&mut self,
mut block: BasicBlock,
scope: Option<CodeExtent>,
scope: Option<CodeExtent<'tcx>>,
expr: Expr<'tcx>)
-> BlockAnd<Operand<'tcx>> {
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);

View file

@ -38,7 +38,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
/// Compile `expr`, yielding an rvalue.
pub fn as_rvalue<M>(&mut self, block: BasicBlock, scope: Option<CodeExtent>, expr: M)
pub fn as_rvalue<M>(&mut self, block: BasicBlock, scope: Option<CodeExtent<'tcx>>, expr: M)
-> BlockAnd<Rvalue<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
@ -48,7 +48,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn expr_as_rvalue(&mut self,
mut block: BasicBlock,
scope: Option<CodeExtent>,
scope: Option<CodeExtent<'tcx>>,
expr: Expr<'tcx>)
-> BlockAnd<Rvalue<'tcx>> {
debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);

View file

@ -21,7 +21,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// up rvalues so as to freeze the value that will be consumed.
pub fn as_temp<M>(&mut self,
block: BasicBlock,
temp_lifetime: Option<CodeExtent>,
temp_lifetime: Option<CodeExtent<'tcx>>,
expr: M)
-> BlockAnd<Lvalue<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
@ -32,7 +32,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn expr_as_temp(&mut self,
mut block: BasicBlock,
temp_lifetime: Option<CodeExtent>,
temp_lifetime: Option<CodeExtent<'tcx>>,
expr: Expr<'tcx>)
-> BlockAnd<Lvalue<'tcx>> {
debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);

View file

@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span) {
let local_id = self.var_indices[&var];
let var_ty = self.local_decls[local_id].ty;
let extent = self.hir.tcx().region_maps.var_scope(var);
let extent = self.hir.region_maps.var_scope(var);
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
}

View file

@ -11,7 +11,7 @@
use hair::cx::Cx;
use hair::Pattern;
use rustc::middle::region::{CodeExtent, CodeExtentData, ROOT_CODE_EXTENT};
use rustc::middle::region::{CodeExtent, CodeExtentData};
use rustc::ty::{self, Ty};
use rustc::mir::*;
use rustc::util::nodemap::NodeMap;
@ -134,13 +134,13 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
let tcx = hir.tcx();
let span = tcx.hir.span(fn_id);
let mut builder = Builder::new(hir, span, arguments.len(), return_ty);
let mut builder = Builder::new(hir.clone(), span, arguments.len(), return_ty);
let call_site_extent =
tcx.region_maps.lookup_code_extent(
tcx.intern_code_extent(
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id });
let arg_extent =
tcx.region_maps.lookup_code_extent(
tcx.intern_code_extent(
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id });
let mut block = START_BLOCK;
unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
@ -200,11 +200,12 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
let tcx = hir.tcx();
let ast_expr = &tcx.hir.body(body_id).value;
let ty = hir.tables().expr_ty_adjusted(ast_expr);
let span = tcx.hir.span(tcx.hir.body_owner(body_id));
let mut builder = Builder::new(hir, span, 0, ty);
let owner_id = tcx.hir.body_owner(body_id);
let span = tcx.hir.span(owner_id);
let mut builder = Builder::new(hir.clone(), span, 0, ty);
let extent = tcx.region_maps.temporary_scope(ast_expr.id)
.unwrap_or(ROOT_CODE_EXTENT);
let extent = hir.region_maps.temporary_scope(tcx, ast_expr.id)
.unwrap_or(tcx.item_extent(owner_id));
let mut block = START_BLOCK;
let _ = builder.in_scope(extent, block, |builder| {
let expr = builder.hir.mirror(ast_expr);
@ -288,7 +289,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn args_and_body(&mut self,
mut block: BasicBlock,
arguments: &[(Ty<'gcx>, Option<&'gcx hir::Pat>)],
argument_extent: CodeExtent,
argument_extent: CodeExtent<'tcx>,
ast_body: &'gcx hir::Expr)
-> BlockAnd<()>
{

View file

@ -102,7 +102,7 @@ pub struct Scope<'tcx> {
visibility_scope: VisibilityScope,
/// the extent of this scope within source code.
extent: CodeExtent,
extent: CodeExtent<'tcx>,
/// Whether there's anything to do for the cleanup path, that is,
/// when unwinding through this scope. This includes destructors,
@ -137,7 +137,7 @@ pub struct Scope<'tcx> {
free: Option<FreeData<'tcx>>,
/// The cache for drop chain on “normal” exit into a particular BasicBlock.
cached_exits: FxHashMap<(BasicBlock, CodeExtent), BasicBlock>,
cached_exits: FxHashMap<(BasicBlock, CodeExtent<'tcx>), BasicBlock>,
}
struct DropData<'tcx> {
@ -180,7 +180,7 @@ struct FreeData<'tcx> {
#[derive(Clone, Debug)]
pub struct BreakableScope<'tcx> {
/// Extent of the loop
pub extent: CodeExtent,
pub extent: CodeExtent<'tcx>,
/// Where the body of the loop begins. `None` if block
pub continue_block: Option<BasicBlock>,
/// Block to branch into when the loop or block terminates (either by being `break`-en out
@ -248,10 +248,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
///
/// Returns the might_break attribute of the BreakableScope used.
pub fn in_breakable_scope<F, R>(&mut self,
loop_block: Option<BasicBlock>,
break_block: BasicBlock,
break_destination: Lvalue<'tcx>,
f: F) -> R
loop_block: Option<BasicBlock>,
break_block: BasicBlock,
break_destination: Lvalue<'tcx>,
f: F) -> R
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R
{
let extent = self.topmost_scope();
@ -270,7 +270,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Convenience wrapper that pushes a scope and then executes `f`
/// to build its contents, popping the scope afterwards.
pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F) -> BlockAnd<R>
pub fn in_scope<F, R>(&mut self,
extent: CodeExtent<'tcx>,
mut block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
{
debug!("in_scope(extent={:?}, block={:?})", extent, block);
@ -285,7 +289,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// scope and call `pop_scope` afterwards. Note that these two
/// calls must be paired; using `in_scope` as a convenience
/// wrapper maybe preferable.
pub fn push_scope(&mut self, extent: CodeExtent) {
pub fn push_scope(&mut self, extent: CodeExtent<'tcx>) {
debug!("push_scope({:?})", extent);
let vis_scope = self.visibility_scope;
self.scopes.push(Scope {
@ -302,7 +306,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// drops onto the end of `block` that are needed. This must
/// match 1-to-1 with `push_scope`.
pub fn pop_scope(&mut self,
extent: CodeExtent,
extent: CodeExtent<'tcx>,
mut block: BasicBlock)
-> BlockAnd<()> {
debug!("pop_scope({:?}, {:?})", extent, block);
@ -326,7 +330,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// module comment for details.
pub fn exit_scope(&mut self,
span: Span,
extent: CodeExtent,
extent: CodeExtent<'tcx>,
mut block: BasicBlock,
target: BasicBlock) {
debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target);
@ -387,7 +391,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// resolving `break` and `continue`.
pub fn find_breakable_scope(&mut self,
span: Span,
label: CodeExtent)
label: CodeExtent<'tcx>)
-> &mut BreakableScope<'tcx> {
// find the loop-scope with the correct id
self.breakable_scopes.iter_mut()
@ -407,11 +411,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Returns the extent of the scope which should be exited by a
/// return.
pub fn extent_of_return_scope(&self) -> CodeExtent {
pub fn extent_of_return_scope(&self) -> CodeExtent<'tcx> {
// The outermost scope (`scopes[0]`) will be the `CallSiteScope`.
// We want `scopes[1]`, which is the `ParameterScope`.
assert!(self.scopes.len() >= 2);
assert!(match self.hir.tcx().region_maps.code_extent_data(self.scopes[1].extent) {
assert!(match *self.scopes[1].extent {
CodeExtentData::ParameterScope { .. } => true,
_ => false,
});
@ -420,7 +424,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Returns the topmost active scope, which is known to be alive until
/// the next scope expression.
pub fn topmost_scope(&self) -> CodeExtent {
pub fn topmost_scope(&self) -> CodeExtent<'tcx> {
self.scopes.last().expect("topmost_scope: no scopes present").extent
}
@ -430,7 +434,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// `extent`.
pub fn schedule_drop(&mut self,
span: Span,
extent: CodeExtent,
extent: CodeExtent<'tcx>,
lvalue: &Lvalue<'tcx>,
lvalue_ty: Ty<'tcx>) {
let needs_drop = self.hir.needs_drop(lvalue_ty);
@ -499,7 +503,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
scope.needs_cleanup = true;
}
let tcx = self.hir.tcx();
let extent_span = extent.span(&tcx.region_maps, &tcx.hir).unwrap();
let extent_span = extent.span(&tcx.hir).unwrap();
// Attribute scope exit drops to scope's closing brace
let scope_end = Span { lo: extent_span.hi, .. extent_span};
scope.drops.push(DropData {
@ -520,7 +524,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// There may only be one “free” scheduled in any given scope.
pub fn schedule_box_free(&mut self,
span: Span,
extent: CodeExtent,
extent: CodeExtent<'tcx>,
value: &Lvalue<'tcx>,
item_ty: Ty<'tcx>) {
for scope in self.scopes.iter_mut().rev() {

View file

@ -24,7 +24,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
let stmts = mirror_stmts(cx, self.id, &*self.stmts);
Block {
targeted_by_break: self.targeted_by_break,
extent: cx.tcx.region_maps.node_extent(self.id),
extent: cx.tcx.node_extent(self.id),
span: self.span,
stmts: stmts,
expr: self.expr.to_ref(),
@ -44,7 +44,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
result.push(StmtRef::Mirror(Box::new(Stmt {
span: stmt.span,
kind: StmtKind::Expr {
scope: cx.tcx.region_maps.node_extent(id),
scope: cx.tcx.node_extent(id),
expr: expr.to_ref(),
},
})))
@ -60,14 +60,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
first_statement_index: index as u32,
});
let remainder_extent =
cx.tcx.region_maps.lookup_code_extent(remainder_extent);
cx.tcx.intern_code_extent(remainder_extent);
let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat);
result.push(StmtRef::Mirror(Box::new(Stmt {
span: stmt.span,
kind: StmtKind::Let {
remainder_scope: remainder_extent,
init_scope: cx.tcx.region_maps.node_extent(id),
init_scope: cx.tcx.node_extent(id),
pattern: pattern,
initializer: local.init.to_ref(),
},
@ -84,7 +84,7 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
block: &'tcx hir::Block)
-> ExprRef<'tcx> {
let block_ty = cx.tables().node_id_to_type(block.id);
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(block.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, block.id);
let expr = Expr {
ty: block_ty,
temp_lifetime: temp_lifetime,

View file

@ -26,8 +26,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
type Output = Expr<'tcx>;
fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(self.id);
let expr_extent = cx.tcx.region_maps.node_extent(self.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, self.id);
let expr_extent = cx.tcx.node_extent(self.id);
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
@ -216,7 +216,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
};
// Finally, create a destruction scope, if any.
if let Some(extent) = cx.tcx.region_maps.opt_destruction_extent(self.id) {
if let Some(extent) = cx.region_maps.opt_destruction_extent(self.id) {
expr = Expr {
temp_lifetime: temp_lifetime,
temp_lifetime_was_shrunk: was_shrunk,
@ -238,7 +238,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &'tcx hir::Expr)
-> Expr<'tcx> {
let expr_ty = cx.tables().expr_ty(expr);
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id);
let kind = match expr.node {
// Here comes the interesting stuff:
@ -610,7 +610,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
match dest.target_id {
hir::ScopeTarget::Block(target_id) |
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break {
label: cx.tcx.region_maps.node_extent(target_id),
label: cx.tcx.node_extent(target_id),
value: value.to_ref(),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
@ -621,7 +621,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
match dest.target_id {
hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"),
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue {
label: cx.tcx.region_maps.node_extent(loop_id),
label: cx.tcx.node_extent(loop_id),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
bug!("invalid loop id for continue: {}", err)
@ -686,7 +686,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
hir::ExprBox(ref value) => {
ExprKind::Box {
value: value.to_ref(),
value_extents: cx.tcx.region_maps.node_extent(value.id),
value_extents: cx.tcx.node_extent(value.id),
}
}
hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() },
@ -707,7 +707,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
method_call: ty::MethodCall)
-> Expr<'tcx> {
let callee = cx.tables().method_map[&method_call];
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id);
Expr {
temp_lifetime: temp_lifetime,
temp_lifetime_was_shrunk: was_shrunk,
@ -791,7 +791,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &'tcx hir::Expr,
def: Def)
-> ExprKind<'tcx> {
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id);
match def {
Def::Local(def_id) => {
@ -827,8 +827,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// FIXME we're just hard-coding the idea that the
// signature will be &self or &mut self and hence will
// have a bound region with number 0
let region = ty::Region::ReFree(ty::FreeRegion {
scope: cx.tcx.region_maps.node_extent(body_id),
let region = ty::ReFree(ty::FreeRegion {
scope: Some(cx.tcx.node_extent(body_id)),
bound_region: ty::BoundRegion::BrAnon(0),
});
let region = cx.tcx.mk_region(region);
@ -979,7 +979,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
PassArgs::ByRef => {
let region = cx.tcx.node_scope_region(expr.id);
let (temp_lifetime, was_shrunk) =
cx.tcx.region_maps.temporary_scope2(expr.id);
cx.region_maps.temporary_scope2(cx.tcx, expr.id);
argrefs.extend(args.iter()
.map(|arg| {
let arg_ty = cx.tables().expr_ty_adjusted(arg);
@ -1031,7 +1031,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// construct the complete expression `foo()` for the overloaded call,
// which will yield the &T type
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id);
let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args);
let ref_expr = Expr {
temp_lifetime: temp_lifetime,
@ -1056,7 +1056,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
closure_expr_id: closure_expr.id,
};
let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap();
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(closure_expr.id);
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, closure_expr.id);
let var_ty = cx.tables().node_id_to_type(id_var);
let captured_var = Expr {
temp_lifetime: temp_lifetime,

View file

@ -22,17 +22,20 @@ use rustc_const_eval::ConstContext;
use rustc_data_structures::indexed_vec::Idx;
use rustc::hir::def_id::DefId;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::middle::region::RegionMaps;
use rustc::infer::InferCtxt;
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt};
use syntax::symbol::{Symbol, InternedString};
use rustc::hir;
use rustc_const_math::{ConstInt, ConstUsize};
use std::rc::Rc;
#[derive(Copy, Clone)]
#[derive(Clone)]
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
pub region_maps: Rc<RegionMaps<'tcx>>,
constness: hir::Constness,
/// True if this constant/function needs overflow checks.
@ -51,7 +54,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
MirSource::Promoted(..) => bug!(),
};
let attrs = infcx.tcx.hir.attrs(src.item_id());
let tcx = infcx.tcx;
let src_id = src.item_id();
let src_def_id = tcx.hir.local_def_id(src_id);
let region_maps = tcx.region_maps(src_def_id);
let attrs = tcx.hir.attrs(src_id);
// Some functions always have overflow checks enabled,
// however, they may not get codegen'd, depending on
@ -60,17 +69,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
.any(|item| item.check_name("rustc_inherit_overflow_checks"));
// Respect -C overflow-checks.
check_overflow |= infcx.tcx.sess.overflow_checks();
check_overflow |= tcx.sess.overflow_checks();
// Constants and const fn's always need overflow checks.
check_overflow |= constness == hir::Constness::Const;
Cx {
tcx: infcx.tcx,
infcx: infcx,
constness: constness,
check_overflow: check_overflow,
}
Cx { tcx, infcx, region_maps, constness, check_overflow }
}
}

View file

@ -32,7 +32,7 @@ pub use rustc_const_eval::pattern::{BindingMode, Pattern, PatternKind, FieldPatt
#[derive(Clone, Debug)]
pub struct Block<'tcx> {
pub targeted_by_break: bool,
pub extent: CodeExtent,
pub extent: CodeExtent<'tcx>,
pub span: Span,
pub stmts: Vec<StmtRef<'tcx>>,
pub expr: Option<ExprRef<'tcx>>,
@ -53,7 +53,7 @@ pub struct Stmt<'tcx> {
pub enum StmtKind<'tcx> {
Expr {
/// scope for this statement; may be used as lifetime of temporaries
scope: CodeExtent,
scope: CodeExtent<'tcx>,
/// expression being evaluated in this statement
expr: ExprRef<'tcx>,
@ -62,11 +62,11 @@ pub enum StmtKind<'tcx> {
Let {
/// scope for variables bound in this let; covers this and
/// remaining statements in block
remainder_scope: CodeExtent,
remainder_scope: CodeExtent<'tcx>,
/// scope for the initialization itself; might be used as
/// lifetime of temporaries
init_scope: CodeExtent,
init_scope: CodeExtent<'tcx>,
/// let <PAT> = ...
pattern: Pattern<'tcx>,
@ -97,7 +97,7 @@ pub struct Expr<'tcx> {
/// lifetime of this expression if it should be spilled into a
/// temporary; should be None only if in a constant context
pub temp_lifetime: Option<CodeExtent>,
pub temp_lifetime: Option<CodeExtent<'tcx>>,
/// whether this temp lifetime was shrunk by #36082.
pub temp_lifetime_was_shrunk: bool,
@ -112,12 +112,12 @@ pub struct Expr<'tcx> {
#[derive(Clone, Debug)]
pub enum ExprKind<'tcx> {
Scope {
extent: CodeExtent,
extent: CodeExtent<'tcx>,
value: ExprRef<'tcx>,
},
Box {
value: ExprRef<'tcx>,
value_extents: CodeExtent,
value_extents: CodeExtent<'tcx>,
},
Call {
ty: ty::Ty<'tcx>,
@ -205,16 +205,16 @@ pub enum ExprKind<'tcx> {
id: DefId,
},
Borrow {
region: &'tcx Region,
region: Region<'tcx>,
borrow_kind: BorrowKind,
arg: ExprRef<'tcx>,
},
Break {
label: CodeExtent,
label: CodeExtent<'tcx>,
value: Option<ExprRef<'tcx>>,
},
Continue {
label: CodeExtent,
label: CodeExtent<'tcx>,
},
Return {
value: Option<ExprRef<'tcx>>,

View file

@ -252,8 +252,8 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-> Ty<'tcx> {
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
let region = ty::Region::ReFree(ty::FreeRegion {
scope: tcx.region_maps.item_extent(body_id.node_id),
let region = ty::ReFree(ty::FreeRegion {
scope: Some(tcx.item_extent(body_id.node_id)),
bound_region: ty::BoundRegion::BrEnv,
});
let region = tcx.mk_region(region);

View file

@ -11,7 +11,6 @@
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::infer;
use rustc::middle::region::ROOT_CODE_EXTENT;
use rustc::middle::const_val::ConstVal;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
@ -45,8 +44,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
debug!("make_shim({:?})", instance);
let did = instance.def_id();
let span = tcx.def_span(did);
let param_env =
tcx.construct_parameter_environment(span, did, ROOT_CODE_EXTENT);
let param_env = tcx.construct_parameter_environment(span, did, None);
let mut result = match instance {
ty::InstanceDef::Item(..) =>

View file

@ -130,7 +130,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
};
let outer_tables = self.tables;
self.tables = self.tcx.typeck_tables_of(self.tcx.hir.local_def_id(item_id));
let item_def_id = self.tcx.hir.local_def_id(item_id);
self.tables = self.tcx.typeck_tables_of(item_def_id);
let body = self.tcx.hir.body(body_id);
if !self.in_fn {
@ -140,7 +141,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
let param_env = infcx.parameter_environment.clone();
let outer_penv = mem::replace(&mut self.param_env, param_env);
euv::ExprUseVisitor::new(self, &infcx).consume_body(body);
let region_maps = &self.tcx.region_maps(item_def_id);;
euv::ExprUseVisitor::new(self, region_maps, &infcx).consume_body(body);
outer_penv
});
@ -480,7 +482,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> {
borrow_id: ast::NodeId,
_borrow_span: Span,
cmt: mc::cmt<'tcx>,
_loan_region: &'tcx ty::Region,
_loan_region: ty::Region<'tcx>,
bk: ty::BorrowKind,
loan_cause: euv::LoanCause) {
// Kind of hacky, but we allow Unsafe coercions in constants.

View file

@ -13,28 +13,28 @@ use super::external_data::*;
use rls_data::CratePreludeData;
pub trait Dump {
fn crate_prelude(&mut self, CratePreludeData) {}
fn enum_data(&mut self, EnumData) {}
fn extern_crate(&mut self, ExternCrateData) {}
fn impl_data(&mut self, ImplData) {}
fn inheritance(&mut self, InheritanceData) {}
fn function(&mut self, FunctionData) {}
fn function_ref(&mut self, FunctionRefData) {}
fn function_call(&mut self, FunctionCallData) {}
fn method(&mut self, MethodData) {}
fn method_call(&mut self, MethodCallData) {}
fn macro_data(&mut self, MacroData) {}
fn macro_use(&mut self, MacroUseData) {}
fn mod_data(&mut self, ModData) {}
fn mod_ref(&mut self, ModRefData) {}
fn struct_data(&mut self, StructData) {}
fn struct_variant(&mut self, StructVariantData) {}
fn trait_data(&mut self, TraitData) {}
fn tuple_variant(&mut self, TupleVariantData) {}
fn type_ref(&mut self, TypeRefData) {}
fn typedef(&mut self, TypeDefData) {}
fn use_data(&mut self, UseData) {}
fn use_glob(&mut self, UseGlobData) {}
fn variable(&mut self, VariableData) {}
fn variable_ref(&mut self, VariableRefData) {}
fn crate_prelude(&mut self, _: CratePreludeData) {}
fn enum_data(&mut self, _: EnumData) {}
fn extern_crate(&mut self, _: ExternCrateData) {}
fn impl_data(&mut self, _: ImplData) {}
fn inheritance(&mut self, _: InheritanceData) {}
fn function(&mut self, _: FunctionData) {}
fn function_ref(&mut self, _: FunctionRefData) {}
fn function_call(&mut self, _: FunctionCallData) {}
fn method(&mut self, _: MethodData) {}
fn method_call(&mut self, _: MethodCallData) {}
fn macro_data(&mut self, _: MacroData) {}
fn macro_use(&mut self, _: MacroUseData) {}
fn mod_data(&mut self, _: ModData) {}
fn mod_ref(&mut self, _: ModRefData) {}
fn struct_data(&mut self, _: StructData) {}
fn struct_variant(&mut self, _: StructVariantData) {}
fn trait_data(&mut self, _: TraitData) {}
fn tuple_variant(&mut self, _: TupleVariantData) {}
fn type_ref(&mut self, _: TypeRefData) {}
fn typedef(&mut self, _: TypeDefData) {}
fn use_data(&mut self, _: UseData) {}
fn use_glob(&mut self, _: UseGlobData) {}
fn variable(&mut self, _: VariableData) {}
fn variable_ref(&mut self, _: VariableRefData) {}
}

View file

@ -53,7 +53,7 @@ pub trait AstConv<'gcx, 'tcx> {
/// What lifetime should we use when a lifetime is omitted (and not elided)?
fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
-> Option<&'tcx ty::Region>;
-> Option<ty::Region<'tcx>>;
/// What type should we use when a type is omitted?
fn ty_infer(&self, span: Span) -> Ty<'tcx>;
@ -104,7 +104,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
pub fn ast_region_to_region(&self,
lifetime: &hir::Lifetime,
def: Option<&ty::RegionParameterDef>)
-> &'tcx ty::Region
-> ty::Region<'tcx>
{
let tcx = self.tcx();
let r = match tcx.named_region_map.defs.get(&lifetime.id) {
@ -133,7 +133,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
Some(&rl::Region::Free(scope, id)) => {
let name = tcx.hir.name(id);
tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: scope.to_code_extent(&tcx.region_maps),
scope: Some(scope.to_code_extent(tcx)),
bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name)
}))
@ -1342,7 +1342,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
fn compute_object_lifetime_bound(&self,
span: Span,
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
-> Option<&'tcx ty::Region> // if None, use the default
-> Option<ty::Region<'tcx>> // if None, use the default
{
let tcx = self.tcx();
@ -1489,7 +1489,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
// and return from functions in multiple places.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Bounds<'tcx> {
pub region_bounds: Vec<&'tcx ty::Region>,
pub region_bounds: Vec<ty::Region<'tcx>>,
pub implicitly_sized: bool,
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
@ -1533,7 +1533,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
pub enum ExplicitSelf<'tcx> {
ByValue,
ByReference(&'tcx ty::Region, hir::Mutability),
ByReference(ty::Region<'tcx>, hir::Mutability),
ByBox
}

View file

@ -73,8 +73,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
let extent = self.tcx.region_maps.call_site_extent(expr.id, body.value.id);
let fn_sig = self.tcx.liberate_late_bound_regions(extent, &sig);
let extent = self.tcx.call_site_extent(expr.id, body.value.id);
let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig);
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
body.value.id, &fn_sig);

View file

@ -250,7 +250,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
exprs: &[E],
a: Ty<'tcx>,
b: Ty<'tcx>,
r_b: &'tcx ty::Region,
r_b: ty::Region<'tcx>,
mt_b: TypeAndMut<'tcx>)
-> CoerceResult<'tcx>
where E: AsCoercionSite

View file

@ -11,13 +11,13 @@
use rustc::hir::{self, ImplItemKind, TraitItemKind};
use rustc::infer::{self, InferOk};
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::RegionMaps;
use rustc::ty::{self, TyCtxt};
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
use rustc::ty::error::{ExpectedFound, TypeError};
use rustc::ty::subst::{Subst, Substs};
use rustc::util::common::ErrorReported;
use syntax::ast;
use syntax_pos::Span;
use super::{Inherited, FnCtxt};
@ -30,14 +30,12 @@ use astconv::ExplicitSelf;
///
/// - impl_m: type of the method we are checking
/// - impl_m_span: span to use for reporting errors
/// - impl_m_body_id: id of the method body
/// - trait_m: the method in the trait
/// - impl_trait_ref: the TraitRef corresponding to the trait implementation
pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_m: &ty::AssociatedItem,
impl_m_span: Span,
impl_m_body_id: ast::NodeId,
trait_m: &ty::AssociatedItem,
impl_trait_ref: ty::TraitRef<'tcx>,
trait_item_span: Option<Span>,
@ -72,7 +70,6 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Err(ErrorReported) = compare_predicate_entailment(tcx,
impl_m,
impl_m_span,
impl_m_body_id,
trait_m,
impl_trait_ref,
old_broken_mode) {
@ -83,21 +80,25 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_m: &ty::AssociatedItem,
impl_m_span: Span,
impl_m_body_id: ast::NodeId,
trait_m: &ty::AssociatedItem,
impl_trait_ref: ty::TraitRef<'tcx>,
old_broken_mode: bool)
-> Result<(), ErrorReported> {
let trait_to_impl_substs = impl_trait_ref.substs;
// This node-id should be used for the `body_id` field on each
// `ObligationCause` (and the `FnCtxt`). This is what
// `regionck_item` expects.
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
let cause = ObligationCause {
span: impl_m_span,
body_id: impl_m_body_id,
body_id: impl_m_node_id,
code: ObligationCauseCode::CompareImplMethodObligation {
item_name: impl_m.name,
impl_item_def_id: impl_m.def_id,
trait_item_def_id: trait_m.def_id,
lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None },
lint_id: if !old_broken_mode { Some(impl_m_node_id) } else { None },
},
};
@ -166,7 +167,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Create a parameter environment that represents the implementation's
// method.
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id);
// Create mapping from impl to skolemized.
@ -217,9 +217,10 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Construct trait parameter environment and then shift it into the skolemized viewpoint.
// The key step here is to update the caller_bounds's predicates to be
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_body_id);
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.predicates);
let trait_param_env = traits::normalize_param_env_or_error(tcx,
impl_m.def_id,
trait_param_env,
normalize_cause.clone());
@ -275,7 +276,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_sig.subst(tcx, impl_to_skol_substs);
let impl_sig =
inh.normalize_associated_types_in(impl_m_span,
impl_m_body_id,
impl_m_node_id,
&impl_sig);
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
@ -287,7 +288,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_sig.subst(tcx, trait_to_skol_substs);
let trait_sig =
inh.normalize_associated_types_in(impl_m_span,
impl_m_body_id,
impl_m_node_id,
&trait_sig);
let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig));
@ -349,13 +350,14 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// region obligations that get overlooked. The right
// thing to do is the code below. But we keep this old
// pass around temporarily.
let region_maps = RegionMaps::new();
let mut free_regions = FreeRegionMap::new();
free_regions.relate_free_regions_from_predicates(
&infcx.parameter_environment.caller_bounds);
infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
infcx.resolve_regions_and_report_errors(impl_m.def_id, &region_maps, &free_regions);
} else {
let fcx = FnCtxt::new(&inh, impl_m_body_id);
fcx.regionck_item(impl_m_body_id, impl_m_span, &[]);
let fcx = FnCtxt::new(&inh, impl_m_node_id);
fcx.regionck_item(impl_m_node_id, impl_m_span, &[]);
}
Ok(())

View file

@ -13,7 +13,7 @@ use check::regionck::RegionCtxt;
use hir::def_id::DefId;
use middle::free_region::FreeRegionMap;
use rustc::infer::{self, InferOk};
use middle::region;
use rustc::middle::region::{self, RegionMaps};
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::traits::{self, ObligationCause, Reveal};
@ -116,8 +116,9 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
return Err(ErrorReported);
}
let region_maps = RegionMaps::new();
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(&free_regions, drop_impl_node_id);
infcx.resolve_regions_and_report_errors(drop_impl_did, &region_maps, &free_regions);
Ok(())
})
}
@ -271,14 +272,14 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>,
ty: ty::Ty<'tcx>,
span: Span,
scope: region::CodeExtent)
scope: region::CodeExtent<'tcx>)
-> Result<(), ErrorReported>
{
debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
ty, scope);
let parent_scope = match rcx.tcx.region_maps.opt_encl_scope(scope) {
let parent_scope = match rcx.region_maps.opt_encl_scope(scope) {
Some(parent_scope) => parent_scope,
// If no enclosing scope, then it must be the root scope
// which cannot be outlived.

View file

@ -781,11 +781,11 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
check_abi(tcx, span, fn_sig.abi());
// Compute the fty from point of view of inside fn.
let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id);
let fn_scope = inh.tcx.call_site_extent(id, body_id.node_id);
let fn_sig =
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
let fn_sig =
inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
inh.tcx.liberate_late_bound_regions(Some(fn_scope), &fn_sig);
let fn_sig =
inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig);
@ -1237,14 +1237,13 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
err.emit()
}
}
hir::ImplItemKind::Method(_, body_id) => {
hir::ImplItemKind::Method(..) => {
let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id);
if ty_trait_item.kind == ty::AssociatedKind::Method {
let err_count = tcx.sess.err_count();
compare_impl_method(tcx,
&ty_impl_item,
impl_item.span,
body_id.node_id,
&ty_trait_item,
impl_trait_ref,
trait_span,
@ -1254,7 +1253,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
compare_impl_method(tcx,
&ty_impl_item,
impl_item.span,
body_id.node_id,
&ty_trait_item,
impl_trait_ref,
trait_span,
@ -1549,7 +1547,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
}
fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
-> Option<&'tcx ty::Region> {
-> Option<ty::Region<'tcx>> {
let v = match def {
Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
None => infer::MiscVariable(span)
@ -1963,7 +1961,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
/// outlive the region `r`.
pub fn register_region_obligation(&self,
ty: Ty<'tcx>,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
cause: traits::ObligationCause<'tcx>)
{
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();

View file

@ -87,7 +87,8 @@ use check::FnCtxt;
use middle::free_region::FreeRegionMap;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::region::{self, CodeExtent};
use middle::region::{self, CodeExtent, RegionMaps};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
use rustc::traits;
use rustc::ty::{self, Ty, MethodCall, TypeFoldable};
@ -97,6 +98,7 @@ use rustc::ty::wf::ImpliedBound;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use syntax::ast;
use syntax_pos::Span;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
@ -112,8 +114,9 @@ macro_rules! ignore_err {
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn regionck_expr(&self, body: &'gcx hir::Body) {
let subject = self.tcx.hir.body_owner_def_id(body.id());
let id = body.value.id;
let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(id));
let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(subject));
if self.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded
rcx.visit_body(body);
@ -132,7 +135,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
span: Span,
wf_tys: &[Ty<'tcx>]) {
debug!("regionck_item(item.id={:?}, wf_tys={:?}", item_id, wf_tys);
let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(item_id));
let subject = self.tcx.hir.local_def_id(item_id);
let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(subject));
rcx.free_region_map.relate_free_regions_from_predicates(
&self.parameter_environment.caller_bounds);
rcx.relate_free_regions(wf_tys, item_id, span);
@ -144,8 +148,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_id: ast::NodeId,
body: &'gcx hir::Body) {
debug!("regionck_fn(id={})", fn_id);
let subject = self.tcx.hir.body_owner_def_id(body.id());
let node_id = body.value.id;
let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(fn_id));
let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(subject));
if self.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded
@ -171,21 +176,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
region_bound_pairs: Vec<(&'tcx ty::Region, GenericKind<'tcx>)>,
region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
free_region_map: FreeRegionMap,
pub region_maps: Rc<RegionMaps<'tcx>>,
free_region_map: FreeRegionMap<'tcx>,
// id of innermost fn body id
body_id: ast::NodeId,
// call_site scope of innermost fn
call_site_scope: Option<CodeExtent>,
call_site_scope: Option<CodeExtent<'tcx>>,
// id of innermost fn or loop
repeating_scope: ast::NodeId,
// id of AST node being analyzed (the subject of the analysis).
subject: ast::NodeId,
subject_def_id: DefId,
}
@ -197,25 +204,28 @@ impl<'a, 'gcx, 'tcx> Deref for RegionCtxt<'a, 'gcx, 'tcx> {
}
pub struct RepeatingScope(ast::NodeId);
pub struct Subject(ast::NodeId);
pub struct Subject(DefId);
impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
pub fn new(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
RepeatingScope(initial_repeating_scope): RepeatingScope,
initial_body_id: ast::NodeId,
Subject(subject): Subject) -> RegionCtxt<'a, 'gcx, 'tcx> {
let region_maps = fcx.tcx.region_maps(subject);
RegionCtxt {
fcx: fcx,
region_maps: region_maps,
repeating_scope: initial_repeating_scope,
body_id: initial_body_id,
call_site_scope: None,
subject: subject,
subject_def_id: subject,
region_bound_pairs: Vec::new(),
free_region_map: FreeRegionMap::new(),
}
}
fn set_call_site_scope(&mut self, call_site_scope: Option<CodeExtent>) -> Option<CodeExtent> {
fn set_call_site_scope(&mut self, call_site_scope: Option<CodeExtent<'tcx>>)
-> Option<CodeExtent<'tcx>> {
mem::replace(&mut self.call_site_scope, call_site_scope)
}
@ -276,7 +286,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let body_id = body.id();
let call_site = self.tcx.region_maps.lookup_code_extent(
let call_site = self.tcx.intern_code_extent(
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
@ -302,7 +312,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let old_body_id = self.set_body_id(body_id.node_id);
self.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span);
self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id), &body.arguments);
self.link_fn_args(self.tcx.node_extent(body_id.node_id), &body.arguments);
self.visit_body(body);
self.visit_region_obligations(body_id.node_id);
@ -417,14 +427,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
fn resolve_regions_and_report_errors(&self) {
let subject_node_id = self.subject;
self.fcx.resolve_regions_and_report_errors(&self.free_region_map,
subject_node_id);
self.fcx.resolve_regions_and_report_errors(self.subject_def_id,
&self.region_maps,
&self.free_region_map);
}
fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
let tcx = self.tcx;
debug!("regionck::visit_pat(pat={:?})", pat);
pat.each_binding(|_, id, span, _| {
// If we have a variable that contains region'd data, that
@ -450,7 +458,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// that the lifetime of any regions that appear in a
// variable's type enclose at least the variable's scope.
let var_scope = tcx.region_maps.var_scope(id);
let var_scope = self.region_maps.var_scope(id);
let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
let origin = infer::BindingTypeIsNotValidAtDecl(span);
@ -569,7 +577,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// If necessary, constrain destructors in the unadjusted form of this
// expression.
let cmt_result = {
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
mc.cat_expr_unadjusted(expr)
};
match cmt_result {
@ -586,7 +594,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// If necessary, constrain destructors in this expression. This will be
// the adjusted form if there is an adjustment.
let cmt_result = {
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
mc.cat_expr(expr)
};
match cmt_result {
@ -868,7 +876,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// call occurs.
//
// FIXME(#6268) to support nested method calls, should be callee_id
let callee_scope = self.tcx.region_maps.node_extent(call_expr.id);
let callee_scope = self.tcx.node_extent(call_expr.id);
let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
debug!("callee_region={:?}", callee_region);
@ -948,7 +956,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
r, m);
{
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i));
debug!("constrain_autoderefs: self_cmt={:?}",
self_cmt);
@ -982,8 +990,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
pub fn mk_subregion_due_to_dereference(&mut self,
deref_span: Span,
minimum_lifetime: &'tcx ty::Region,
maximum_lifetime: &'tcx ty::Region) {
minimum_lifetime: ty::Region<'tcx>,
maximum_lifetime: ty::Region<'tcx>) {
self.sub_regions(infer::DerefPointer(deref_span),
minimum_lifetime, maximum_lifetime)
}
@ -1021,7 +1029,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
debug!("constrain_index(index_expr=?, indexed_ty={}",
self.ty_to_string(indexed_ty));
let r_index_expr = ty::ReScope(self.tcx.region_maps.node_extent(index_expr.id));
let r_index_expr = ty::ReScope(self.tcx.node_extent(index_expr.id));
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
match mt.ty.sty {
ty::TySlice(_) | ty::TyStr => {
@ -1038,7 +1046,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn type_of_node_must_outlive(&mut self,
origin: infer::SubregionOrigin<'tcx>,
id: ast::NodeId,
minimum_lifetime: &'tcx ty::Region)
minimum_lifetime: ty::Region<'tcx>)
{
// Try to resolve the type. If we encounter an error, then typeck
// is going to fail anyway, so just stop here and let typeck
@ -1060,7 +1068,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
debug!("link_addr_of(expr={:?}, base={:?})", expr, base);
let cmt = {
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
ignore_err!(mc.cat_expr(base))
};
@ -1078,7 +1086,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
None => { return; }
Some(ref expr) => &**expr,
};
let mc = mc::MemCategorizationContext::new(self);
let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
let discr_cmt = ignore_err!(mc.cat_expr(init_expr));
self.link_pattern(mc, discr_cmt, &local.pat);
}
@ -1088,7 +1096,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// linked to the lifetime of its guarantor (if any).
fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
debug!("regionck::for_match()");
let mc = mc::MemCategorizationContext::new(self);
let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
let discr_cmt = ignore_err!(mc.cat_expr(discr));
debug!("discr_cmt={:?}", discr_cmt);
for arm in arms {
@ -1101,9 +1109,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// Computes the guarantors for any ref bindings in a match and
/// then ensures that the lifetime of the resulting pointer is
/// linked to the lifetime of its guarantor (if any).
fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) {
fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) {
debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
let mc = mc::MemCategorizationContext::new(self);
let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
for arg in args {
let arg_ty = self.node_ty(arg.id);
let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
@ -1120,13 +1128,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// Link lifetimes of any ref bindings in `root_pat` to the pointers found
/// in the discriminant, if needed.
fn link_pattern<'t>(&self,
mc: mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
discr_cmt: mc::cmt<'tcx>,
root_pat: &hir::Pat) {
debug!("link_pattern(discr_cmt={:?}, root_pat={:?})",
discr_cmt,
root_pat);
let _ = mc.cat_pattern(discr_cmt, root_pat, |_, sub_cmt, sub_pat| {
let _ = mc.cat_pattern(discr_cmt, root_pat, |_, sub_cmt, sub_pat| {
match sub_pat.node {
// `ref x` pattern
PatKind::Binding(hir::BindByRef(mutbl), ..) => {
@ -1146,7 +1154,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
autoref: &adjustment::AutoBorrow<'tcx>)
{
debug!("link_autoref(autoderefs={}, autoref={:?})", autoderefs, autoref);
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs));
debug!("expr_cmt={:?}", expr_cmt);
@ -1167,10 +1175,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// must outlive `callee_scope`.
fn link_by_ref(&self,
expr: &hir::Expr,
callee_scope: CodeExtent) {
callee_scope: CodeExtent<'tcx>) {
debug!("link_by_ref(expr={:?}, callee_scope={:?})",
expr, callee_scope);
let mc = mc::MemCategorizationContext::new(self);
let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
let expr_cmt = ignore_err!(mc.cat_expr(expr));
let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope));
self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt);
@ -1200,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// between regions, as explained in `link_reborrowed_region()`.
fn link_region(&self,
span: Span,
borrow_region: &'tcx ty::Region,
borrow_region: ty::Region<'tcx>,
borrow_kind: ty::BorrowKind,
borrow_cmt: mc::cmt<'tcx>) {
let mut borrow_cmt = borrow_cmt;
@ -1297,10 +1305,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// recurse and process `ref_cmt` (see case 2 above).
fn link_reborrowed_region(&self,
span: Span,
borrow_region: &'tcx ty::Region,
borrow_region: ty::Region<'tcx>,
borrow_kind: ty::BorrowKind,
ref_cmt: mc::cmt<'tcx>,
ref_region: &'tcx ty::Region,
ref_region: ty::Region<'tcx>,
mut ref_kind: ty::BorrowKind,
note: mc::Note)
-> Option<(mc::cmt<'tcx>, ty::BorrowKind)>
@ -1411,7 +1419,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
origin: infer::ParameterOrigin,
substs: &Substs<'tcx>,
expr_span: Span,
expr_region: &'tcx ty::Region) {
expr_region: ty::Region<'tcx>) {
debug!("substs_wf_in_scope(substs={:?}, \
expr_region={:?}, \
origin={:?}, \
@ -1436,7 +1444,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
pub fn type_must_outlive(&self,
origin: infer::SubregionOrigin<'tcx>,
ty: Ty<'tcx>,
region: &'tcx ty::Region)
region: ty::Region<'tcx>)
{
let ty = self.resolve_type(ty);
@ -1454,7 +1462,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn components_must_outlive(&self,
origin: infer::SubregionOrigin<'tcx>,
components: Vec<ty::outlives::Component<'tcx>>,
region: &'tcx ty::Region)
region: ty::Region<'tcx>)
{
for component in components {
let origin = origin.clone();
@ -1485,7 +1493,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn param_ty_must_outlive(&self,
origin: infer::SubregionOrigin<'tcx>,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
param_ty: ty::ParamTy) {
debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})",
region, param_ty, origin);
@ -1497,7 +1505,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn projection_must_outlive(&self,
origin: infer::SubregionOrigin<'tcx>,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>)
{
debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
@ -1614,7 +1622,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// Add in the default bound of fn body that applies to all in
// scope type parameters:
param_bounds.push(param_env.implicit_region_bound);
param_bounds.extend(param_env.implicit_region_bound);
VerifyBound::AnyRegion(param_bounds)
}
@ -1622,7 +1630,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn projection_declared_bounds(&self,
span: Span,
projection_ty: ty::ProjectionTy<'tcx>)
-> Vec<&'tcx ty::Region>
-> Vec<ty::Region<'tcx>>
{
// First assemble bounds from where clauses and traits.
@ -1637,7 +1645,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn projection_bound(&self,
span: Span,
declared_bounds: Vec<&'tcx ty::Region>,
declared_bounds: Vec<ty::Region<'tcx>>,
projection_ty: ty::ProjectionTy<'tcx>)
-> VerifyBound<'tcx> {
debug!("projection_bound(declared_bounds={:?}, projection_ty={:?})",
@ -1673,7 +1681,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
-> Vec<&'tcx ty::Region>
-> Vec<ty::Region<'tcx>>
{
let param_env = &self.parameter_environment;
@ -1707,7 +1715,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn declared_projection_bounds_from_trait(&self,
span: Span,
projection_ty: ty::ProjectionTy<'tcx>)
-> Vec<&'tcx ty::Region>
-> Vec<ty::Region<'tcx>>
{
debug!("projection_bounds(projection_ty={:?})",
projection_ty);

View file

@ -164,9 +164,12 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id());
{
let body_owner_def_id = self.fcx.tcx.hir.body_owner_def_id(body.id());
let region_maps = &self.fcx.tcx.region_maps(body_owner_def_id);
let mut euv =
euv::ExprUseVisitor::with_options(self,
self.fcx,
region_maps,
mc::MemCategorizationOptions {
during_closure_kind_inference: true
});
@ -536,7 +539,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> {
borrow_id: ast::NodeId,
_borrow_span: Span,
cmt: mc::cmt<'tcx>,
_loan_region: &'tcx ty::Region,
_loan_region: ty::Region<'tcx>,
bk: ty::BorrowKind,
_loan_cause: euv::LoanCause)
{

View file

@ -341,9 +341,9 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
let mut implied_bounds = vec![];
let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id);
let free_id_outlive = fcx.tcx.call_site_extent(item.id, body_id.node_id);
this.check_fn_or_method(fcx, item.span, sig, &predicates,
free_id_outlive, &mut implied_bounds);
Some(free_id_outlive), &mut implied_bounds);
implied_bounds
})
}
@ -429,7 +429,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
span: Span,
sig: ty::PolyFnSig<'tcx>,
predicates: &ty::InstantiatedPredicates<'tcx>,
free_id_outlive: CodeExtent,
free_id_outlive: Option<CodeExtent<'tcx>>,
implied_bounds: &mut Vec<Ty<'tcx>>)
{
let free_substs = &fcx.parameter_environment.free_substs;
@ -453,7 +453,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
method_sig: &hir::MethodSig,
method: &ty::AssociatedItem,
free_id_outlive: CodeExtent,
free_id_outlive: Option<CodeExtent<'tcx>>,
self_ty: ty::Ty<'tcx>)
{
// check that the type of the method's receiver matches the

View file

@ -76,7 +76,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
// early-bound versions of them, visible from the
// outside of the function. This is needed by, and
// only populated if there are any `impl Trait`.
free_to_bound_regions: DefIdMap<&'gcx ty::Region>,
free_to_bound_regions: DefIdMap<ty::Region<'gcx>>,
body: &'gcx hir::Body,
}
@ -275,7 +275,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
fn visit_free_region_map(&mut self) {
self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map);
let free_region_map = free_region_map.expect("all regions in free-region-map are global");
self.tables.free_region_map = free_region_map;
}
fn visit_anon_types(&mut self) {
@ -522,7 +524,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
// FIXME This should be carefully checked
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match self.infcx.fully_resolve(&r) {
Ok(r) => r,
Err(_) => {

View file

@ -12,6 +12,7 @@
//! up data structures required by type-checking/translation.
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::RegionMaps;
use rustc::middle::lang_items::UnsizeTraitLangItem;
use rustc::traits::{self, ObligationCause, Reveal};
@ -342,10 +343,11 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
// Finally, resolve all regions.
let region_maps = RegionMaps::new();
let mut free_regions = FreeRegionMap::new();
free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment
.caller_bounds);
infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
infcx.resolve_regions_and_report_errors(impl_did, &region_maps, &free_regions);
CoerceUnsizedInfo {
custom_kind: kind

View file

@ -215,7 +215,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
}
fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
-> Option<&'tcx ty::Region> {
-> Option<ty::Region<'tcx>> {
None
}

View file

@ -75,7 +75,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
t.super_visit_with(self)
}
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
match *r {
ty::ReEarlyBound(data) => {
self.parameters.push(Parameter::from(data));

View file

@ -479,7 +479,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// context with ambient variance `variance`
fn add_constraints_from_region(&mut self,
generics: &ty::Generics,
region: &'tcx ty::Region,
region: ty::Region<'tcx>,
variance: VarianceTermPtr<'a>) {
match *region {
ty::ReEarlyBound(ref data) => {

View file

@ -503,7 +503,7 @@ impl<'a> Iterator for ListAttributesIter<'a> {
pub trait AttributesExt {
/// Finds an attribute as List and returns the list of attributes nested inside.
fn lists<'a>(&'a self, &'a str) -> ListAttributesIter<'a>;
fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>;
}
impl AttributesExt for [ast::Attribute] {
@ -518,7 +518,7 @@ impl AttributesExt for [ast::Attribute] {
pub trait NestedAttributesExt {
/// Returns whether the attribute list contains a specific `Word`
fn has_word(self, &str) -> bool;
fn has_word(self, word: &str) -> bool;
}
impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
@ -726,7 +726,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
if let ty::TyTuple(ts, _) = ty_s.sty {
for &ty_s in ts {
if let ty::TyRef(ref reg, _) = ty_s.sty {
if let &ty::Region::ReLateBound(..) = *reg {
if let &ty::RegionKind::ReLateBound(..) = *reg {
debug!(" hit an ReLateBound {:?}", reg);
if let Some(lt) = reg.clean(cx) {
late_bounds.push(lt);
@ -819,7 +819,7 @@ impl Clean<Lifetime> for ty::RegionParameterDef {
}
}
impl Clean<Option<Lifetime>> for ty::Region {
impl<'tcx> Clean<Option<Lifetime>> for ty::RegionKind<'tcx> {
fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
match *self {
ty::ReStatic => Some(Lifetime::statik()),
@ -915,7 +915,7 @@ impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
}
}
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> {
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>> {
fn clean(&self, cx: &DocContext) -> WherePredicate {
let ty::OutlivesPredicate(ref a, ref b) = *self;
WherePredicate::RegionPredicate {
@ -925,7 +925,7 @@ impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'t
}
}
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, &'tcx ty::Region> {
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, ty::Region<'tcx>> {
fn clean(&self, cx: &DocContext) -> WherePredicate {
let ty::OutlivesPredicate(ref ty, ref lt) = *self;

View file

@ -89,7 +89,7 @@ impl<'a, 'tcx> DocContext<'a, 'tcx> {
}
pub trait DocAccessLevels {
fn is_doc_reachable(&self, DefId) -> bool;
fn is_doc_reachable(&self, did: DefId) -> bool;
}
impl DocAccessLevels for AccessLevels<DefId> {

Some files were not shown because too many files have changed in this diff Show more