rustc: rename CodeExtent to Scope and RegionMaps to ScopeTree.

This commit is contained in:
Eduard-Mihai Burtescu 2017-08-31 21:37:38 +03:00
parent f861b6ee46
commit 8bdfd8a003
65 changed files with 673 additions and 659 deletions

View File

@ -10,7 +10,7 @@
use rustc_data_structures::graph;
use cfg::*;
use middle::region::CodeExtent;
use middle::region;
use ty::{self, TyCtxt};
use syntax::ptr::P;
@ -579,14 +579,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
fn add_exiting_edge(&mut self,
from_expr: &hir::Expr,
from_index: CFGIndex,
target_scope: CodeExtent,
target_scope: region::Scope,
to_index: CFGIndex) {
let mut data = CFGEdgeData { exiting_scopes: vec![] };
let mut scope = CodeExtent::Misc(from_expr.hir_id.local_id);
let region_maps = self.tcx.region_maps(self.owner_def_id);
let mut scope = region::Scope::Node(from_expr.hir_id.local_id);
let region_scope_tree = self.tcx.region_scope_tree(self.owner_def_id);
while scope != target_scope {
data.exiting_scopes.push(scope.item_local_id());
scope = region_maps.encl_scope(scope);
scope = region_scope_tree.encl_scope(scope);
}
self.graph.add_edge(from_index, to_index, data);
}
@ -606,14 +606,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
fn find_scope_edge(&self,
expr: &hir::Expr,
destination: hir::Destination,
scope_cf_kind: ScopeCfKind) -> (CodeExtent, CFGIndex) {
scope_cf_kind: ScopeCfKind) -> (region::Scope, CFGIndex) {
match destination.target_id {
hir::ScopeTarget::Block(block_expr_id) => {
for b in &self.breakable_block_scopes {
if b.block_expr_id == self.tcx.hir.node_to_hir_id(block_expr_id).local_id {
let scope_id = self.tcx.hir.node_to_hir_id(block_expr_id).local_id;
return (CodeExtent::Misc(scope_id), match scope_cf_kind {
return (region::Scope::Node(scope_id), match scope_cf_kind {
ScopeCfKind::Break => b.break_index,
ScopeCfKind::Continue => bug!("can't continue to block"),
});
@ -625,7 +625,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
for l in &self.loop_scopes {
if l.loop_id == self.tcx.hir.node_to_hir_id(loop_id).local_id {
let scope_id = self.tcx.hir.node_to_hir_id(loop_id).local_id;
return (CodeExtent::Misc(scope_id), match scope_cf_kind {
return (region::Scope::Node(scope_id), match scope_cf_kind {
ScopeCfKind::Break => l.break_index,
ScopeCfKind::Continue => l.continue_index,
});

View File

@ -395,7 +395,7 @@ define_dep_nodes!( <'tcx>
[] WorkProduct(WorkProductId),
// Represents different phases in the compiler.
[] RegionMaps(DefId),
[] RegionScopeTree(DefId),
[] Coherence,
[] CoherenceInherentImplOverlapCheck,
[] Resolve,

View File

@ -239,8 +239,8 @@ for mir::StatementKind<'gcx> {
mir::StatementKind::StorageDead(ref lvalue) => {
lvalue.hash_stable(hcx, hasher);
}
mir::StatementKind::EndRegion(ref extent) => {
extent.hash_stable(hcx, hasher);
mir::StatementKind::EndRegion(ref region_scope) => {
region_scope.hash_stable(hcx, hasher);
}
mir::StatementKind::Validate(ref op, ref lvalues) => {
op.hash_stable(hcx, hasher);
@ -271,7 +271,7 @@ impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
}
}
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) });
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) });
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,

View File

@ -17,6 +17,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
use std::hash as std_hash;
use std::mem;
use syntax_pos::symbol::InternedString;
use middle::region;
use ty;
impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
@ -65,8 +66,8 @@ for ty::RegionKind {
index.hash_stable(hcx, hasher);
name.hash_stable(hcx, hasher);
}
ty::ReScope(code_extent) => {
code_extent.hash_stable(hcx, hasher);
ty::ReScope(scope) => {
scope.hash_stable(hcx, hasher);
}
ty::ReFree(ref free_region) => {
free_region.hash_stable(hcx, hasher);
@ -450,24 +451,22 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
});
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for ::middle::region::CodeExtent
for region::Scope
{
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
use middle::region::CodeExtent;
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
CodeExtent::Misc(node_id) |
CodeExtent::DestructionScope(node_id) => {
region::Scope::Node(node_id) |
region::Scope::Destruction(node_id) => {
node_id.hash_stable(hcx, hasher);
}
CodeExtent::CallSiteScope(body_id) |
CodeExtent::ParameterScope(body_id) => {
region::Scope::CallSite(body_id) |
region::Scope::Arguments(body_id) => {
body_id.hash_stable(hcx, hasher);
}
CodeExtent::Remainder(block_remainder) => {
region::Scope::Remainder(block_remainder) => {
block_remainder.hash_stable(hcx, hasher);
}
}

View File

@ -64,7 +64,7 @@ use std::fmt;
use hir;
use hir::map as hir_map;
use hir::def_id::DefId;
use middle::region::{self, RegionMaps};
use middle::region;
use traits::{ObligationCause, ObligationCauseCode};
use ty::{self, Region, TyCtxt, TypeFoldable};
use ty::error::TypeError;
@ -83,7 +83,7 @@ mod anon_anon_conflict;
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn note_and_explain_region(self,
region_maps: &RegionMaps,
region_scope_tree: &region::ScopeTree,
err: &mut DiagnosticBuilder,
prefix: &str,
region: ty::Region<'tcx>,
@ -131,8 +131,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
format!("{}unknown scope: {:?}{}. Please report a bug.",
prefix, scope, suffix)
};
let span = scope.span(self, region_maps);
let tag = match self.hir.find(scope.node_id(self, region_maps)) {
let span = scope.span(self, region_scope_tree);
let tag = match self.hir.find(scope.node_id(self, region_scope_tree)) {
Some(hir_map::NodeBlock(_)) => "block",
Some(hir_map::NodeExpr(expr)) => match expr.node {
hir::ExprCall(..) => "call",
@ -153,18 +153,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
};
let scope_decorated_tag = match scope {
region::CodeExtent::Misc(_) => tag,
region::CodeExtent::CallSiteScope(_) => {
region::Scope::Node(_) => tag,
region::Scope::CallSite(_) => {
"scope of call-site for function"
}
region::CodeExtent::ParameterScope(_) => {
region::Scope::Arguments(_) => {
"scope of function body"
}
region::CodeExtent::DestructionScope(_) => {
region::Scope::Destruction(_) => {
new_string = format!("destruction scope surrounding {}", tag);
&new_string[..]
}
region::CodeExtent::Remainder(r) => {
region::Scope::Remainder(r) => {
new_string = format!("block suffix following statement {}",
r.first_statement_index);
&new_string[..]
@ -256,7 +256,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn report_region_errors(&self,
region_maps: &RegionMaps,
region_scope_tree: &region::ScopeTree,
errors: &Vec<RegionResolutionError<'tcx>>) {
debug!("report_region_errors(): {} errors to start", errors.len());
@ -281,15 +281,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// the error. If all of these fails, we fall back to a rather
// general bit of code that displays the error information
ConcreteFailure(origin, sub, sup) => {
self.report_concrete_failure(region_maps, origin, sub, sup).emit();
self.report_concrete_failure(region_scope_tree, origin, sub, sup).emit();
}
GenericBoundFailure(kind, param_ty, sub) => {
self.report_generic_bound_failure(region_maps, kind, param_ty, sub);
self.report_generic_bound_failure(region_scope_tree, kind, param_ty, sub);
}
SubSupConflict(var_origin, sub_origin, sub_r, sup_origin, sup_r) => {
self.report_sub_sup_conflict(region_maps,
self.report_sub_sup_conflict(region_scope_tree,
var_origin,
sub_origin,
sub_r,
@ -769,7 +769,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
fn report_generic_bound_failure(&self,
region_maps: &RegionMaps,
region_scope_tree: &region::ScopeTree,
origin: SubregionOrigin<'tcx>,
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>)
@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
err.help(&format!("consider adding an explicit lifetime bound for `{}`",
bound_kind));
self.tcx.note_and_explain_region(
region_maps,
region_scope_tree,
&mut err,
&format!("{} must be valid for ", labeled_user_string),
sub,
@ -851,7 +851,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
fn report_sub_sup_conflict(&self,
region_maps: &RegionMaps,
region_scope_tree: &region::ScopeTree,
var_origin: RegionVariableOrigin,
sub_origin: SubregionOrigin<'tcx>,
sub_region: Region<'tcx>,
@ -859,14 +859,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
sup_region: Region<'tcx>) {
let mut err = self.report_inference_failure(var_origin);
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"first, the lifetime cannot outlive ",
sup_region,
"...");
self.note_region_origin(&mut err, &sup_origin);
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"but, the lifetime must be valid for ",
sub_region,
"...");

View File

@ -9,7 +9,7 @@
// except according to those terms.
use infer::{self, InferCtxt, SubregionOrigin};
use middle::region::RegionMaps;
use middle::region;
use ty::{self, Region};
use ty::error::TypeError;
use errors::DiagnosticBuilder;
@ -145,7 +145,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub(super) fn report_concrete_failure(&self,
region_maps: &RegionMaps,
region_scope_tree: &region::ScopeTree,
origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>,
sup: Region<'tcx>)
@ -154,8 +154,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
infer::Subtype(trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, &terr);
self.tcx.note_and_explain_region(region_maps, &mut err, "", sup, "...");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err, "", sup, "...");
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...does not necessarily outlive ", sub, "");
err
}
@ -165,11 +165,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0312,
"lifetime of reference outlives lifetime of \
borrowed content...");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...the reference is valid for ",
sub,
"...");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...but the borrowed content is only valid for ",
sup,
"");
@ -183,12 +183,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
of captured variable `{}`...",
self.tcx
.local_var_name_str_def_index(upvar_id.var_id));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...the borrowed pointer is valid for ",
sub,
"...");
self.tcx.note_and_explain_region(
region_maps,
region_scope_tree,
&mut err,
&format!("...but `{}` is only valid for ",
self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
@ -199,11 +199,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
infer::InfStackClosure(span) => {
let mut err =
struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...the closure must be valid for ",
sub,
"...");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...but the closure's stack frame is only valid \
for ",
sup,
@ -215,7 +215,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span,
E0315,
"cannot invoke closure outside of its lifetime");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the closure is only valid for ", sup, "");
err
}
@ -224,7 +224,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span,
E0473,
"dereference of reference outside its lifetime");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the reference is only valid for ", sup, "");
err
}
@ -235,9 +235,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"captured variable `{}` does not outlive the \
enclosing closure",
self.tcx.local_var_name_str(id));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"captured variable is valid for ", sup, "");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"closure is valid for ", sub, "");
err
}
@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span,
E0475,
"index of slice outside its lifetime");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the slice is only valid for ", sup, "");
err
}
@ -256,9 +256,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0476,
"lifetime of the source pointer does not outlive \
lifetime bound of the object type");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"object type is valid for ", sub, "");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"source pointer is only valid for ",
sup,
"");
@ -273,11 +273,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.ty_to_string(ty));
match *sub {
ty::ReStatic => {
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"type must satisfy ", sub, "")
}
_ => {
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"type must outlive ", sub, "")
}
}
@ -286,11 +286,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
infer::RelateRegionParamBound(span) => {
let mut err =
struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"lifetime parameter instantiated with ",
sup,
"");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"but lifetime parameter must outlive ",
sub,
"");
@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"the type `{}` (provided as the value of a type \
parameter) is not valid at this point",
self.ty_to_string(ty));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"type must outlive ", sub, "");
err
}
@ -313,7 +313,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0480,
"lifetime of method receiver does not outlive the \
method call");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the receiver is only valid for ", sup, "");
err
}
@ -323,7 +323,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0481,
"lifetime of function argument does not outlive \
the function call");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the function argument is only valid for ",
sup,
"");
@ -335,7 +335,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0482,
"lifetime of return value does not outlive the \
function call");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the return value is only valid for ",
sup,
"");
@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0483,
"lifetime of operand does not outlive the \
operation");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the operand is only valid for ", sup, "");
err
}
@ -356,7 +356,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span,
E0484,
"reference is not valid at the time of borrow");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the borrow is only valid for ", sup, "");
err
}
@ -366,7 +366,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0485,
"automatically reference is not valid at the time \
of borrow");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the automatic borrow is only valid for ",
sup,
"");
@ -379,7 +379,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"type of expression contains references that are \
not valid during the expression: `{}`",
self.ty_to_string(t));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"type is only valid for ", sup, "");
err
}
@ -390,8 +390,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"unsafe use of destructor: destructor might be \
called while references are dead");
// FIXME (22171): terms "super/subregion" are suboptimal
self.tcx.note_and_explain_region(region_maps, &mut err, "superregion: ", sup, "");
self.tcx.note_and_explain_region(region_maps, &mut err, "subregion: ", sub, "");
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"superregion: ", sup, "");
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"subregion: ", sub, "");
err
}
infer::BindingTypeIsNotValidAtDecl(span) => {
@ -400,7 +402,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0488,
"lifetime of variable does not enclose its \
declaration");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the variable is only valid for ", sup, "");
err
}
@ -409,7 +411,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span,
E0489,
"type/lifetime parameter not in scope here");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the parameter is only valid for ", sub, "");
err
}
@ -419,9 +421,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
E0490,
"a value of type `{}` is borrowed for too long",
self.ty_to_string(ty));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the type is valid for ", sub, "");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"but the borrow lasts for ", sup, "");
err
}
@ -432,9 +434,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"in type `{}`, reference has a longer lifetime \
than the data it references",
self.ty_to_string(ty));
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"the pointer is valid for ", sub, "");
self.tcx.note_and_explain_region(region_maps, &mut err,
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"but the referenced data is only valid for ",
sup,
"");

View File

@ -20,7 +20,7 @@ pub use self::region_inference::{GenericKind, VerifyBound};
use hir::def_id::DefId;
use middle::free_region::{FreeRegionMap, RegionRelations};
use middle::region::RegionMaps;
use middle::region;
use middle::lang_items;
use mir::tcx::LvalueTy;
use ty::subst::{Kind, Subst, Substs};
@ -1070,7 +1070,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn resolve_regions_and_report_errors(&self,
region_context: DefId,
region_map: &RegionMaps,
region_map: &region::ScopeTree,
free_regions: &FreeRegionMap<'tcx>) {
let region_rels = RegionRelations::new(self.tcx,
region_context,

View File

@ -21,7 +21,7 @@ use graphviz as dot;
use hir::def_id::DefIndex;
use ty;
use middle::free_region::RegionRelations;
use middle::region::CodeExtent;
use middle::region;
use super::Constraint;
use infer::SubregionOrigin;
use infer::region_inference::RegionVarBindings;
@ -136,7 +136,7 @@ enum Node {
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
enum Edge<'tcx> {
Constraint(Constraint<'tcx>),
EnclScope(CodeExtent, CodeExtent),
EnclScope(region::Scope, region::Scope),
}
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
@ -159,7 +159,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
add_node(n2);
}
region_rels.region_maps.each_encl_scope(|sub, sup| {
region_rels.region_scope_tree.each_encl_scope(|sub, sup| {
add_node(Node::Region(ty::ReScope(sub)));
add_node(Node::Region(ty::ReScope(sup)));
});
@ -245,7 +245,9 @@ 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.region_rels.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
self.region_rels.region_scope_tree.each_encl_scope(|sub, sup| {
v.push(Edge::EnclScope(sub, sup))
});
debug!("region graph has {} edges", v.len());
Cow::Owned(v)
}

View File

@ -935,14 +935,14 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// reasonably compare free regions and scopes:
let fr_scope = match (a, b) {
(&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
region_rels.region_maps.early_free_extent(self.tcx, br)
region_rels.region_scope_tree.early_free_scope(self.tcx, br)
}
(&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
region_rels.region_maps.free_extent(self.tcx, fr)
region_rels.region_scope_tree.free_scope(self.tcx, fr)
}
_ => bug!()
};
let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id);
let r_id = region_rels.region_scope_tree.nearest_common_ancestor(fr_scope, s_id);
if r_id == fr_scope {
// if the free region's scope `fr.scope` is bigger than
// the scope region `s_id`, then the LUB is the free
@ -963,7 +963,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
// The region corresponding to an outer block is a
// subtype of the region corresponding to an inner
// block.
let lub = region_rels.region_maps.nearest_common_ancestor(a_id, b_id);
let lub = region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id);
self.tcx.mk_region(ReScope(lub))
}

View File

@ -23,7 +23,7 @@ use hir::def::Def;
use hir::def_id::{DefId};
use infer::InferCtxt;
use middle::mem_categorization as mc;
use middle::region::{CodeExtent, RegionMaps};
use middle::region;
use ty::{self, TyCtxt, adjustment};
use hir::{self, PatKind};
@ -265,12 +265,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> {
pub fn new(delegate: &'a mut (Delegate<'tcx>+'a),
tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>)
-> Self
{
ExprUseVisitor {
mc: mc::MemCategorizationContext::new(tcx, region_maps, tables),
mc: mc::MemCategorizationContext::new(tcx, region_scope_tree, tables),
delegate,
param_env,
}
@ -281,12 +281,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
pub fn with_infer(delegate: &'a mut (Delegate<'tcx>+'a),
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>)
-> Self
{
ExprUseVisitor {
mc: mc::MemCategorizationContext::with_infer(infcx, region_maps, tables),
mc: mc::MemCategorizationContext::with_infer(infcx, region_scope_tree, tables),
delegate,
param_env,
}
@ -299,7 +299,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.hir_id));
let fn_body_scope_r =
self.tcx().mk_region(ty::ReScope(CodeExtent::Misc(body.value.hir_id.local_id)));
self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id)));
let arg_cmt = self.mc.cat_rvalue(
arg.id,
arg.pat.span,
@ -543,7 +543,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
ty::TyError => { }
_ => {
let def_id = self.mc.tables.type_dependent_defs()[call.hir_id].def_id();
let call_scope = CodeExtent::Misc(call.hir_id.local_id);
let call_scope = region::Scope::Node(call.hir_id.local_id);
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
FnMutOverloadedCall => {
let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
@ -751,7 +751,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
// Converting from a &T to *T (or &mut T to *mut T) is
// treated as borrowing it for the enclosing temporary
// scope.
let r = self.tcx().mk_region(ty::ReScope(CodeExtent::Misc(expr.hir_id.local_id)));
let r = self.tcx().mk_region(ty::ReScope(
region::Scope::Node(expr.hir_id.local_id)));
self.delegate.borrow(expr.id,
expr.span,

View File

@ -16,11 +16,11 @@
//! region outlives another and so forth.
use hir::def_id::DefId;
use middle::region::RegionMaps;
use middle::region;
use ty::{self, Lift, TyCtxt, Region};
use rustc_data_structures::transitive_relation::TransitiveRelation;
/// Combines a `RegionMaps` (which governs relationships between
/// Combines a `region::ScopeTree` (which governs relationships between
/// scopes) and a `FreeRegionMap` (which governs relationships between
/// free regions) to yield a complete relation between concrete
/// regions.
@ -34,7 +34,7 @@ pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> {
pub context: DefId,
/// region maps for the given context
pub region_maps: &'a RegionMaps,
pub region_scope_tree: &'a region::ScopeTree,
/// free-region relationships
pub free_regions: &'a FreeRegionMap<'tcx>,
@ -44,13 +44,13 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
pub fn new(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
context: DefId,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
free_regions: &'a FreeRegionMap<'tcx>,
) -> Self {
Self {
tcx,
context,
region_maps,
region_scope_tree,
free_regions,
}
}
@ -68,16 +68,16 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
true,
(&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) =>
self.region_maps.is_subscope_of(sub_scope, super_scope),
self.region_scope_tree.is_subscope_of(sub_scope, super_scope),
(&ty::ReScope(sub_scope), &ty::ReEarlyBound(ref br)) => {
let fr_scope = self.region_maps.early_free_extent(self.tcx, br);
self.region_maps.is_subscope_of(sub_scope, fr_scope)
let fr_scope = self.region_scope_tree.early_free_scope(self.tcx, br);
self.region_scope_tree.is_subscope_of(sub_scope, fr_scope)
}
(&ty::ReScope(sub_scope), &ty::ReFree(ref fr)) => {
let fr_scope = self.region_maps.free_extent(self.tcx, fr);
self.region_maps.is_subscope_of(sub_scope, fr_scope)
let fr_scope = self.region_scope_tree.free_scope(self.tcx, fr);
self.region_scope_tree.is_subscope_of(sub_scope, fr_scope)
}
(&ty::ReEarlyBound(_), &ty::ReEarlyBound(_)) |

View File

@ -69,7 +69,7 @@ pub use self::Note::*;
use self::Aliasability::*;
use middle::region::RegionMaps;
use middle::region;
use hir::def_id::{DefId, DefIndex};
use hir::map as hir_map;
use infer::InferCtxt;
@ -283,7 +283,7 @@ impl ast_node for hir::Pat {
#[derive(Clone)]
pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub region_maps: &'a RegionMaps,
pub region_scope_tree: &'a region::ScopeTree,
pub tables: &'a ty::TypeckTables<'tcx>,
infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>,
}
@ -391,21 +391,21 @@ impl MutabilityCategory {
impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>)
-> MemCategorizationContext<'a, 'tcx, 'tcx> {
MemCategorizationContext { tcx, region_maps, tables, infcx: None }
MemCategorizationContext { tcx, region_scope_tree, tables, infcx: None }
}
}
impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
pub fn with_infer(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>)
-> MemCategorizationContext<'a, 'gcx, 'tcx> {
MemCategorizationContext {
tcx: infcx.tcx,
region_maps,
region_scope_tree,
tables,
infcx: Some(infcx),
}
@ -862,7 +862,7 @@ 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: hir::ItemLocalId) -> ty::Region<'tcx> {
let scope = self.region_maps.temporary_scope(id);
let scope = self.region_scope_tree.temporary_scope(id);
self.tcx.mk_region(match scope {
Some(scope) => ty::ReScope(scope),
None => ty::ReStatic

View File

@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This file actually contains two passes related to regions. The first
//! pass builds up the `scope_map`, which describes the parent links in
//! the region hierarchy. The second pass infers which types must be
//! region parameterized.
//! This file builds up the `ScopeTree`, which describes
//! the parent links in the region hierarchy.
//!
//! Most of the documentation on regions can be found in
//! `middle/infer/region_inference/README.md`
@ -34,24 +32,24 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap};
use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local};
use mir::transform::MirSource;
/// CodeExtent represents a statically-describable extent that can be
/// Scope represents a statically-describable scope that can be
/// used to bound the lifetime/region for values.
///
/// `Misc(node_id)`: Any AST node that has any extent at all has the
/// `Misc(node_id)` extent. Other variants represent special cases not
/// `Node(node_id)`: Any AST node that has any scope at all has the
/// `Node(node_id)` scope. Other variants represent special cases not
/// immediately derivable from the abstract syntax tree structure.
///
/// `DestructionScope(node_id)` represents the extent of destructors
/// `DestructionScope(node_id)` represents the scope of destructors
/// implicitly-attached to `node_id` that run immediately after the
/// expression for `node_id` itself. Not every AST node carries a
/// `DestructionScope`, but those that are `terminating_scopes` do;
/// see discussion with `RegionMaps`.
/// see discussion with `ScopeTree`.
///
/// `Remainder(BlockRemainder { block, statement_index })` represents
/// the extent of user code running immediately after the initializer
/// the scope of user code running immediately after the initializer
/// expression for the indexed statement, until the end of the block.
///
/// So: the following code can be broken down into the extents beneath:
/// So: the following code can be broken down into the scopes beneath:
/// ```
/// let a = f().g( 'b: { let x = d(); let y = d(); x.h(y) } ) ;
/// ```
@ -69,21 +67,21 @@ use mir::transform::MirSource;
/// +--+ (M2.)
/// +-----------------------------------------------------------+ (M1.)
///
/// (M1.): Misc extent of the whole `let a = ...;` statement.
/// (M2.): Misc extent of the `f()` expression.
/// (M3.): Misc extent of the `f().g(..)` expression.
/// (M4.): Misc extent of the block labeled `'b:`.
/// (M5.): Misc extent of the `let x = d();` statement
/// (M1.): Node scope of the whole `let a = ...;` statement.
/// (M2.): Node scope of the `f()` expression.
/// (M3.): Node scope of the `f().g(..)` expression.
/// (M4.): Node scope of the block labeled `'b:`.
/// (M5.): Node scope of the `let x = d();` statement
/// (D6.): DestructionScope for temporaries created during M5.
/// (R7.): Remainder extent for block `'b:`, stmt 0 (let x = ...).
/// (M8.): Misc Extent of the `let y = d();` statement.
/// (R7.): Remainder scope for block `'b:`, stmt 0 (let x = ...).
/// (M8.): Node scope of the `let y = d();` statement.
/// (D9.): DestructionScope for temporaries created during M8.
/// (R10.): Remainder extent for block `'b:`, stmt 1 (let y = ...).
/// (R10.): Remainder scope for block `'b:`, stmt 1 (let y = ...).
/// (D11.): DestructionScope for temporaries and bindings from block `'b:`.
/// (D12.): DestructionScope for temporaries created during M1 (e.g. f()).
///
/// Note that while the above picture shows the destruction scopes
/// as following their corresponding misc extents, in the internal
/// as following their corresponding node scopes, in the internal
/// data structures of the compiler the destruction scopes are
/// represented as enclosing parents. This is sound because we use the
/// enclosing parent relationship just to ensure that referenced
@ -96,21 +94,21 @@ use mir::transform::MirSource;
/// actually attach a more meaningful ordering to scopes than the one
/// generated via deriving here.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
pub enum CodeExtent {
Misc(hir::ItemLocalId),
pub enum Scope {
Node(hir::ItemLocalId),
// extent of the call-site for a function or closure (outlives
// the parameters as well as the body).
CallSiteScope(hir::ItemLocalId),
// Scope of the call-site for a function or closure
// (outlives the arguments as well as the body).
CallSite(hir::ItemLocalId),
// extent of parameters passed to a function or closure (they
// outlive its body)
ParameterScope(hir::ItemLocalId),
// Scope of arguments passed to a function or closure
// (they outlive its body).
Arguments(hir::ItemLocalId),
// extent of destructors for temporaries of node-id
DestructionScope(hir::ItemLocalId),
// Scope of destructors for temporaries of node-id.
Destruction(hir::ItemLocalId),
// extent of code following a `let id = expr;` binding in a block
// Scope following a `let id = expr;` binding in a block.
Remainder(BlockRemainder)
}
@ -125,9 +123,9 @@ pub enum CodeExtent {
/// * the subscope with `first_statement_index == 0` is scope of both
/// `a` and `b`; it does not include EXPR_1, but does include
/// everything after that first `let`. (If you want a scope that
/// includes EXPR_1 as well, then do not use `CodeExtent::Remainder`,
/// but instead another `CodeExtent` that encompasses the whole block,
/// e.g. `CodeExtent::Misc`.
/// includes EXPR_1 as well, then do not use `Scope::Remainder`,
/// but instead another `Scope` that encompasses the whole block,
/// e.g. `Scope::Node`.
///
/// * the subscope with `first_statement_index == 1` is scope of `c`,
/// and thus does not include EXPR_2, but covers the `...`.
@ -138,26 +136,26 @@ pub struct BlockRemainder {
pub first_statement_index: u32,
}
impl CodeExtent {
impl Scope {
/// Returns a item-local id associated with this scope.
///
/// NB: likely to be replaced as API is refined; e.g. pnkfelix
/// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
pub fn item_local_id(&self) -> hir::ItemLocalId {
match *self {
CodeExtent::Misc(id) => id,
Scope::Node(id) => id,
// These cases all return rough approximations to the
// precise extent denoted by `self`.
CodeExtent::Remainder(br) => br.block,
CodeExtent::DestructionScope(id) |
CodeExtent::CallSiteScope(id) |
CodeExtent::ParameterScope(id) => id,
// precise scope denoted by `self`.
Scope::Remainder(br) => br.block,
Scope::Destruction(id) |
Scope::CallSite(id) |
Scope::Arguments(id) => id,
}
}
pub fn node_id(&self, tcx: TyCtxt, region_maps: &RegionMaps) -> ast::NodeId {
match region_maps.root_body {
pub fn node_id(&self, tcx: TyCtxt, scope_tree: &ScopeTree) -> ast::NodeId {
match scope_tree.root_body {
Some(hir_id) => {
tcx.hir.hir_to_node_id(hir::HirId {
owner: hir_id.owner,
@ -168,18 +166,18 @@ impl CodeExtent {
}
}
/// Returns the span of this CodeExtent. Note that in general the
/// Returns the span of this Scope. Note that in general the
/// returned span may not correspond to the span of any node id in
/// the AST.
pub fn span(&self, tcx: TyCtxt, region_maps: &RegionMaps) -> Span {
let node_id = self.node_id(tcx, region_maps);
pub fn span(&self, tcx: TyCtxt, scope_tree: &ScopeTree) -> Span {
let node_id = self.node_id(tcx, scope_tree);
if node_id == ast::DUMMY_NODE_ID {
return DUMMY_SP;
}
let span = tcx.hir.span(node_id);
if let CodeExtent::Remainder(r) = *self {
if let Scope::Remainder(r) = *self {
if let hir::map::NodeBlock(ref blk) = tcx.hir.get(node_id) {
// Want span for extent starting after the
// Want span for scope starting after the
// indexed statement and ending at end of
// `blk`; reuse span of `blk` and shift `lo`
// forward to end of indexed statement.
@ -200,9 +198,9 @@ impl CodeExtent {
}
}
/// The region maps encode information about region relationships.
/// The region scope tree encodes information about region relationships.
#[derive(Default)]
pub struct RegionMaps {
pub struct ScopeTree {
/// If not empty, this body is the root of this region hierarchy.
root_body: Option<hir::HirId>,
@ -211,20 +209,20 @@ pub struct RegionMaps {
/// have lifetime parameters free in this body.
root_parent: Option<ast::NodeId>,
/// `scope_map` maps from a scope id to the enclosing scope id;
/// `parent_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: FxHashMap<CodeExtent, CodeExtent>,
parent_map: FxHashMap<Scope, Scope>,
/// `var_map` maps from a variable or binding id to the block in
/// which that variable is declared.
var_map: FxHashMap<hir::ItemLocalId, CodeExtent>,
var_map: FxHashMap<hir::ItemLocalId, Scope>,
/// maps from a node-id to the associated destruction scope (if any)
destruction_scopes: FxHashMap<hir::ItemLocalId, CodeExtent>,
destruction_scopes: FxHashMap<hir::ItemLocalId, Scope>,
/// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
/// larger than the default. The map goes from the expression id
@ -234,7 +232,7 @@ pub struct RegionMaps {
/// block (see `terminating_scopes`).
/// In constants, None is used to indicate that certain expressions
/// escape into 'static and should have no local cleanup scope.
rvalue_scopes: FxHashMap<hir::ItemLocalId, Option<CodeExtent>>,
rvalue_scopes: FxHashMap<hir::ItemLocalId, Option<Scope>>,
/// Encodes the hierarchy of fn bodies. Every fn body (including
/// closures) forms its own distinct region hierarchy, rooted in
@ -250,7 +248,7 @@ pub struct RegionMaps {
/// If there are any `yield` nested within a scope, this map
/// stores the `Span` of the first one.
yield_in_scope: FxHashMap<CodeExtent, Span>,
yield_in_scope: FxHashMap<Scope, Span>,
}
#[derive(Debug, Copy, Clone)]
@ -264,17 +262,17 @@ pub struct Context {
root_id: Option<hir::ItemLocalId>,
/// the scope that contains any new variables declared
var_parent: Option<CodeExtent>,
var_parent: Option<Scope>,
/// region parent of expressions etc
parent: Option<CodeExtent>,
parent: Option<Scope>,
}
struct RegionResolutionVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Generated maps:
region_maps: RegionMaps,
// Generated scope tree:
scope_tree: ScopeTree,
cx: Context,
@ -302,36 +300,34 @@ struct RegionResolutionVisitor<'a, 'tcx: 'a> {
}
impl<'tcx> RegionMaps {
pub fn record_code_extent(&mut self,
child: CodeExtent,
parent: Option<CodeExtent>) {
impl<'tcx> ScopeTree {
pub fn record_scope_parent(&mut self, child: Scope, parent: Option<Scope>) {
debug!("{:?}.parent = {:?}", child, parent);
if let Some(p) = parent {
let prev = self.scope_map.insert(child, p);
let prev = self.parent_map.insert(child, p);
assert!(prev.is_none());
}
// record the destruction scopes for later so we can query them
if let CodeExtent::DestructionScope(n) = child {
if let Scope::Destruction(n) = child {
self.destruction_scopes.insert(n, child);
}
}
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(CodeExtent, CodeExtent) {
for (&child, &parent) in &self.scope_map {
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(Scope, Scope) {
for (&child, &parent) in &self.parent_map {
e(child, parent)
}
}
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&hir::ItemLocalId, CodeExtent) {
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&hir::ItemLocalId, Scope) {
for (child, &parent) in self.var_map.iter() {
e(child, parent)
}
}
pub fn opt_destruction_extent(&self, n: hir::ItemLocalId) -> Option<CodeExtent> {
pub fn opt_destruction_scope(&self, n: hir::ItemLocalId) -> Option<Scope> {
self.destruction_scopes.get(&n).cloned()
}
@ -360,13 +356,13 @@ impl<'tcx> RegionMaps {
}
}
fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: CodeExtent) {
fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.item_local_id());
self.var_map.insert(var, lifetime);
}
fn record_rvalue_scope(&mut self, var: hir::ItemLocalId, lifetime: Option<CodeExtent>) {
fn record_rvalue_scope(&mut self, var: hir::ItemLocalId, lifetime: Option<Scope>) {
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
if let Some(lifetime) = lifetime {
assert!(var != lifetime.item_local_id());
@ -374,26 +370,26 @@ impl<'tcx> RegionMaps {
self.rvalue_scopes.insert(var, lifetime);
}
pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
pub fn opt_encl_scope(&self, id: Scope) -> Option<Scope> {
//! Returns the narrowest scope that encloses `id`, if any.
self.scope_map.get(&id).cloned()
self.parent_map.get(&id).cloned()
}
#[allow(dead_code)] // used in cfg
pub fn encl_scope(&self, id: CodeExtent) -> CodeExtent {
pub fn encl_scope(&self, id: Scope) -> Scope {
//! 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: hir::ItemLocalId) -> CodeExtent {
pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
match self.var_map.get(&var_id) {
Some(&r) => r,
None => { bug!("no enclosing scope for id {:?}", var_id); }
}
}
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<CodeExtent> {
pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
//! Returns the scope when temp created by expr_id will be cleaned up
// check for a designated rvalue scope
@ -406,11 +402,11 @@ impl<'tcx> RegionMaps {
// if there's one. Static items, for instance, won't
// have an enclosing scope, hence no scope will be
// returned.
let mut id = CodeExtent::Misc(expr_id);
let mut id = Scope::Node(expr_id);
while let Some(&p) = self.scope_map.get(&id) {
while let Some(&p) = self.parent_map.get(&id) {
match p {
CodeExtent::DestructionScope(..) => {
Scope::Destruction(..) => {
debug!("temporary_scope({:?}) = {:?} [enclosing]",
expr_id, id);
return Some(id);
@ -431,7 +427,7 @@ impl<'tcx> RegionMaps {
scope
}
pub fn scopes_intersect(&self, scope1: CodeExtent, scope2: CodeExtent)
pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope)
-> bool {
self.is_subscope_of(scope1, scope2) ||
self.is_subscope_of(scope2, scope1)
@ -440,8 +436,8 @@ impl<'tcx> RegionMaps {
/// Returns true if `subscope` is equal to or is lexically nested inside `superscope` and false
/// otherwise.
pub fn is_subscope_of(&self,
subscope: CodeExtent,
superscope: CodeExtent)
subscope: Scope,
superscope: Scope)
-> bool {
let mut s = subscope;
debug!("is_subscope_of({:?}, {:?})", subscope, superscope);
@ -465,22 +461,22 @@ impl<'tcx> 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: Scope,
scope_b: Scope)
-> Scope {
if scope_a == scope_b { return scope_a; }
// [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> = vec![];
let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32];
let mut b_vec: Vec<CodeExtent> = 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_buf: [Scope; 32] = [scope_a /* [1] */; 32];
let mut a_vec: Vec<Scope> = vec![];
let mut b_buf: [Scope; 32] = [scope_b /* [1] */; 32];
let mut b_vec: Vec<Scope> = vec![];
let parent_map = &self.parent_map;
let a_ancestors = ancestors_of(parent_map, scope_a, &mut a_buf, &mut a_vec);
let b_ancestors = ancestors_of(parent_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;
@ -501,8 +497,8 @@ impl<'tcx> RegionMaps {
let a_root_scope = a_ancestors[a_index];
let b_root_scope = a_ancestors[a_index];
return match (a_root_scope, b_root_scope) {
(CodeExtent::DestructionScope(a_root_id),
CodeExtent::DestructionScope(b_root_id)) => {
(Scope::Destruction(a_root_id),
Scope::Destruction(b_root_id)) => {
if self.closure_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
@ -515,7 +511,7 @@ impl<'tcx> RegionMaps {
}
}
_ => {
// root ids are always Misc right now
// root ids are always Node right now
bug!()
}
};
@ -533,18 +529,18 @@ impl<'tcx> RegionMaps {
}
}
fn ancestors_of<'a, 'tcx>(scope_map: &FxHashMap<CodeExtent, CodeExtent>,
scope: CodeExtent,
buf: &'a mut [CodeExtent; 32],
vec: &'a mut Vec<CodeExtent>)
-> &'a [CodeExtent] {
fn ancestors_of<'a, 'tcx>(parent_map: &FxHashMap<Scope, Scope>,
scope: Scope,
buf: &'a mut [Scope; 32],
vec: &'a mut Vec<Scope>)
-> &'a [Scope] {
// debug!("ancestors_of(scope={:?})", scope);
let mut scope = scope;
let mut i = 0;
while i < 32 {
buf[i] = scope;
match scope_map.get(&scope) {
match parent_map.get(&scope) {
Some(&superscope) => scope = superscope,
_ => return &buf[..i+1]
}
@ -555,7 +551,7 @@ impl<'tcx> RegionMaps {
vec.extend_from_slice(buf);
loop {
vec.push(scope);
match scope_map.get(&scope) {
match parent_map.get(&scope) {
Some(&superscope) => scope = superscope,
_ => return &*vec
}
@ -563,11 +559,11 @@ impl<'tcx> RegionMaps {
}
}
/// Assuming that the provided region was defined within this `RegionMaps`,
/// returns the outermost `CodeExtent` that the region outlives.
pub fn early_free_extent<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
/// Assuming that the provided region was defined within this `ScopeTree`,
/// returns the outermost `Scope` that the region outlives.
pub fn early_free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
br: &ty::EarlyBoundRegion)
-> CodeExtent {
-> Scope {
let param_owner = tcx.parent_def_id(br.def_id).unwrap();
let param_owner_id = tcx.hir.as_local_node_id(param_owner).unwrap();
@ -578,7 +574,8 @@ impl<'tcx> RegionMaps {
// which in practice can only mean a trait or an impl, that
// is the parent of a method, and that is enforced below.
assert_eq!(Some(param_owner_id), self.root_parent,
"free_extent: {:?} not recognized by the region maps for {:?} / {:?}",
"free_scope: {:?} not recognized by the \
region scope tree for {:?} / {:?}",
param_owner,
self.root_parent.map(|id| tcx.hir.local_def_id(id)),
self.root_body.map(|hir_id| DefId::local(hir_id.owner)));
@ -587,13 +584,13 @@ impl<'tcx> RegionMaps {
self.root_body.unwrap().local_id
});
CodeExtent::CallSiteScope(scope)
Scope::CallSite(scope)
}
/// Assuming that the provided region was defined within this `RegionMaps`,
/// returns the outermost `CodeExtent` that the region outlives.
pub fn free_extent<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, fr: &ty::FreeRegion)
-> CodeExtent {
/// Assuming that the provided region was defined within this `ScopeTree`,
/// returns the outermost `Scope` that the region outlives.
pub fn free_scope<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, fr: &ty::FreeRegion)
-> Scope {
let param_owner = match fr.bound_region {
ty::BoundRegion::BrNamed(def_id, _) => {
tcx.parent_def_id(def_id).unwrap()
@ -607,12 +604,12 @@ impl<'tcx> RegionMaps {
let param_owner_id = tcx.hir.as_local_node_id(param_owner).unwrap();
let body_id = tcx.hir.body_owned_by(param_owner_id);
CodeExtent::CallSiteScope(tcx.hir.body(body_id).value.hir_id.local_id)
Scope::CallSite(tcx.hir.body(body_id).value.hir_id.local_id)
}
/// Checks whether the given code extent contains a `yield`. If so,
/// Checks whether the given scope contains a `yield`. If so,
/// returns `Some(span)` with the span of a yield we found.
pub fn yield_in_scope(&self, scope: CodeExtent) -> Option<Span> {
pub fn yield_in_scope(&self, scope: Scope) -> Option<Span> {
self.yield_in_scope.get(&scope).cloned()
}
}
@ -628,7 +625,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
// extern fn isalnum(c: c_int) -> c_int
}
Some(parent_scope) =>
visitor.region_maps.record_var_scope(var_id, parent_scope),
visitor.scope_tree.record_var_scope(var_id, parent_scope),
}
}
@ -662,7 +659,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
// `other_argument()` has run and also the call to `quux(..)`
// itself has returned.
visitor.enter_node_extent_with_dtor(blk.hir_id.local_id);
visitor.enter_node_scope_with_dtor(blk.hir_id.local_id);
visitor.cx.var_parent = visitor.cx.parent;
{
@ -679,8 +676,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
// has the previous subscope in the block as a parent,
// except for the first such subscope, which has the
// block itself as a parent.
visitor.enter_code_extent(
CodeExtent::Remainder(BlockRemainder {
visitor.enter_scope(
Scope::Remainder(BlockRemainder {
block: blk.hir_id.local_id,
first_statement_index: i as u32
})
@ -706,7 +703,7 @@ fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &
}
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: &'tcx hir::Pat) {
visitor.record_code_extent(CodeExtent::Misc(pat.hir_id.local_id));
visitor.record_child_scope(Scope::Node(pat.hir_id.local_id));
// If this is a binding then record the lifetime of that binding.
if let PatKind::Binding(..) = pat.node {
@ -722,13 +719,13 @@ fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt:
// Every statement will clean up the temporaries created during
// execution of that statement. Therefore each statement has an
// associated destruction scope that represents the extent of the
// statement plus its destructors, and thus the extent for which
// associated destruction scope that represents the scope of the
// statement plus its destructors, and thus the scope for which
// regions referenced by the destructors need to survive.
visitor.terminating_scopes.insert(stmt_id);
let prev_parent = visitor.cx.parent;
visitor.enter_node_extent_with_dtor(stmt_id);
visitor.enter_node_scope_with_dtor(stmt_id);
intravisit::walk_stmt(visitor, stmt);
@ -739,7 +736,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
debug!("resolve_expr(expr.id={:?})", expr.id);
let prev_cx = visitor.cx;
visitor.enter_node_extent_with_dtor(expr.hir_id.local_id);
visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);
{
let terminating_scopes = &mut visitor.terminating_scopes;
@ -806,9 +803,9 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
hir::ExprYield(..) => {
// Mark this expr's scope and all parent scopes as containing `yield`.
let mut scope = CodeExtent::Misc(expr.hir_id.local_id);
let mut scope = Scope::Node(expr.hir_id.local_id);
loop {
match visitor.region_maps.yield_in_scope.entry(scope) {
match visitor.scope_tree.yield_in_scope.entry(scope) {
// Another `yield` has already been found.
Entry::Occupied(_) => break,
@ -818,9 +815,9 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
}
// Keep traversing up while we can.
match visitor.region_maps.scope_map.get(&scope) {
match visitor.scope_tree.parent_map.get(&scope) {
// Don't cross from closure bodies to their parent.
Some(&CodeExtent::CallSiteScope(_)) => break,
Some(&Scope::CallSite(_)) => break,
Some(&superscope) => scope = superscope,
None => break
}
@ -999,7 +996,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
fn record_rvalue_scope_if_borrow_expr<'a, 'tcx>(
visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
expr: &hir::Expr,
blk_id: Option<CodeExtent>)
blk_id: Option<Scope>)
{
match expr.node {
hir::ExprAddrOf(_, ref subexpr) => {
@ -1049,7 +1046,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
expr: &hir::Expr,
blk_scope: Option<CodeExtent>) {
blk_scope: Option<Scope>) {
let mut expr = expr;
loop {
// Note: give all the expressions matching `ET` with the
@ -1057,7 +1054,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
// because in trans if we must compile e.g. `*rvalue()`
// into a temporary, we request the temporary scope of the
// outer expression.
visitor.region_maps.record_rvalue_scope(expr.hir_id.local_id, blk_scope);
visitor.scope_tree.record_rvalue_scope(expr.hir_id.local_id, blk_scope);
match expr.node {
hir::ExprAddrOf(_, ref subexpr) |
@ -1077,27 +1074,27 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> {
/// Records the current parent (if any) as the parent of `child_scope`.
fn record_code_extent(&mut self, child_scope: CodeExtent) {
fn record_child_scope(&mut self, child_scope: Scope) {
let parent = self.cx.parent;
self.region_maps.record_code_extent(child_scope, parent);
self.scope_tree.record_scope_parent(child_scope, parent);
}
/// Records the current parent (if any) as the parent of `child_scope`,
/// and sets `child_scope` as the new current parent.
fn enter_code_extent(&mut self, child_scope: CodeExtent) {
self.record_code_extent(child_scope);
fn enter_scope(&mut self, child_scope: Scope) {
self.record_child_scope(child_scope);
self.cx.parent = Some(child_scope);
}
fn enter_node_extent_with_dtor(&mut self, id: hir::ItemLocalId) {
fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
// 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
// account for the destruction scope representing the scope of
// the destructors that run immediately after it completes.
if self.terminating_scopes.contains(&id) {
self.enter_code_extent(CodeExtent::DestructionScope(id));
self.enter_scope(Scope::Destruction(id));
}
self.enter_code_extent(CodeExtent::Misc(id));
self.enter_scope(Scope::Node(id));
}
}
@ -1125,12 +1122,12 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
self.terminating_scopes.insert(body.value.hir_id.local_id);
if let Some(root_id) = self.cx.root_id {
self.region_maps.record_closure_parent(body.value.hir_id.local_id, root_id);
self.scope_tree.record_closure_parent(body.value.hir_id.local_id, root_id);
}
self.cx.root_id = Some(body.value.hir_id.local_id);
self.enter_code_extent(CodeExtent::CallSiteScope(body.value.hir_id.local_id));
self.enter_code_extent(CodeExtent::ParameterScope(body.value.hir_id.local_id));
self.enter_scope(Scope::CallSite(body.value.hir_id.local_id));
self.enter_scope(Scope::Arguments(body.value.hir_id.local_id));
// The arguments and `self` are parented to the fn.
self.cx.var_parent = self.cx.parent.take();
@ -1187,19 +1184,19 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
}
}
fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> Rc<RegionMaps>
fn region_scope_tree<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> Rc<ScopeTree>
{
let closure_base_def_id = tcx.closure_base_def_id(def_id);
if closure_base_def_id != def_id {
return tcx.region_maps(closure_base_def_id);
return tcx.region_scope_tree(closure_base_def_id);
}
let id = tcx.hir.as_local_node_id(def_id).unwrap();
let maps = if let Some(body_id) = tcx.hir.maybe_body_owned_by(id) {
let scope_tree = if let Some(body_id) = tcx.hir.maybe_body_owned_by(id) {
let mut visitor = RegionResolutionVisitor {
tcx,
region_maps: RegionMaps::default(),
scope_tree: ScopeTree::default(),
cx: Context {
root_id: None,
parent: None,
@ -1209,7 +1206,7 @@ fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
};
let body = tcx.hir.body(body_id);
visitor.region_maps.root_body = Some(body.value.hir_id);
visitor.scope_tree.root_body = Some(body.value.hir_id);
// If the item is an associated const or a method,
// record its impl/trait parent, as it can also have
@ -1217,24 +1214,24 @@ fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
match tcx.hir.get(id) {
hir::map::NodeImplItem(_) |
hir::map::NodeTraitItem(_) => {
visitor.region_maps.root_parent = Some(tcx.hir.get_parent(id));
visitor.scope_tree.root_parent = Some(tcx.hir.get_parent(id));
}
_ => {}
}
visitor.visit_body(body);
visitor.region_maps
visitor.scope_tree
} else {
RegionMaps::default()
ScopeTree::default()
};
Rc::new(maps)
Rc::new(scope_tree)
}
pub fn provide(providers: &mut Providers) {
*providers = Providers {
region_maps,
region_scope_tree,
..*providers
};
}

View File

@ -12,7 +12,7 @@
use graphviz::IntoCow;
use middle::const_val::ConstVal;
use middle::region::CodeExtent;
use middle::region;
use rustc_const_math::{ConstUsize, ConstInt, ConstMathErr};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
@ -918,9 +918,9 @@ pub enum StatementKind<'tcx> {
/// See <https://internals.rust-lang.org/t/types-as-contracts/5562/73> for more details.
Validate(ValidationOp, Vec<ValidationOperand<'tcx, Lvalue<'tcx>>>),
/// Mark one terminating point of an extent (i.e. static region).
/// Mark one terminating point of a region scope (i.e. static region).
/// (The starting point(s) arise implicitly from borrows.)
EndRegion(CodeExtent),
EndRegion(region::Scope),
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
@ -939,7 +939,7 @@ pub enum ValidationOp {
Release,
/// Recursive traverse the *mutable* part of the type and relinquish all exclusive
/// access *until* the given region ends. Then, access will be recovered.
Suspend(CodeExtent),
Suspend(region::Scope),
}
impl Debug for ValidationOp {
@ -959,7 +959,7 @@ impl Debug for ValidationOp {
pub struct ValidationOperand<'tcx, T> {
pub lval: T,
pub ty: Ty<'tcx>,
pub re: Option<CodeExtent>,
pub re: Option<region::Scope>,
pub mutbl: hir::Mutability,
}
@ -1709,11 +1709,11 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
inputs: inputs.fold_with(folder)
},
// Note for future: If we want to expose the extents
// Note for future: If we want to expose the region scopes
// during the fold, we need to either generalize EndRegion
// to carry `[ty::Region]`, or extend the `TypeFolder`
// trait with a `fn fold_extent`.
EndRegion(ref extent) => EndRegion(extent.clone()),
// trait with a `fn fold_scope`.
EndRegion(ref region_scope) => EndRegion(region_scope.clone()),
Validate(ref op, ref lvals) =>
Validate(op.clone(),
@ -1738,11 +1738,11 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
InlineAsm { ref outputs, ref inputs, .. } =>
outputs.visit_with(visitor) || inputs.visit_with(visitor),
// Note for future: If we want to expose the extents
// Note for future: If we want to expose the region scopes
// during the visit, we need to either generalize EndRegion
// to carry `[ty::Region]`, or extend the `TypeVisitor`
// trait with a `fn visit_extent`.
EndRegion(ref _extent) => false,
// trait with a `fn visit_scope`.
EndRegion(ref _scope) => false,
Validate(ref _op, ref lvalues) =>
lvalues.iter().any(|ty_and_lvalue| ty_and_lvalue.visit_with(visitor)),

View File

@ -17,7 +17,7 @@ pub use self::ObligationCauseCode::*;
use hir;
use hir::def_id::DefId;
use middle::region::RegionMaps;
use middle::region;
use middle::free_region::FreeRegionMap;
use ty::subst::Substs;
use ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, ToPredicate};
@ -532,9 +532,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::default();
let region_scope_tree = region::ScopeTree::default();
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(region_context, &region_maps, &free_regions);
infcx.resolve_regions_and_report_errors(region_context, &region_scope_tree, &free_regions);
let predicates = match infcx.fully_resolve(&predicates) {
Ok(predicates) => predicates,
Err(fixup_err) => {

View File

@ -17,7 +17,7 @@ use lint;
use middle::const_val;
use middle::cstore::{ExternCrate, LinkagePreference};
use middle::privacy::AccessLevels;
use middle::region::RegionMaps;
use middle::region;
use mir;
use mir::transform::{MirSuite, MirPassIndex};
use session::CompileResult;
@ -1080,10 +1080,9 @@ define_maps! { <'tcx>
[] fn 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.
[] fn region_maps: RegionMaps(DefId) -> Rc<RegionMaps>,
/// Per-body `region::ScopeTree`. The `DefId` should be the owner-def-id for the body;
/// in the case of closures, this will be redirected to the enclosing function.
[] fn region_scope_tree: RegionScopeTree(DefId) -> Rc<region::ScopeTree>,
[] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>,

View File

@ -213,8 +213,8 @@ pub enum TypeVariants<'tcx> {
/// as extra type parameters? The reason for this design is that the
/// upvar types can reference lifetimes that are internal to the
/// creating function. In my example above, for example, the lifetime
/// `'b` represents the extent of the closure itself; this is some
/// subset of `foo`, probably just the extent of the call to the to
/// `'b` represents the scope of the closure itself; this is some
/// subset of `foo`, probably just the scope of the call to the to
/// `do()`. If we just had the lifetime/type parameters from the
/// enclosing function, we couldn't name this lifetime `'b`. Note that
/// there can also be lifetimes in the types of the upvars themselves,
@ -845,10 +845,10 @@ pub enum RegionKind {
/// region parameters.
ReFree(FreeRegion),
/// A concrete region naming some statically determined extent
/// A concrete region naming some statically determined scope
/// (e.g. an expression or sequence of statements) within the
/// current function.
ReScope(region::CodeExtent),
ReScope(region::Scope),
/// Static data that has an "infinite" lifetime. Top in the region lattice.
ReStatic,

View File

@ -10,7 +10,7 @@
use hir::def_id::DefId;
use hir::map::definitions::DefPathData;
use middle::region::{CodeExtent, BlockRemainder};
use middle::region::{self, BlockRemainder};
use ty::subst::{self, Subst};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
use ty::{TyBool, TyChar, TyAdt};
@ -524,18 +524,18 @@ impl fmt::Display for ty::RegionKind {
ty::ReSkolemized(_, br) => {
write!(f, "{}", br)
}
ty::ReScope(code_extent) if identify_regions() => {
match code_extent {
CodeExtent::Misc(id) =>
write!(f, "'{}mce", id.as_usize()),
CodeExtent::CallSiteScope(id) =>
write!(f, "'{}cce", id.as_usize()),
CodeExtent::ParameterScope(id) =>
write!(f, "'{}pce", id.as_usize()),
CodeExtent::DestructionScope(id) =>
write!(f, "'{}dce", id.as_usize()),
CodeExtent::Remainder(BlockRemainder { block, first_statement_index }) =>
write!(f, "'{}_{}rce", block.as_usize(), first_statement_index),
ty::ReScope(scope) if identify_regions() => {
match scope {
region::Scope::Node(id) =>
write!(f, "'{}s", id.as_usize()),
region::Scope::CallSite(id) =>
write!(f, "'{}cs", id.as_usize()),
region::Scope::Arguments(id) =>
write!(f, "'{}as", id.as_usize()),
region::Scope::Destruction(id) =>
write!(f, "'{}ds", id.as_usize()),
region::Scope::Remainder(BlockRemainder { block, first_statement_index }) =>
write!(f, "'{}_{}rs", block.as_usize(), first_statement_index),
}
}
ty::ReVar(region_vid) if identify_regions() => {

View File

@ -206,7 +206,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
all_loans,
param_env,
};
euv::ExprUseVisitor::new(&mut clcx, bccx.tcx, param_env, &bccx.region_maps, bccx.tables)
euv::ExprUseVisitor::new(&mut clcx, bccx.tcx, param_env, &bccx.region_scope_tree, bccx.tables)
.consume_body(body);
}
@ -240,14 +240,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::Scope, mut op: F) -> bool where
F: FnMut(&Loan<'tcx>) -> bool,
{
//! Like `each_issued_loan()`, but only considers loans that are
//! currently in scope.
self.each_issued_loan(scope.item_local_id(), |loan| {
if self.bccx.region_maps.is_subscope_of(scope, loan.kill_scope) {
if self.bccx.region_scope_tree.is_subscope_of(scope, loan.kill_scope) {
op(loan)
} else {
true
@ -256,7 +256,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
}
fn each_in_scope_loan_affecting_path<F>(&self,
scope: region::CodeExtent,
scope: region::Scope,
loan_path: &LoanPath<'tcx>,
mut op: F)
-> bool where
@ -386,7 +386,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
new_loan);
// Should only be called for loans that are in scope at the same time.
assert!(self.bccx.region_maps.scopes_intersect(old_loan.kill_scope,
assert!(self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope,
new_loan.kill_scope));
self.report_error_if_loan_conflicts_with_restriction(
@ -467,7 +467,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
// 3. Where does old loan expire.
let previous_end_span =
old_loan.kill_scope.span(self.tcx(), &self.bccx.region_maps).end_point();
old_loan.kill_scope.span(self.tcx(), &self.bccx.region_scope_tree).end_point();
let mut err = match (new_loan.kind, old_loan.kind) {
(ty::MutBorrow, ty::MutBorrow) => {
@ -714,7 +714,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
let mut ret = UseOk;
self.each_in_scope_loan_affecting_path(
region::CodeExtent::Misc(expr_id), use_path, |loan| {
region::Scope::Node(expr_id), use_path, |loan| {
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
false
@ -833,7 +833,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 = region::CodeExtent::Misc(assignment_id);
let scope = region::Scope::Node(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,7 +24,7 @@ use syntax_pos::Span;
type R = Result<(),()>;
pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
item_scope: region::CodeExtent,
item_scope: region::Scope,
span: Span,
cause: euv::LoanCause,
cmt: mc::cmt<'tcx>,
@ -52,7 +52,7 @@ 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::Scope,
span: Span,
cause: euv::LoanCause,
@ -117,7 +117,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
Categorization::Local(local_id) => {
let hir_id = self.bccx.tcx.hir.node_to_hir_id(local_id);
self.bccx.tcx.mk_region(ty::ReScope(
self.bccx.region_maps.var_scope(hir_id.local_id)))
self.bccx.region_scope_tree.var_scope(hir_id.local_id)))
}
Categorization::StaticItem |
Categorization::Deref(_, mc::UnsafePtr(..)) => {

View File

@ -43,12 +43,12 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
let mut glcx = GatherLoanCtxt {
bccx,
all_loans: Vec::new(),
item_ub: region::CodeExtent::Misc(bccx.tcx.hir.body(body).value.hir_id.local_id),
item_ub: region::Scope::Node(bccx.tcx.hir.body(body).value.hir_id.local_id),
move_data: MoveData::default(),
move_error_collector: move_error::MoveErrorCollector::new(),
};
euv::ExprUseVisitor::new(&mut glcx, bccx.tcx, param_env, &bccx.region_maps, bccx.tables)
euv::ExprUseVisitor::new(&mut glcx, bccx.tcx, param_env, &bccx.region_scope_tree, bccx.tables)
.consume_body(bccx.body);
glcx.report_potential_errors();
@ -63,7 +63,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::Scope,
}
impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
@ -351,11 +351,11 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
ty::ReScope(scope) => scope,
ty::ReEarlyBound(ref br) => {
self.bccx.region_maps.early_free_extent(self.tcx(), br)
self.bccx.region_scope_tree.early_free_scope(self.tcx(), br)
}
ty::ReFree(ref fr) => {
self.bccx.region_maps.free_extent(self.tcx(), fr)
self.bccx.region_scope_tree.free_scope(self.tcx(), fr)
}
ty::ReStatic => self.item_ub,
@ -373,7 +373,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
};
debug!("loan_scope = {:?}", loan_scope);
let borrow_scope = region::CodeExtent::Misc(borrow_id);
let borrow_scope = region::Scope::Node(borrow_id);
let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope);
debug!("gen_scope = {:?}", gen_scope);
@ -473,23 +473,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::Scope,
loan_scope: region::Scope)
-> region::Scope {
//! 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.region_maps.is_subscope_of(borrow_scope, loan_scope) {
if self.bccx.region_scope_tree.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::Scope, lp: &LoanPath<'tcx>)
-> region::Scope {
//! 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,
@ -512,10 +512,10 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
//! do not require restrictions and hence do not cause a loan.
let lexical_scope = lp.kill_scope(self.bccx);
if self.bccx.region_maps.is_subscope_of(lexical_scope, loan_scope) {
if self.bccx.region_scope_tree.is_subscope_of(lexical_scope, loan_scope) {
lexical_scope
} else {
assert!(self.bccx.region_maps.is_subscope_of(loan_scope, lexical_scope));
assert!(self.bccx.region_scope_tree.is_subscope_of(loan_scope, lexical_scope));
loan_scope
}
}

View File

@ -32,7 +32,7 @@ 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::{self, RegionMaps};
use rustc::middle::region;
use rustc::middle::free_region::RegionRelations;
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::Providers;
@ -98,9 +98,9 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
let body_id = tcx.hir.body_owned_by(owner_id);
let tables = tcx.typeck_tables_of(owner_def_id);
let region_maps = tcx.region_maps(owner_def_id);
let region_scope_tree = tcx.region_scope_tree(owner_def_id);
let body = tcx.hir.body(body_id);
let bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id, body };
let bccx = &mut BorrowckCtxt { tcx, tables, region_scope_tree, owner_def_id, body };
// Eventually, borrowck will always read the MIR, but at the
// moment we do not. So, for now, we always force MIR to be
@ -196,9 +196,9 @@ 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 region_maps = tcx.region_maps(owner_def_id);
let region_scope_tree = tcx.region_scope_tree(owner_def_id);
let body = tcx.hir.body(body_id);
let mut bccx = BorrowckCtxt { tcx, tables, region_maps, owner_def_id, body };
let mut bccx = BorrowckCtxt { tcx, tables, region_scope_tree, owner_def_id, body };
let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg);
(bccx, dataflow_data.unwrap())
@ -214,7 +214,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
// Some in `borrowck_fn` and cleared later
tables: &'a ty::TypeckTables<'tcx>,
region_maps: Rc<RegionMaps>,
region_scope_tree: Rc<region::ScopeTree>,
owner_def_id: DefId,
@ -255,13 +255,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::Scope,
/// 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::Scope,
span: Span,
cause: euv::LoanCause,
}
@ -362,16 +362,16 @@ fn closure_to_block(closure_id: DefIndex,
}
impl<'a, 'tcx> LoanPath<'tcx> {
pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::CodeExtent {
pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::Scope {
match self.kind {
LpVar(local_id) => {
let hir_id = bccx.tcx.hir.node_to_hir_id(local_id);
bccx.region_maps.var_scope(hir_id.local_id)
bccx.region_scope_tree.var_scope(hir_id.local_id)
}
LpUpvar(upvar_id) => {
let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx);
let hir_id = bccx.tcx.hir.node_to_hir_id(block_id);
region::CodeExtent::Misc(hir_id.local_id)
region::Scope::Node(hir_id.local_id)
}
LpDowncast(ref base, _) |
LpExtend(ref base, ..) => base.kill_scope(bccx),
@ -535,7 +535,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
{
let region_rels = RegionRelations::new(self.tcx,
self.owner_def_id,
&self.region_maps,
&self.region_scope_tree,
&self.tables.free_region_map);
region_rels.is_subregion_of(r_sub, r_sup)
}
@ -820,18 +820,18 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
debug!("err_out_of_scope: self.body.is_generator = {:?}",
self.body.is_generator);
let maybe_borrow_across_yield = if self.body.is_generator {
let body_extent = region::CodeExtent::Misc(self.body.value.hir_id.local_id);
debug!("err_out_of_scope: body_extent = {:?}", body_extent);
let body_scope = region::Scope::Node(self.body.value.hir_id.local_id);
debug!("err_out_of_scope: body_scope = {:?}", body_scope);
debug!("err_out_of_scope: super_scope = {:?}", super_scope);
debug!("err_out_of_scope: sub_scope = {:?}", sub_scope);
match (super_scope, sub_scope) {
(&ty::RegionKind::ReScope(value_extent),
&ty::RegionKind::ReScope(loan_extent)) => {
(&ty::RegionKind::ReScope(value_scope),
&ty::RegionKind::ReScope(loan_scope)) => {
if {
// value_extent <= body_extent &&
self.region_maps.is_subscope_of(value_extent, body_extent) &&
// body_extent <= loan_extent
self.region_maps.is_subscope_of(body_extent, loan_extent)
// value_scope <= body_scope &&
self.region_scope_tree.is_subscope_of(value_scope, body_scope) &&
// body_scope <= loan_scope
self.region_scope_tree.is_subscope_of(body_scope, loan_scope)
} {
// We now know that this is a case
// that fits the bill described above:
@ -846,7 +846,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
// block remainder that starts with
// `let a`) for a yield. We can cite
// that for the user.
self.region_maps.yield_in_scope(value_extent)
self.region_scope_tree.yield_in_scope(value_scope)
} else {
None
}
@ -945,7 +945,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
None => {
self.tcx.note_and_explain_region(
&self.region_maps,
&self.region_scope_tree,
&mut db,
"borrowed value must be valid for ",
sub_scope,
@ -958,7 +958,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
None => {
self.tcx.note_and_explain_region(
&self.region_maps,
&self.region_scope_tree,
&mut db,
"...but borrowed value is only valid for ",
super_scope,
@ -969,7 +969,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
if let ty::ReScope(scope) = *super_scope {
let node_id = scope.node_id(self.tcx, &self.region_maps);
let node_id = scope.node_id(self.tcx, &self.region_scope_tree);
match self.tcx.hir.find(node_id) {
Some(hir_map::NodeStmt(_)) => {
db.note("consider using a `let` binding to increase its lifetime");
@ -994,14 +994,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
None => self.cmt_to_string(&err.cmt),
};
self.tcx.note_and_explain_region(
&self.region_maps,
&self.region_scope_tree,
&mut db,
&format!("{} would have to be valid for ",
descr),
loan_scope,
"...");
self.tcx.note_and_explain_region(
&self.region_maps,
&self.region_scope_tree,
&mut db,
&format!("...but {} is only valid for ", descr),
ptr_scope,
@ -1257,7 +1257,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
match *region {
ty::ReScope(scope) => {
Some(scope.span(self.tcx, &self.region_maps).end_point())
Some(scope.span(self.tcx, &self.region_scope_tree).end_point())
}
_ => None
}

View File

@ -18,7 +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::middle::region;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::Substs;
@ -51,7 +51,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
MatchVisitor {
tcx: self.tcx,
tables: self.tcx.body_tables(b),
region_maps: &self.tcx.region_maps(def_id),
region_scope_tree: &self.tcx.region_scope_tree(def_id),
param_env: self.tcx.param_env(def_id),
identity_substs: Substs::identity_for_item(self.tcx, def_id),
}.visit_body(self.tcx.hir.body(b));
@ -72,7 +72,7 @@ struct MatchVisitor<'a, 'tcx: 'a> {
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
identity_substs: &'tcx Substs<'tcx>,
region_maps: &'a RegionMaps,
region_scope_tree: &'a region::ScopeTree,
}
impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
@ -526,7 +526,7 @@ fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) {
let mut checker = MutationChecker {
cx,
};
ExprUseVisitor::new(&mut checker, cx.tcx, cx.param_env, cx.region_maps, cx.tables)
ExprUseVisitor::new(&mut checker, cx.tcx, cx.param_env, cx.region_scope_tree, cx.tables)
.walk_expr(guard);
}

View File

@ -17,7 +17,7 @@ use rustc_resolve::MakeGlobMap;
use rustc_trans;
use rustc::middle::lang_items;
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::{CodeExtent, RegionMaps};
use rustc::middle::region;
use rustc::middle::resolve_lifetime;
use rustc::middle::stability;
use rustc::ty::subst::{Kind, Subst};
@ -45,7 +45,7 @@ use rustc::hir;
struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>,
region_maps: &'a mut RegionMaps,
region_scope_tree: &'a mut region::ScopeTree,
param_env: ty::ParamEnv<'tcx>,
}
@ -157,15 +157,15 @@ fn test_env<F>(source_string: &str,
"test_crate",
|tcx| {
tcx.infer_ctxt().enter(|infcx| {
let mut region_maps = RegionMaps::default();
let mut region_scope_tree = region::ScopeTree::default();
body(Env {
infcx: &infcx,
region_maps: &mut region_maps,
region_scope_tree: &mut region_scope_tree,
param_env: ty::ParamEnv::empty(Reveal::UserFacing),
});
let free_regions = FreeRegionMap::new();
let def_id = tcx.hir.local_def_id(ast::CRATE_NODE_ID);
infcx.resolve_regions_and_report_errors(def_id, &region_maps, &free_regions);
infcx.resolve_regions_and_report_errors(def_id, &region_scope_tree, &free_regions);
assert_eq!(tcx.sess.err_count(), expected_err_count);
});
});
@ -176,9 +176,9 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
self.infcx.tcx
}
pub fn create_region_hierarchy(&mut self, rh: &RH, parent: CodeExtent) {
let me = CodeExtent::Misc(rh.id);
self.region_maps.record_code_extent(me, Some(parent));
pub fn create_region_hierarchy(&mut self, rh: &RH, parent: region::Scope) {
let me = region::Scope::Node(rh.id);
self.region_scope_tree.record_scope_parent(me, Some(parent));
for child_rh in rh.sub {
self.create_region_hierarchy(child_rh, me);
}
@ -188,8 +188,8 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
// creates a region hierarchy where 1 is root, 10 and 11 are
// children of 1, etc
let dscope = CodeExtent::DestructionScope(hir::ItemLocalId(1));
self.region_maps.record_code_extent(dscope, None);
let dscope = region::Scope::Destruction(hir::ItemLocalId(1));
self.region_scope_tree.record_scope_parent(dscope, None);
self.create_region_hierarchy(&RH {
id: hir::ItemLocalId(1),
sub: &[RH {
@ -333,7 +333,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
}
pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> {
let r = ty::ReScope(CodeExtent::Misc(hir::ItemLocalId(id)));
let r = ty::ReScope(region::Scope::Node(hir::ItemLocalId(id)));
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
}

View File

@ -603,7 +603,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
//
// (Or if you prefer, all the *other* iterations over loans
// only consider loans that are in scope of some given
// CodeExtent)
// region::Scope)
//
// The (currently skeletal) code here does not encode such a
// distinction, which means it is almost certainly over

View File

@ -21,10 +21,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ast_block: &'tcx hir::Block,
source_info: SourceInfo)
-> BlockAnd<()> {
let Block { extent, opt_destruction_extent, span, stmts, expr, targeted_by_break } =
let Block { region_scope, opt_destruction_scope, span, stmts, expr, targeted_by_break } =
self.hir.mirror(ast_block);
self.in_opt_scope(opt_destruction_extent.map(|de|(de, source_info)), block, move |this| {
this.in_scope((extent, source_info), block, move |this| {
self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
this.in_scope((region_scope, source_info), block, move |this| {
if targeted_by_break {
// This is a `break`-able block (currently only `catch { ... }`)
let exit_block = this.cfg.start_new_block();
@ -67,15 +67,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// the let-scopes at the end.
//
// First we build all the statements in the block.
let mut let_extent_stack = Vec::with_capacity(8);
let mut let_scope_stack = Vec::with_capacity(8);
let outer_visibility_scope = this.visibility_scope;
let source_info = this.source_info(span);
for stmt in stmts {
let Stmt { kind, opt_destruction_extent } = this.hir.mirror(stmt);
let Stmt { kind, opt_destruction_scope } = this.hir.mirror(stmt);
match kind {
StmtKind::Expr { scope, expr } => {
unpack!(block = this.in_opt_scope(
opt_destruction_extent.map(|de|(de, source_info)), block, |this| {
opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
this.in_scope((scope, source_info), block, |this| {
let expr = this.hir.mirror(expr);
this.stmt_expr(block, expr)
@ -85,17 +85,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
// Enter the remainder scope, i.e. the bindings' destruction scope.
this.push_scope((remainder_scope, source_info));
let_extent_stack.push(remainder_scope);
let_scope_stack.push(remainder_scope);
// Declare the bindings, which may create a visibility scope.
let remainder_span = remainder_scope.span(this.hir.tcx(),
&this.hir.region_maps);
&this.hir.region_scope_tree);
let scope = this.declare_bindings(None, remainder_span, &pattern);
// Evaluate the initializer, if present.
if let Some(init) = initializer {
unpack!(block = this.in_opt_scope(
opt_destruction_extent.map(|de|(de, source_info)), block, move |this| {
opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
this.in_scope((init_scope, source_info), block, move |this| {
// FIXME #30046 ^~~~
this.expr_into_pattern(block, pattern, init)
@ -124,8 +124,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
// Finally, we pop all the let scopes before exiting out from the scope of block
// itself.
for extent in let_extent_stack.into_iter().rev() {
unpack!(block = this.pop_scope((extent, source_info), block));
for scope in let_scope_stack.into_iter().rev() {
unpack!(block = this.pop_scope((scope, source_info), block));
}
// Restore the original visibility scope.
this.visibility_scope = outer_visibility_scope;

View File

@ -14,7 +14,7 @@
//! Routines for manipulating the control-flow graph.
use build::CFG;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::mir::*;
impl<'tcx> CFG<'tcx> {
@ -47,10 +47,10 @@ impl<'tcx> CFG<'tcx> {
pub fn push_end_region(&mut self,
block: BasicBlock,
source_info: SourceInfo,
extent: CodeExtent) {
region_scope: region::Scope) {
self.push(block, Statement {
source_info,
kind: StatementKind::EndRegion(extent),
kind: StatementKind::EndRegion(region_scope),
});
}

View File

@ -29,7 +29,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let Expr { ty, temp_lifetime: _, span, kind }
= expr;
match kind {
ExprKind::Scope { extent: _, value } =>
ExprKind::Scope { region_scope: _, value } =>
this.as_constant(value),
ExprKind::Literal { literal } =>
Constant { span: span, ty: ty, literal: literal },

View File

@ -39,8 +39,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let expr_span = expr.span;
let source_info = this.source_info(expr_span);
match expr.kind {
ExprKind::Scope { extent, value } => {
this.in_scope((extent, source_info), block, |this| this.as_lvalue(block, value))
ExprKind::Scope { region_scope, value } => {
this.in_scope((region_scope, source_info), block, |this| {
this.as_lvalue(block, value)
})
}
ExprKind::Field { lhs, name } => {
let lvalue = unpack!(block = this.as_lvalue(block, lhs));
@ -56,7 +58,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty());
let slice = unpack!(block = this.as_lvalue(block, lhs));
// extent=None so lvalue indexes live forever. They are scalars so they
// region_scope=None so lvalue indexes live forever. They are scalars so they
// do not need storage annotations, and they are often copied between
// places.
let idx = unpack!(block = this.as_operand(block, None, index));

View File

@ -13,7 +13,7 @@
use build::{BlockAnd, BlockAndExtension, Builder};
use build::expr::category::Category;
use hair::*;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::mir::*;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@ -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<region::Scope>,
expr: M) -> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
@ -49,16 +49,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn expr_as_operand(&mut self,
mut block: BasicBlock,
scope: Option<CodeExtent>,
scope: Option<region::Scope>,
expr: Expr<'tcx>)
-> BlockAnd<Operand<'tcx>> {
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
let this = self;
if let ExprKind::Scope { extent, value } = expr.kind {
if let ExprKind::Scope { region_scope, value } = expr.kind {
let source_info = this.source_info(expr.span);
let extent = (extent, source_info);
return this.in_scope(extent, block, |this| {
let region_scope = (region_scope, source_info);
return this.in_scope(region_scope, block, |this| {
this.as_operand(block, scope, value)
});
}

View File

@ -21,7 +21,7 @@ use build::expr::category::{Category, RvalueFunc};
use hair::*;
use rustc_const_math::{ConstInt, ConstIsize};
use rustc::middle::const_val::ConstVal;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::ty;
use rustc::mir::*;
use syntax::ast;
@ -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<region::Scope>, 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<region::Scope>,
expr: Expr<'tcx>)
-> BlockAnd<Rvalue<'tcx>> {
debug!("expr_as_rvalue(block={:?}, scope={:?}, expr={:?})", block, scope, expr);
@ -58,9 +58,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = this.source_info(expr_span);
match expr.kind {
ExprKind::Scope { extent, value } => {
let extent = (extent, source_info);
this.in_scope(extent, block, |this| this.as_rvalue(block, scope, value))
ExprKind::Scope { region_scope, value } => {
let region_scope = (region_scope, source_info);
this.in_scope(region_scope, block, |this| this.as_rvalue(block, scope, value))
}
ExprKind::Repeat { value, count } => {
let value_operand = unpack!(block = this.as_operand(block, scope, value));

View File

@ -13,7 +13,7 @@
use build::{BlockAnd, BlockAndExtension, Builder};
use build::expr::category::Category;
use hair::*;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::mir::*;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@ -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<region::Scope>,
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<region::Scope>,
expr: Expr<'tcx>)
-> BlockAnd<Lvalue<'tcx>> {
debug!("expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?})",
@ -41,8 +41,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let expr_span = expr.span;
let source_info = this.source_info(expr_span);
if let ExprKind::Scope { extent, value } = expr.kind {
return this.in_scope((extent, source_info), block, |this| {
if let ExprKind::Scope { region_scope, value } = expr.kind {
return this.in_scope((region_scope, source_info), block, |this| {
this.as_temp(block, temp_lifetime, value)
});
}

View File

@ -38,9 +38,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = this.source_info(expr_span);
match expr.kind {
ExprKind::Scope { extent, value } => {
let extent = (extent, source_info);
this.in_scope(extent, block, |this| this.into(destination, block, value))
ExprKind::Scope { region_scope, value } => {
let region_scope = (region_scope, source_info);
this.in_scope(region_scope, block, |this| this.into(destination, block, value))
}
ExprKind::Block { body: ast_block } => {
this.ast_block(destination, block, ast_block, source_info)

View File

@ -22,9 +22,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Handle a number of expressions that don't need a destination at all. This
// avoids needing a mountain of temporary `()` variables.
match expr.kind {
ExprKind::Scope { extent, value } => {
ExprKind::Scope { region_scope, value } => {
let value = this.hir.mirror(value);
this.in_scope((extent, source_info), block, |this| this.stmt_expr(block, value))
this.in_scope((region_scope, source_info), block, |this| {
this.stmt_expr(block, value)
})
}
ExprKind::Assign { lhs, rhs } => {
let lhs = this.hir.mirror(lhs);
@ -77,29 +79,29 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block.unit()
}
ExprKind::Continue { label } => {
let BreakableScope { continue_block, extent, .. } =
let BreakableScope { continue_block, region_scope, .. } =
*this.find_breakable_scope(expr_span, label);
let continue_block = continue_block.expect(
"Attempted to continue in non-continuable breakable block");
this.exit_scope(expr_span, (extent, source_info), block, continue_block);
this.exit_scope(expr_span, (region_scope, source_info), block, continue_block);
this.cfg.start_new_block().unit()
}
ExprKind::Break { label, value } => {
let (break_block, extent, destination) = {
let (break_block, region_scope, destination) = {
let BreakableScope {
break_block,
extent,
region_scope,
ref break_destination,
..
} = *this.find_breakable_scope(expr_span, label);
(break_block, extent, break_destination.clone())
(break_block, region_scope, break_destination.clone())
};
if let Some(value) = value {
unpack!(block = this.into(&destination, block, value))
} else {
this.cfg.push_assign_unit(block, source_info, &destination)
}
this.exit_scope(expr_span, (extent, source_info), block, break_block);
this.exit_scope(expr_span, (region_scope, source_info), block, break_block);
this.cfg.start_new_block().unit()
}
ExprKind::Return { value } => {
@ -114,9 +116,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block
}
};
let extent = this.extent_of_return_scope();
let region_scope = this.region_scope_of_return_scope();
let return_block = this.return_block();
this.exit_scope(expr_span, (extent, source_info), block, return_block);
this.exit_scope(expr_span, (region_scope, source_info), block, return_block);
this.cfg.start_new_block().unit()
}
ExprKind::InlineAsm { asm, outputs, inputs } => {

View File

@ -203,8 +203,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let local_id = self.var_indices[&var];
let var_ty = self.local_decls[local_id].ty;
let hir_id = self.hir.tcx().hir.node_to_hir_id(var);
let extent = self.hir.region_maps.var_scope(hir_id.local_id);
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
let region_scope = self.hir.region_scope_tree.var_scope(hir_id.local_id);
self.schedule_drop(span, region_scope, &Lvalue::Local(local_id), var_ty);
}
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)

View File

@ -14,7 +14,7 @@ use hair::cx::Cx;
use hair::Pattern;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
use rustc::mir::visit::{MutVisitor, Lookup};
@ -355,13 +355,13 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
arguments.len(),
return_ty);
let call_site_extent = CodeExtent::CallSiteScope(body.value.hir_id.local_id);
let arg_extent = CodeExtent::ParameterScope(body.value.hir_id.local_id);
let call_site_scope = region::Scope::CallSite(body.value.hir_id.local_id);
let arg_scope = region::Scope::Arguments(body.value.hir_id.local_id);
let mut block = START_BLOCK;
let source_info = builder.source_info(span);
unpack!(block = builder.in_scope((call_site_extent, source_info), block, |builder| {
unpack!(block = builder.in_scope((arg_extent, source_info), block, |builder| {
builder.args_and_body(block, &arguments, arg_extent, &body.value)
unpack!(block = builder.in_scope((call_site_scope, source_info), block, |builder| {
unpack!(block = builder.in_scope((arg_scope, source_info), block, |builder| {
builder.args_and_body(block, &arguments, arg_scope, &body.value)
}));
// Attribute epilogue to function's closing brace
let fn_end = span.with_lo(span.hi());
@ -503,7 +503,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_scope: region::Scope,
ast_body: &'gcx hir::Expr)
-> BlockAnd<()>
{
@ -547,7 +547,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Make sure we drop (parts of) the argument even when not matched on.
self.schedule_drop(pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
argument_extent, &lvalue, ty);
argument_scope, &lvalue, ty);
}

View File

@ -12,7 +12,7 @@
Managing the scope stack. The scopes are tied to lexical scopes, so as
we descend the HAIR, we push a scope on the stack, translate ite
contents, and then pop it off. Every scope is named by a
`CodeExtent`.
`region::Scope`.
### SEME Regions
@ -23,7 +23,7 @@ via a `break` or `return` or just by fallthrough, that marks an exit
from the scope. Each lexical scope thus corresponds to a single-entry,
multiple-exit (SEME) region in the control-flow graph.
For now, we keep a mapping from each `CodeExtent` to its
For now, we keep a mapping from each `region::Scope` to its
corresponding SEME region for later reference (see caveat in next
paragraph). This is because region scopes are tied to
them. Eventually, when we shift to non-lexical lifetimes, there should
@ -88,7 +88,7 @@ should go to.
*/
use build::{BlockAnd, BlockAndExtension, Builder, CFG};
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::ty::Ty;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
@ -101,11 +101,11 @@ pub struct Scope<'tcx> {
/// The visibility scope this scope was created in.
visibility_scope: VisibilityScope,
/// the extent of this scope within source code.
extent: CodeExtent,
/// the region span of this scope within source code.
region_scope: region::Scope,
/// the span of that extent
extent_span: Span,
/// the span of that region_scope
region_scope_span: Span,
/// Whether there's anything to do for the cleanup path, that is,
/// when unwinding through this scope. This includes destructors,
@ -125,7 +125,7 @@ pub struct Scope<'tcx> {
drops: Vec<DropData<'tcx>>,
/// The cache for drop chain on “normal” exit into a particular BasicBlock.
cached_exits: FxHashMap<(BasicBlock, CodeExtent), BasicBlock>,
cached_exits: FxHashMap<(BasicBlock, region::Scope), BasicBlock>,
/// The cache for drop chain on "generator drop" exit.
cached_generator_drop: Option<BasicBlock>,
@ -165,8 +165,8 @@ enum DropKind {
#[derive(Clone, Debug)]
pub struct BreakableScope<'tcx> {
/// Extent of the loop
pub extent: CodeExtent,
/// Region scope of the loop
pub region_scope: region::Scope,
/// 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
@ -269,9 +269,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
f: F) -> R
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R
{
let extent = self.topmost_scope();
let region_scope = self.topmost_scope();
let scope = BreakableScope {
extent,
region_scope,
continue_block: loop_block,
break_block,
break_destination,
@ -279,41 +279,41 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.breakable_scopes.push(scope);
let res = f(self);
let breakable_scope = self.breakable_scopes.pop().unwrap();
assert!(breakable_scope.extent == extent);
assert!(breakable_scope.region_scope == region_scope);
res
}
pub fn in_opt_scope<F, R>(&mut self,
opt_extent: Option<(CodeExtent, SourceInfo)>,
opt_scope: Option<(region::Scope, SourceInfo)>,
mut block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
{
debug!("in_opt_scope(opt_extent={:?}, block={:?})", opt_extent, block);
if let Some(extent) = opt_extent { self.push_scope(extent); }
debug!("in_opt_scope(opt_scope={:?}, block={:?})", opt_scope, block);
if let Some(region_scope) = opt_scope { self.push_scope(region_scope); }
let rv = unpack!(block = f(self));
if let Some(extent) = opt_extent {
unpack!(block = self.pop_scope(extent, block));
if let Some(region_scope) = opt_scope {
unpack!(block = self.pop_scope(region_scope, block));
}
debug!("in_scope: exiting opt_extent={:?} block={:?}", opt_extent, block);
debug!("in_scope: exiting opt_scope={:?} block={:?}", opt_scope, block);
block.and(rv)
}
/// 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, SourceInfo),
region_scope: (region::Scope, SourceInfo),
mut block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
{
debug!("in_scope(extent={:?}, block={:?})", extent, block);
self.push_scope(extent);
debug!("in_scope(region_scope={:?}, block={:?})", region_scope, block);
self.push_scope(region_scope);
let rv = unpack!(block = f(self));
unpack!(block = self.pop_scope(extent, block));
debug!("in_scope: exiting extent={:?} block={:?}", extent, block);
unpack!(block = self.pop_scope(region_scope, block));
debug!("in_scope: exiting region_scope={:?} block={:?}", region_scope, block);
block.and(rv)
}
@ -321,13 +321,13 @@ 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, SourceInfo)) {
debug!("push_scope({:?})", extent);
pub fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo)) {
debug!("push_scope({:?})", region_scope);
let vis_scope = self.visibility_scope;
self.scopes.push(Scope {
visibility_scope: vis_scope,
extent: extent.0,
extent_span: extent.1.span,
region_scope: region_scope.0,
region_scope_span: region_scope.1.span,
needs_cleanup: false,
drops: vec![],
cached_generator_drop: None,
@ -335,14 +335,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
});
}
/// Pops a scope, which should have extent `extent`, adding any
/// drops onto the end of `block` that are needed. This must
/// match 1-to-1 with `push_scope`.
/// Pops a scope, which should have region scope `region_scope`,
/// adding any 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, SourceInfo),
region_scope: (region::Scope, SourceInfo),
mut block: BasicBlock)
-> BlockAnd<()> {
debug!("pop_scope({:?}, {:?})", extent, block);
debug!("pop_scope({:?}, {:?})", region_scope, block);
// If we are emitting a `drop` statement, we need to have the cached
// diverge cleanup pads ready in case that drop panics.
let may_panic =
@ -351,7 +351,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.diverge_cleanup();
}
let scope = self.scopes.pop().unwrap();
assert_eq!(scope.extent, extent.0);
assert_eq!(scope.region_scope, region_scope.0);
unpack!(block = build_scope_drops(&mut self.cfg,
&scope,
&self.scopes,
@ -359,25 +359,27 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.arg_count,
false));
self.cfg.push_end_region(block, extent.1, scope.extent);
self.cfg.push_end_region(block, region_scope.1, scope.region_scope);
block.unit()
}
/// Branch out of `block` to `target`, exiting all scopes up to
/// and including `extent`. This will insert whatever drops are
/// and including `region_scope`. This will insert whatever drops are
/// needed, as well as tracking this exit for the SEME region. See
/// module comment for details.
pub fn exit_scope(&mut self,
span: Span,
extent: (CodeExtent, SourceInfo),
region_scope: (region::Scope, SourceInfo),
mut block: BasicBlock,
target: BasicBlock) {
debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target);
let scope_count = 1 + self.scopes.iter().rev().position(|scope| scope.extent == extent.0)
.unwrap_or_else(||{
span_bug!(span, "extent {:?} does not enclose", extent)
});
debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})",
region_scope, block, target);
let scope_count = 1 + self.scopes.iter().rev()
.position(|scope| scope.region_scope == region_scope.0)
.unwrap_or_else(|| {
span_bug!(span, "region_scope {:?} does not enclose", region_scope)
});
let len = self.scopes.len();
assert!(scope_count < len, "should not use `exit_scope` to pop ALL scopes");
@ -393,7 +395,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let mut rest = &mut self.scopes[(len - scope_count)..];
while let Some((scope, rest_)) = {rest}.split_last_mut() {
rest = rest_;
block = if let Some(&e) = scope.cached_exits.get(&(target, extent.0)) {
block = if let Some(&e) = scope.cached_exits.get(&(target, region_scope.0)) {
self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: e });
return;
@ -401,7 +403,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let b = self.cfg.start_new_block();
self.cfg.terminate(block, scope.source_info(span),
TerminatorKind::Goto { target: b });
scope.cached_exits.insert((target, extent.0), b);
scope.cached_exits.insert((target, region_scope.0), b);
b
};
unpack!(block = build_scope_drops(&mut self.cfg,
@ -412,7 +414,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
false));
// End all regions for scopes out of which we are breaking.
self.cfg.push_end_region(block, extent.1, scope.extent);
self.cfg.push_end_region(block, region_scope.1, scope.region_scope);
}
}
let scope = &self.scopes[len - scope_count];
@ -461,7 +463,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
true));
// End all regions for scopes out of which we are breaking.
self.cfg.push_end_region(block, src_info, scope.extent);
self.cfg.push_end_region(block, src_info, scope.region_scope);
}
self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop);
@ -486,12 +488,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// resolving `break` and `continue`.
pub fn find_breakable_scope(&mut self,
span: Span,
label: CodeExtent)
label: region::Scope)
-> &mut BreakableScope<'tcx> {
// find the loop-scope with the correct id
self.breakable_scopes.iter_mut()
.rev()
.filter(|breakable_scope| breakable_scope.extent == label)
.filter(|breakable_scope| breakable_scope.region_scope == label)
.next()
.unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found"))
}
@ -504,23 +506,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}
/// Returns the extent of the scope which should be exited by a
/// Returns the `region::Scope` of the scope which should be exited by a
/// return.
pub fn extent_of_return_scope(&self) -> CodeExtent {
pub fn region_scope_of_return_scope(&self) -> region::Scope {
// 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.scopes[1].extent {
CodeExtent::ParameterScope(_) => true,
assert!(match self.scopes[1].region_scope {
region::Scope::Arguments(_) => true,
_ => false,
});
self.scopes[1].extent
self.scopes[1].region_scope
}
/// Returns the topmost active scope, which is known to be alive until
/// the next scope expression.
pub fn topmost_scope(&self) -> CodeExtent {
self.scopes.last().expect("topmost_scope: no scopes present").extent
pub fn topmost_scope(&self) -> region::Scope {
self.scopes.last().expect("topmost_scope: no scopes present").region_scope
}
/// Returns the scope that we should use as the lifetime of an
@ -545,7 +547,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
///
/// When building statics/constants, returns `None` since
/// intermediate values do not have to be dropped in that case.
pub fn local_scope(&self) -> Option<CodeExtent> {
pub fn local_scope(&self) -> Option<region::Scope> {
match self.hir.src {
MirSource::Const(_) |
MirSource::Static(..) =>
@ -562,10 +564,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Scheduling drops
// ================
/// Indicates that `lvalue` should be dropped on exit from
/// `extent`.
/// `region_scope`.
pub fn schedule_drop(&mut self,
span: Span,
extent: CodeExtent,
region_scope: region::Scope,
lvalue: &Lvalue<'tcx>,
lvalue_ty: Ty<'tcx>) {
let needs_drop = self.hir.needs_drop(lvalue_ty);
@ -580,7 +582,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
};
for scope in self.scopes.iter_mut().rev() {
let this_scope = scope.extent == extent;
let this_scope = scope.region_scope == region_scope;
// When building drops, we try to cache chains of drops in such a way so these drops
// could be reused by the drops which would branch into the cached (already built)
// blocks. This, however, means that whenever we add a drop into a scope which already
@ -633,9 +635,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
if let DropKind::Value { .. } = drop_kind {
scope.needs_cleanup = true;
}
let extent_span = extent.span(self.hir.tcx(), &self.hir.region_maps);
let region_scope_span = region_scope.span(self.hir.tcx(),
&self.hir.region_scope_tree);
// Attribute scope exit drops to scope's closing brace
let scope_end = extent_span.with_lo(extent_span.hi());
let scope_end = region_scope_span.with_lo(region_scope_span.hi());
scope.drops.push(DropData {
span: scope_end,
location: lvalue.clone(),
@ -644,7 +647,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
return;
}
}
span_bug!(span, "extent {:?} not in scope to drop {:?}", extent, lvalue);
span_bug!(span, "region scope {:?} not in scope to drop {:?}", region_scope, lvalue);
}
// Other
@ -691,7 +694,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
};
for scope in scopes.iter_mut() {
target = build_diverge_scope(cfg, scope.extent_span, scope, target, generator_drop);
target = build_diverge_scope(cfg, scope.region_scope_span,
scope, target, generator_drop);
}
Some(target)
}
@ -889,7 +893,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(cfg: &mut CFG<'tcx>,
// becomes trivial goto after pass that removes all EndRegions.)
{
let block = cfg.start_new_cleanup_block();
cfg.push_end_region(block, source_info(span), scope.extent);
cfg.push_end_region(block, source_info(span), scope.region_scope);
cfg.terminate(block, source_info(span), TerminatorKind::Goto { target: target });
target = block
}

View File

@ -107,7 +107,7 @@ impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
self.borrows.len()
}
fn start_block_effect(&self, _sets: &mut BlockSets<BorrowIndex>) {
// no borrows of code extents have been taken prior to
// no borrows of code region_scopes have been taken prior to
// function execution, so this method has no effect on
// `_sets`.
}
@ -121,9 +121,9 @@ impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
panic!("could not find statement at location {:?}");
});
match stmt.kind {
mir::StatementKind::EndRegion(extent) => {
let borrow_indexes = self.region_map.get(&ReScope(extent)).unwrap_or_else(|| {
panic!("could not find BorrowIndexs for code-extent {:?}", extent);
mir::StatementKind::EndRegion(region_scope) => {
let borrow_indexes = self.region_map.get(&ReScope(region_scope)).unwrap_or_else(|| {
panic!("could not find BorrowIndexs for region scope {:?}", region_scope);
});
for idx in borrow_indexes { sets.kill(&idx); }
@ -153,7 +153,7 @@ impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
fn terminator_effect(&self,
_sets: &mut BlockSets<BorrowIndex>,
_location: Location) {
// no terminators start nor end code extents.
// no terminators start nor end region scopes.
}
fn propagate_call_return(&self,
@ -161,7 +161,7 @@ impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
_call_bb: mir::BasicBlock,
_dest_bb: mir::BasicBlock,
_dest_lval: &mir::Lvalue) {
// there are no effects on the extents from method calls.
// there are no effects on the region scopes from method calls.
}
}

View File

@ -11,7 +11,7 @@
use hair::*;
use hair::cx::Cx;
use hair::cx::to_ref::ToRef;
use rustc::middle::region::{BlockRemainder, CodeExtent};
use rustc::middle::region::{self, BlockRemainder};
use rustc::hir;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
@ -21,11 +21,12 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
// We have to eagerly translate the "spine" of the statements
// in order to get the lexical scoping correctly.
let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
let opt_destruction_extent = cx.region_maps.opt_destruction_extent(self.hir_id.local_id);
let opt_destruction_scope =
cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
Block {
targeted_by_break: self.targeted_by_break,
extent: CodeExtent::Misc(self.hir_id.local_id),
opt_destruction_extent,
region_scope: region::Scope::Node(self.hir_id.local_id),
opt_destruction_scope,
span: self.span,
stmts,
expr: self.expr.to_ref(),
@ -40,16 +41,16 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let mut result = vec![];
for (index, stmt) in stmts.iter().enumerate() {
let hir_id = cx.tcx.hir.node_to_hir_id(stmt.node.id());
let opt_dxn_ext = cx.region_maps.opt_destruction_extent(hir_id.local_id);
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
match stmt.node {
hir::StmtExpr(ref expr, _) |
hir::StmtSemi(ref expr, _) => {
result.push(StmtRef::Mirror(Box::new(Stmt {
kind: StmtKind::Expr {
scope: CodeExtent::Misc(hir_id.local_id),
scope: region::Scope::Node(hir_id.local_id),
expr: expr.to_ref(),
},
opt_destruction_extent: opt_dxn_ext,
opt_destruction_scope: opt_dxn_ext,
})))
}
hir::StmtDecl(ref decl, _) => {
@ -58,7 +59,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// ignore for purposes of the MIR
}
hir::DeclLocal(ref local) => {
let remainder_extent = CodeExtent::Remainder(BlockRemainder {
let remainder_scope = region::Scope::Remainder(BlockRemainder {
block: block_id,
first_statement_index: index as u32,
});
@ -69,12 +70,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
&local.pat);
result.push(StmtRef::Mirror(Box::new(Stmt {
kind: StmtKind::Let {
remainder_scope: remainder_extent,
init_scope: CodeExtent::Misc(hir_id.local_id),
remainder_scope: remainder_scope,
init_scope: region::Scope::Node(hir_id.local_id),
pattern,
initializer: local.init.to_ref(),
},
opt_destruction_extent: opt_dxn_ext,
opt_destruction_scope: opt_dxn_ext,
})));
}
}
@ -88,7 +89,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.hir_id);
let temp_lifetime = cx.region_maps.temporary_scope(block.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
let expr = Expr {
ty: block_ty,
temp_lifetime,

View File

@ -25,8 +25,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 = cx.region_maps.temporary_scope(self.hir_id.local_id);
let expr_extent = CodeExtent::Misc(self.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(self.hir_id.local_id);
let expr_scope = region::Scope::Node(self.hir_id.local_id);
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
@ -46,19 +46,20 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
ty: expr.ty,
span: self.span,
kind: ExprKind::Scope {
extent: expr_extent,
region_scope: expr_scope,
value: expr.to_ref(),
},
};
// Finally, create a destruction scope, if any.
if let Some(extent) = cx.region_maps.opt_destruction_extent(self.hir_id.local_id) {
if let Some(region_scope) =
cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id) {
expr = Expr {
temp_lifetime,
ty: expr.ty,
span: self.span,
kind: ExprKind::Scope {
extent,
region_scope,
value: expr.to_ref(),
},
};
@ -125,7 +126,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// Convert this to a suitable `&foo` and
// then an unsafe coercion. Limit the region to be just this
// expression.
let region = ty::ReScope(CodeExtent::Misc(hir_expr.hir_id.local_id));
let region = ty::ReScope(region::Scope::Node(hir_expr.hir_id.local_id));
let region = cx.tcx.mk_region(region);
expr = Expr {
temp_lifetime,
@ -160,7 +161,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 = cx.region_maps.temporary_scope(expr.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let kind = match expr.node {
// Here comes the interesting stuff:
@ -487,7 +488,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: CodeExtent::Misc(cx.tcx.hir.node_to_hir_id(target_id).local_id),
label: region::Scope::Node(cx.tcx.hir.node_to_hir_id(target_id).local_id),
value: value.to_ref(),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
@ -498,7 +499,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: CodeExtent::Misc(cx.tcx.hir.node_to_hir_id(loop_id).local_id),
label: region::Scope::Node(cx.tcx.hir.node_to_hir_id(loop_id).local_id),
},
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
bug!("invalid loop id for continue: {}", err)
@ -585,7 +586,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &hir::Expr,
custom_callee: Option<(DefId, &'tcx Substs<'tcx>)>)
-> Expr<'tcx> {
let temp_lifetime = cx.region_maps.temporary_scope(expr.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
(cx.tables().type_dependent_defs()[expr.hir_id].def_id(),
cx.tables().node_substs(expr.hir_id))
@ -676,7 +677,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &'tcx hir::Expr,
def: Def)
-> ExprKind<'tcx> {
let temp_lifetime = cx.region_maps.temporary_scope(expr.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
match def {
Def::Local(def_id) => {
@ -867,7 +868,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 = cx.region_maps.temporary_scope(expr.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let fun = method_callee(cx, expr, custom_callee);
let ref_expr = Expr {
temp_lifetime,
@ -896,7 +897,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).index,
};
let upvar_capture = cx.tables().upvar_capture(upvar_id);
let temp_lifetime = cx.region_maps.temporary_scope(closure_expr.hir_id.local_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
let var_ty = cx.tables()
.node_id_to_type(cx.tcx.hir.node_to_hir_id(var_node_id));
let captured_var = Expr {

View File

@ -22,7 +22,7 @@ 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::middle::region;
use rustc::infer::InferCtxt;
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt};
@ -42,7 +42,7 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
/// Identity `Substs` for use with const-evaluation.
pub identity_substs: &'gcx Substs<'gcx>,
pub region_maps: Rc<RegionMaps>,
pub region_scope_tree: Rc<region::ScopeTree>,
pub tables: &'a ty::TypeckTables<'gcx>,
/// This is `Constness::Const` if we are compiling a `static`,
@ -92,7 +92,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
infcx,
param_env: tcx.param_env(src_def_id),
identity_substs: Substs::identity_for_item(tcx.global_tcx(), src_def_id),
region_maps: tcx.region_maps(src_def_id),
region_scope_tree: tcx.region_scope_tree(src_def_id),
tables: tcx.typeck_tables_of(src_def_id),
constness,
src,

View File

@ -17,7 +17,7 @@
use rustc_const_math::ConstUsize;
use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp};
use rustc::hir::def_id::DefId;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::ty::subst::Substs;
use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior};
use rustc::hir;
@ -32,8 +32,8 @@ 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 opt_destruction_extent: Option<CodeExtent>,
pub region_scope: region::Scope,
pub opt_destruction_scope: Option<region::Scope>,
pub span: Span,
pub stmts: Vec<StmtRef<'tcx>>,
pub expr: Option<ExprRef<'tcx>>,
@ -47,14 +47,14 @@ pub enum StmtRef<'tcx> {
#[derive(Clone, Debug)]
pub struct Stmt<'tcx> {
pub kind: StmtKind<'tcx>,
pub opt_destruction_extent: Option<CodeExtent>,
pub opt_destruction_scope: Option<region::Scope>,
}
#[derive(Clone, Debug)]
pub enum StmtKind<'tcx> {
Expr {
/// scope for this statement; may be used as lifetime of temporaries
scope: CodeExtent,
scope: region::Scope,
/// expression being evaluated in this statement
expr: ExprRef<'tcx>,
@ -63,11 +63,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: region::Scope,
/// scope for the initialization itself; might be used as
/// lifetime of temporaries
init_scope: CodeExtent,
init_scope: region::Scope,
/// let <PAT> = ...
pattern: Pattern<'tcx>,
@ -98,7 +98,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<region::Scope>,
/// span of the expression in the source
pub span: Span,
@ -110,7 +110,7 @@ pub struct Expr<'tcx> {
#[derive(Clone, Debug)]
pub enum ExprKind<'tcx> {
Scope {
extent: CodeExtent,
region_scope: region::Scope,
value: ExprRef<'tcx>,
},
Box {
@ -207,11 +207,11 @@ pub enum ExprKind<'tcx> {
arg: ExprRef<'tcx>,
},
Break {
label: CodeExtent,
label: region::Scope,
value: Option<ExprRef<'tcx>>,
},
Continue {
label: CodeExtent,
label: region::Scope,
},
Return {
value: Option<ExprRef<'tcx>>,

View File

@ -18,7 +18,7 @@ use rustc::ty::{self, TyCtxt, RegionKind};
use rustc::hir;
use rustc::mir::*;
use rustc::mir::transform::{MirPass, MirSource};
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
pub struct AddValidation;
@ -27,7 +27,7 @@ fn lval_context<'a, 'tcx, D>(
lval: &Lvalue<'tcx>,
local_decls: &D,
tcx: TyCtxt<'a, 'tcx, 'tcx>
) -> (Option<CodeExtent>, hir::Mutability)
) -> (Option<region::Scope>, hir::Mutability)
where D: HasLocalDecls<'tcx>
{
use rustc::mir::Lvalue::*;

View File

@ -21,7 +21,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::mir::transform::{MirPass, MirSource};
use rustc::mir::{BasicBlock, Location, Mir, Rvalue, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Visitor, Lookup};
@ -30,11 +30,11 @@ use rustc::ty::{Ty, RegionKind, TyCtxt};
pub struct CleanEndRegions;
struct GatherBorrowedRegions {
seen_regions: FxHashSet<CodeExtent>,
seen_regions: FxHashSet<region::Scope>,
}
struct DeleteTrivialEndRegions<'a> {
seen_regions: &'a FxHashSet<CodeExtent>,
seen_regions: &'a FxHashSet<region::Scope>,
}
impl MirPass for CleanEndRegions {
@ -84,8 +84,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DeleteTrivialEndRegions<'a> {
location: Location) {
let mut delete_it = false;
if let StatementKind::EndRegion(ref extent) = statement.kind {
if !self.seen_regions.contains(extent) {
if let StatementKind::EndRegion(ref region_scope) = statement.kind {
if !self.seen_regions.contains(region_scope) {
delete_it = true;
}
}

View File

@ -143,8 +143,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let tcx = self.tcx;
let param_env = self.param_env;
let region_maps = self.tcx.region_maps(item_def_id);
euv::ExprUseVisitor::new(self, tcx, param_env, &region_maps, self.tables)
let region_scope_tree = self.tcx.region_scope_tree(item_def_id);
euv::ExprUseVisitor::new(self, tcx, param_env, &region_scope_tree, self.tables)
.consume_body(body);
self.visit_body(body);

View File

@ -11,7 +11,7 @@
use rustc::hir::{self, ImplItemKind, TraitItemKind};
use rustc::infer::{self, InferOk};
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region::RegionMaps;
use rustc::middle::region;
use rustc::ty::{self, TyCtxt};
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
use rustc::ty::error::{ExpectedFound, TypeError};
@ -340,10 +340,12 @@ 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::default();
let region_scope_tree = region::ScopeTree::default();
let mut free_regions = FreeRegionMap::new();
free_regions.relate_free_regions_from_predicates(&param_env.caller_bounds);
infcx.resolve_regions_and_report_errors(impl_m.def_id, &region_maps, &free_regions);
infcx.resolve_regions_and_report_errors(impl_m.def_id,
&region_scope_tree,
&free_regions);
} else {
let fcx = FnCtxt::new(&inh, param_env, impl_m_node_id);
fcx.regionck_item(impl_m_node_id, impl_m_span, &[]);

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 rustc::middle::region::{self, RegionMaps};
use rustc::middle::region;
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::traits::{self, ObligationCause};
@ -114,9 +114,9 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
return Err(ErrorReported);
}
let region_maps = RegionMaps::default();
let region_scope_tree = region::ScopeTree::default();
let free_regions = FreeRegionMap::new();
infcx.resolve_regions_and_report_errors(drop_impl_did, &region_maps, &free_regions);
infcx.resolve_regions_and_report_errors(drop_impl_did, &region_scope_tree, &free_regions);
Ok(())
})
}
@ -270,14 +270,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::Scope)
-> Result<(), ErrorReported>
{
debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
ty, scope);
let parent_scope = match rcx.region_maps.opt_encl_scope(scope) {
let parent_scope = match rcx.region_scope_tree.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

@ -16,7 +16,7 @@
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::{self, Body, Pat, PatKind, Expr};
use rustc::middle::region::{RegionMaps, CodeExtent};
use rustc::middle::region;
use rustc::ty::Ty;
use std::rc::Rc;
use super::FnCtxt;
@ -25,15 +25,15 @@ use util::nodemap::FxHashMap;
struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
types: FxHashMap<Ty<'tcx>, usize>,
region_maps: Rc<RegionMaps>,
region_scope_tree: Rc<region::ScopeTree>,
}
impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
fn record(&mut self, ty: Ty<'tcx>, scope: Option<CodeExtent>, expr: Option<&'tcx Expr>) {
fn record(&mut self, ty: Ty<'tcx>, scope: Option<region::Scope>, expr: Option<&'tcx Expr>) {
use syntax_pos::DUMMY_SP;
let live_across_yield = scope.map_or(Some(DUMMY_SP), |s| {
self.region_maps.yield_in_scope(s)
self.region_scope_tree.yield_in_scope(s)
});
if let Some(span) = live_across_yield {
@ -59,7 +59,7 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
let mut visitor = InteriorVisitor {
fcx,
types: FxHashMap(),
region_maps: fcx.tcx.region_maps(def_id),
region_scope_tree: fcx.tcx.region_scope_tree(def_id),
};
intravisit::walk_body(&mut visitor, body);
@ -93,7 +93,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'gcx, 'tcx> {
fn visit_pat(&mut self, pat: &'tcx Pat) {
if let PatKind::Binding(..) = pat.node {
let scope = self.region_maps.var_scope(pat.hir_id.local_id);
let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
let ty = self.fcx.tables.borrow().pat_ty(pat);
self.record(ty, Some(scope), None);
}
@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'gcx, 'tcx> {
}
fn visit_expr(&mut self, expr: &'tcx Expr) {
let scope = self.region_maps.temporary_scope(expr.hir_id.local_id);
let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let ty = self.fcx.tables.borrow().expr_ty_adjusted(expr);
self.record(ty, scope, Some(expr));

View File

@ -91,7 +91,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_back::slice::ref_slice;
use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
use rustc::infer::type_variable::{TypeVariableOrigin};
use rustc::middle::region::CodeExtent;
use rustc::middle::region;
use rustc::ty::subst::{Kind, Subst, Substs};
use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode};
use rustc::ty::{ParamTy, LvaluePreference, NoPreference, PreferMutLvalue};
@ -608,7 +608,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id));
let implicit_region_bound = body_id.map(|body_id| {
let body = tcx.hir.body(body_id);
tcx.mk_region(ty::ReScope(CodeExtent::CallSiteScope(body.value.hir_id.local_id)))
tcx.mk_region(ty::ReScope(region::Scope::CallSite(body.value.hir_id.local_id)))
});
Inherited {

View File

@ -87,7 +87,7 @@ use check::FnCtxt;
use middle::free_region::FreeRegionMap;
use middle::mem_categorization as mc;
use middle::mem_categorization::Categorization;
use middle::region::{CodeExtent, RegionMaps};
use middle::region;
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
use rustc::traits;
@ -179,7 +179,7 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
pub region_maps: Rc<RegionMaps>,
pub region_scope_tree: Rc<region::ScopeTree>,
free_region_map: FreeRegionMap<'tcx>,
@ -187,7 +187,7 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
body_id: ast::NodeId,
// call_site scope of innermost fn
call_site_scope: Option<CodeExtent>,
call_site_scope: Option<region::Scope>,
// id of innermost fn or loop
repeating_scope: ast::NodeId,
@ -230,10 +230,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'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);
let region_scope_tree = fcx.tcx.region_scope_tree(subject);
RegionCtxt {
fcx,
region_maps,
region_scope_tree,
repeating_scope: initial_repeating_scope,
body_id: initial_body_id,
call_site_scope: None,
@ -243,8 +243,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
}
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<region::Scope>)
-> Option<region::Scope> {
mem::replace(&mut self.call_site_scope, call_site_scope)
}
@ -305,7 +305,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let body_id = body.id();
let call_site = CodeExtent::CallSiteScope(body.value.hir_id.local_id);
let call_site = region::Scope::CallSite(body.value.hir_id.local_id);
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
let fn_sig = {
@ -330,7 +330,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(CodeExtent::Misc(body.value.hir_id.local_id), &body.arguments);
self.link_fn_args(region::Scope::Node(body.value.hir_id.local_id), &body.arguments);
self.visit_body(body);
self.visit_region_obligations(body_id.node_id);
@ -580,7 +580,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn resolve_regions_and_report_errors(&self) {
self.fcx.resolve_regions_and_report_errors(self.subject_def_id,
&self.region_maps,
&self.region_scope_tree,
&self.free_region_map);
}
@ -611,7 +611,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// variable's type enclose at least the variable's scope.
let hir_id = self.tcx.hir.node_to_hir_id(id);
let var_scope = self.region_maps.var_scope(hir_id.local_id);
let var_scope = self.region_scope_tree.var_scope(hir_id.local_id);
let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
let origin = infer::BindingTypeIsNotValidAtDecl(span);
@ -668,7 +668,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// scope of that expression. This also guarantees basic WF.
let expr_ty = self.resolve_node_type(expr.hir_id);
// the region corresponding to this expression
let expr_region = self.tcx.mk_region(ty::ReScope(CodeExtent::Misc(expr.hir_id.local_id)));
let expr_region = self.tcx.mk_region(ty::ReScope(
region::Scope::Node(expr.hir_id.local_id)));
self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span),
expr_ty, expr_region);
@ -950,7 +951,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 = CodeExtent::Misc(call_expr.hir_id.local_id);
let callee_scope = region::Scope::Node(call_expr.hir_id.local_id);
let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
debug!("callee_region={:?}", callee_region);
@ -979,7 +980,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
where F: for<'b> FnOnce(mc::MemCategorizationContext<'b, 'gcx, 'tcx>) -> R
{
f(mc::MemCategorizationContext::with_infer(&self.infcx,
&self.region_maps,
&self.region_scope_tree,
&self.tables.borrow()))
}
@ -1002,7 +1003,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// expression.
self.check_safety_of_rvalue_destructor_if_necessary(cmt.clone(), expr.span);
let expr_region = self.tcx.mk_region(ty::ReScope(CodeExtent::Misc(expr.hir_id.local_id)));
let expr_region = self.tcx.mk_region(ty::ReScope(
region::Scope::Node(expr.hir_id.local_id)));
for adjustment in adjustments {
debug!("constrain_adjustments: adjustment={:?}, cmt={:?}",
adjustment, cmt);
@ -1095,7 +1097,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(CodeExtent::Misc(index_expr.hir_id.local_id));
let r_index_expr = ty::ReScope(region::Scope::Node(index_expr.hir_id.local_id));
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
match mt.ty.sty {
ty::TySlice(_) | ty::TyStr => {
@ -1176,7 +1178,7 @@ 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: region::Scope, args: &[hir::Arg]) {
debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
for arg in args {
let arg_ty = self.node_ty(arg.hir_id);
@ -1232,7 +1234,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
adjustment::AutoBorrow::RawPtr(m) => {
let r = self.tcx.mk_region(ty::ReScope(CodeExtent::Misc(expr.hir_id.local_id)));
let r = self.tcx.mk_region(ty::ReScope(region::Scope::Node(expr.hir_id.local_id)));
self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt);
}
}

View File

@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
{
let body_owner_def_id = self.tcx.hir.body_owner_def_id(body.id());
let region_maps = &self.tcx.region_maps(body_owner_def_id);
let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id);
let mut delegate = InferBorrowKind {
fcx: self,
adjust_closure_kinds: FxHashMap(),
@ -161,7 +161,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
euv::ExprUseVisitor::with_infer(&mut delegate,
&self.infcx,
self.param_env,
region_maps,
region_scope_tree,
&self.tables.borrow())
.consume_body(body);

View File

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

View File

@ -22,16 +22,16 @@ fn main() {
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
// let mut _0: ();
// let _1: i32;
// let _2: &'10_1rce i32;
// let _2: &'10_1rs i32;
//
// bb0: {
// StorageLive(_1);
// _1 = const 3i32;
// StorageLive(_2);
// _2 = &'10_1rce _1;
// _2 = &'10_1rs _1;
// _0 = ();
// StorageDead(_2);
// EndRegion('10_1rce);
// EndRegion('10_1rs);
// StorageDead(_1);
// return;
// }

View File

@ -27,8 +27,8 @@ fn main() {
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
// let mut _0: ();
// let _2: bool;
// let _3: &'23_1rce bool;
// let _7: &'23_3rce bool;
// let _3: &'23_1rs bool;
// let _7: &'23_3rs bool;
// let mut _4: ();
// let mut _5: bool;
// bb0: {
@ -38,7 +38,7 @@ fn main() {
// StorageLive(_2);
// _2 = const true;
// StorageLive(_3);
// _3 = &'23_1rce _2;
// _3 = &'23_1rs _2;
// StorageLive(_5);
// _5 = _2;
// switchInt(_5) -> [0u8: bb3, otherwise: bb2];
@ -47,19 +47,19 @@ fn main() {
// _0 = ();
// StorageDead(_5);
// StorageDead(_3);
// EndRegion('23_1rce);
// EndRegion('23_1rs);
// StorageDead(_2);
// return;
// }
// bb3: {
// StorageDead(_5);
// StorageLive(_7);
// _7 = &'23_3rce _2;
// _7 = &'23_3rs _2;
// _1 = ();
// StorageDead(_7);
// EndRegion('23_3rce);
// EndRegion('23_3rs);
// StorageDead(_3);
// EndRegion('23_1rce);
// EndRegion('23_1rs);
// StorageDead(_2);
// goto -> bb1;
// }

View File

@ -28,8 +28,8 @@ fn main() {
// START rustc.node4.SimplifyCfg-qualify-consts.after.mir
// let mut _0: ();
// let mut _1: bool;
// let _3: &'26_1rce bool;
// let _7: &'26_3rce bool;
// let _3: &'26_1rs bool;
// let _7: &'26_3rs bool;
// let mut _2: ();
// let mut _4: ();
// let mut _5: bool;
@ -41,7 +41,7 @@ fn main() {
// bb1: {
// _1 = const true;
// StorageLive(_3);
// _3 = &'26_1rce _1;
// _3 = &'26_1rs _1;
// StorageLive(_5);
// _5 = _1;
// switchInt(_5) -> [0u8: bb3, otherwise: bb2];
@ -50,7 +50,7 @@ fn main() {
// _0 = ();
// StorageDead(_5);
// StorageDead(_3);
// EndRegion('26_1rce);
// EndRegion('26_1rs);
// StorageDead(_1);
// return;
// }
@ -58,12 +58,12 @@ fn main() {
// _4 = ();
// StorageDead(_5);
// StorageLive(_7);
// _7 = &'26_3rce _1;
// _7 = &'26_3rs _1;
// _2 = ();
// StorageDead(_7);
// EndRegion('26_3rce);
// EndRegion('26_3rs);
// StorageDead(_3);
// EndRegion('26_1rce);
// EndRegion('26_1rs);
// goto -> bb1;
// }
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir

View File

@ -33,8 +33,8 @@ fn foo(i: i32) {
// let mut _0: ();
// let _1: D;
// let _2: i32;
// let _3: &'26_2rce i32;
// let _6: &'26_4rce i32;
// let _3: &'26_2rs i32;
// let _6: &'26_4rs i32;
// let mut _4: ();
// let mut _5: i32;
// bb0: {
@ -43,7 +43,7 @@ fn foo(i: i32) {
// StorageLive(_2);
// _2 = const 0i32;
// StorageLive(_3);
// _3 = &'26_2rce _2;
// _3 = &'26_2rs _2;
// StorageLive(_5);
// _5 = (*_3);
// _4 = const foo(_5) -> [return: bb1, unwind: bb3];
@ -51,12 +51,12 @@ fn foo(i: i32) {
// bb1: {
// StorageDead(_5);
// StorageLive(_6);
// _6 = &'26_4rce _2;
// _6 = &'26_4rs _2;
// _0 = ();
// StorageDead(_6);
// EndRegion('26_4rce);
// EndRegion('26_4rs);
// StorageDead(_3);
// EndRegion('26_2rce);
// EndRegion('26_2rs);
// StorageDead(_2);
// drop(_1) -> bb4;
// }
@ -64,7 +64,7 @@ fn foo(i: i32) {
// resume;
// }
// bb3: {
// EndRegion('26_2rce);
// EndRegion('26_2rs);
// drop(_1) -> bb2;
// }
// bb4: {

View File

@ -31,21 +31,21 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// let mut _0: ();
// let _1: D;
// let mut _2: ();
// let mut _3: [closure@NodeId(18) d:&'14mce D];
// let mut _4: &'14mce D;
// let mut _3: [closure@NodeId(18) d:&'14s D];
// let mut _4: &'14s D;
// bb0: {
// StorageLive(_1);
// _1 = D::{{constructor}}(const 0i32,);
// StorageLive(_3);
// StorageLive(_4);
// _4 = &'14mce _1;
// _4 = &'14s _1;
// _3 = [closure@NodeId(18)] { d: _4 };
// StorageDead(_4);
// _2 = const foo(_3) -> [return: bb1, unwind: bb3];
// }
// bb1: {
// StorageDead(_3);
// EndRegion('14mce);
// EndRegion('14s);
// _0 = ();
// drop(_1) -> bb4;
// }
@ -53,7 +53,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// resume;
// }
// bb3: {
// EndRegion('14mce);
// EndRegion('14s);
// drop(_1) -> bb2;
// }
// bb4: {
@ -64,13 +64,13 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir
// START rustc.node18.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(18) d:&'14mce D]) -> i32 {
// fn main::{{closure}}(_1: [closure@NodeId(18) d:&'14s D]) -> i32 {
// let mut _0: i32;
// let mut _2: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = ((*(_1.0: &'14mce D)).0: i32);
// _2 = ((*(_1.0: &'14s D)).0: i32);
// _0 = _2;
// StorageDead(_2);
// return;

View File

@ -31,21 +31,21 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// let mut _0: ();
// let _1: D;
// let mut _2: ();
// let mut _3: [closure@NodeId(22) d:&'19mce D];
// let mut _4: &'19mce D;
// let mut _3: [closure@NodeId(22) d:&'19s D];
// let mut _4: &'19s D;
// bb0: {
// StorageLive(_1);
// _1 = D::{{constructor}}(const 0i32,);
// StorageLive(_3);
// StorageLive(_4);
// _4 = &'19mce _1;
// _4 = &'19s _1;
// _3 = [closure@NodeId(22)] { d: _4 };
// StorageDead(_4);
// _2 = const foo(_3) -> [return: bb1, unwind: bb3];
// }
// bb1: {
// StorageDead(_3);
// EndRegion('19mce);
// EndRegion('19s);
// _0 = ();
// drop(_1) -> bb4;
// }
@ -53,7 +53,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// resume;
// }
// bb3: {
// EndRegion('19mce);
// EndRegion('19s);
// drop(_1) -> bb2;
// }
// bb4: {
@ -63,20 +63,20 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir
// START rustc.node22.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19mce D]) -> i32 {
// fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19s D]) -> i32 {
// let mut _0: i32;
// let _2: &'15_0rce D;
// let _2: &'15_0rs D;
// let mut _3: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = &'15_0rce (*(_1.0: &'19mce D));
// _2 = &'15_0rs (*(_1.0: &'19s D));
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = _3;
// StorageDead(_3);
// StorageDead(_2);
// EndRegion('15_0rce);
// EndRegion('15_0rs);
// return;
// }
// END rustc.node22.SimplifyCfg-qualify-consts.after.mir

View File

@ -74,18 +74,18 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// START rustc.node22.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(22) d:D]) -> i32 {
// let mut _0: i32;
// let _2: &'15_0rce D;
// let _2: &'15_0rs D;
// let mut _3: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = &'15_0rce (_1.0: D);
// _2 = &'15_0rs (_1.0: D);
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = _3;
// StorageDead(_3);
// StorageDead(_2);
// EndRegion('15_0rce);
// EndRegion('15_0rs);
// drop(_1) -> bb1;
// }
// bb1: {

View File

@ -31,15 +31,15 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// fn main() -> () {
// let mut _0: ();
// let _1: D;
// let _2: &'21_1rce D;
// let _2: &'21_1rs D;
// let mut _3: ();
// let mut _4: [closure@NodeId(22) r:&'21_1rce D];
// let mut _5: &'21_1rce D;
// let mut _4: [closure@NodeId(22) r:&'21_1rs D];
// let mut _5: &'21_1rs D;
// bb0: {
// StorageLive(_1);
// _1 = D::{{constructor}}(const 0i32,);
// StorageLive(_2);
// _2 = &'21_1rce _1;
// _2 = &'21_1rs _1;
// StorageLive(_4);
// StorageLive(_5);
// _5 = _2;
@ -51,14 +51,14 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// StorageDead(_4);
// _0 = ();
// StorageDead(_2);
// EndRegion('21_1rce);
// EndRegion('21_1rs);
// drop(_1) -> bb4;
// }
// bb2: {
// resume;
// }
// bb3: {
// EndRegion('21_1rce);
// EndRegion('21_1rs);
// drop(_1) -> bb2;
// }
// bb4: {
@ -69,13 +69,13 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// END rustc.node4.SimplifyCfg-qualify-consts.after.mir
// START rustc.node22.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'21_1rce D]) -> i32 {
// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'21_1rs D]) -> i32 {
// let mut _0: i32;
// let mut _2: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = ((*(_1.0: &'21_1rce D)).0: i32);
// _2 = ((*(_1.0: &'21_1rs D)).0: i32);
// _0 = _2;
// StorageDead(_2);
// return;

View File

@ -42,7 +42,7 @@ fn main() {
// let mut _0: ();
// let mut _1: bool;
// let _2: i32;
// let mut _4: &'13_0rce i32;
// let mut _4: &'13_0rs i32;
// let mut _3: ();
// let mut _5: !;
// let mut _6: ();
@ -68,14 +68,14 @@ fn main() {
// _0 = ();
// StorageDead(_7);
// StorageDead(_4);
// EndRegion('13_0rce);
// EndRegion('13_0rs);
// StorageDead(_2);
// StorageDead(_1);
// return;
// }
//
// bb3: {
// _4 = &'13_0rce _2;
// _4 = &'13_0rs _2;
// _6 = ();
// StorageDead(_7);
// _1 = const true;

View File

@ -30,14 +30,14 @@ fn main() { }
// scope 1 {
// let _2: std::cell::RefCell<i32>;
// }
// let mut _3: std::cell::RefMut<'17dce, i32>;
// let mut _4: &'17dce std::cell::RefCell<i32>;
// let mut _3: std::cell::RefMut<'17ds, i32>;
// let mut _4: &'17ds std::cell::RefCell<i32>;
//
// bb0: {
// StorageLive(_2);
// _2 = _1;
// StorageLive(_4);
// _4 = &'17dce _2;
// _4 = &'17ds _2;
// _3 = const <std::cell::RefCell<T>>::borrow_mut(_4) -> bb1;
// }
//
@ -47,7 +47,7 @@ fn main() { }
//
// bb2: {
// StorageDead(_4);
// EndRegion('17dce);
// EndRegion('17ds);
// _0 = ();
// StorageDead(_2);
// return;

View File

@ -37,19 +37,19 @@ fn main() {
// START rustc.node23.EraseRegions.after.mir
// fn main() -> () {
// bb0: {
// Validate(Suspend(ReScope(Misc(ItemLocalId(10)))), [_1: i32]);
// Validate(Suspend(ReScope(Node(ItemLocalId(10)))), [_1: i32]);
// _6 = &ReErased mut _1;
// Validate(Acquire, [(*_6): i32/ReScope(Misc(ItemLocalId(10)))]);
// Validate(Suspend(ReScope(Misc(ItemLocalId(10)))), [(*_6): i32/ReScope(Misc(ItemLocalId(10)))]);
// Validate(Acquire, [(*_6): i32/ReScope(Node(ItemLocalId(10)))]);
// Validate(Suspend(ReScope(Node(ItemLocalId(10)))), [(*_6): i32/ReScope(Node(ItemLocalId(10)))]);
// _5 = &ReErased mut (*_6);
// Validate(Acquire, [(*_5): i32/ReScope(Misc(ItemLocalId(10)))]);
// Validate(Release, [_2: (), _3: &ReScope(Misc(ItemLocalId(10))) Test, _5: &ReScope(Misc(ItemLocalId(10))) mut i32]);
// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(10)))]);
// Validate(Release, [_2: (), _3: &ReScope(Node(ItemLocalId(10))) Test, _5: &ReScope(Node(ItemLocalId(10))) mut i32]);
// _2 = const Test::foo(_3, _5) -> bb1;
// }
//
// bb1: {
// Validate(Acquire, [_2: ()]);
// EndRegion(ReScope(Misc(ItemLocalId(10))));
// EndRegion(ReScope(Node(ItemLocalId(10))));
// return;
// }
// }

View File

@ -32,17 +32,17 @@ fn main() {
// fn main() -> () {
// let mut _5: &ReErased i32;
// bb0: {
// Validate(Suspend(ReScope(Misc(ItemLocalId(17)))), [((*_2).0: i32): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })) (imm)]);
// Validate(Suspend(ReScope(Node(ItemLocalId(17)))), [((*_2).0: i32): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })) (imm)]);
// _5 = &ReErased ((*_2).0: i32);
// Validate(Acquire, [(*_5): i32/ReScope(Misc(ItemLocalId(17))) (imm)]);
// Validate(Suspend(ReScope(Misc(ItemLocalId(17)))), [(*_5): i32/ReScope(Misc(ItemLocalId(17))) (imm)]);
// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
// Validate(Suspend(ReScope(Node(ItemLocalId(17)))), [(*_5): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
// _4 = &ReErased (*_5);
// Validate(Acquire, [(*_4): i32/ReScope(Misc(ItemLocalId(17))) (imm)]);
// Validate(Release, [_3: (), _4: &ReScope(Misc(ItemLocalId(17))) i32]);
// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(17))) i32]);
// _3 = const foo(_4) -> bb1;
// }
// bb1: {
// EndRegion(ReScope(Misc(ItemLocalId(17))));
// EndRegion(ReScope(Node(ItemLocalId(17))));
// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })));
// return;
// }

View File

@ -50,12 +50,12 @@ fn main() {
// _3 = _2;
// StorageLive(_4);
// StorageLive(_5);
// Validate(Suspend(ReScope(Misc(ItemLocalId(9)))), [(*_3): i32]);
// Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_3): i32]);
// _5 = &ReErased mut (*_3);
// Validate(Acquire, [(*_5): i32/ReScope(Misc(ItemLocalId(9)))]);
// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(9)))]);
// _4 = _5 as *mut i32 (Misc);
// StorageDead(_5);
// EndRegion(ReScope(Misc(ItemLocalId(9))));
// EndRegion(ReScope(Node(ItemLocalId(9))));
// Validate(Release, [_0: bool, _4: *mut i32]);
// _0 = const write_42(_4) -> bb1;
// }