rustc: rename CodeExtent to Scope and RegionMaps to ScopeTree.
This commit is contained in:
parent
f861b6ee46
commit
8bdfd8a003
@ -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,
|
||||
});
|
||||
|
@ -395,7 +395,7 @@ define_dep_nodes!( <'tcx>
|
||||
[] WorkProduct(WorkProductId),
|
||||
|
||||
// Represents different phases in the compiler.
|
||||
[] RegionMaps(DefId),
|
||||
[] RegionScopeTree(DefId),
|
||||
[] Coherence,
|
||||
[] CoherenceInherentImplOverlapCheck,
|
||||
[] Resolve,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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: ®ion::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: ®ion::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: ®ion::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: ®ion::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,
|
||||
"...");
|
||||
|
@ -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: ®ion::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,
|
||||
"");
|
||||
|
@ -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: ®ion::ScopeTree,
|
||||
free_regions: &FreeRegionMap<'tcx>) {
|
||||
let region_rels = RegionRelations::new(self.tcx,
|
||||
region_context,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(_)) |
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -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)),
|
||||
|
@ -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, ®ion_maps, &free_regions);
|
||||
infcx.resolve_regions_and_report_errors(region_context, ®ion_scope_tree, &free_regions);
|
||||
let predicates = match infcx.fully_resolve(&predicates) {
|
||||
Ok(predicates) => predicates,
|
||||
Err(fixup_err) => {
|
||||
|
@ -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>,
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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() => {
|
||||
|
@ -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
|
||||
|
@ -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(..)) => {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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, ®ion_maps, &free_regions);
|
||||
infcx.resolve_regions_and_report_errors(def_id, ®ion_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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
});
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 } => {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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>>,
|
||||
|
@ -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::*;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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, ®ion_maps, self.tables)
|
||||
let region_scope_tree = self.tcx.region_scope_tree(item_def_id);
|
||||
euv::ExprUseVisitor::new(self, tcx, param_env, ®ion_scope_tree, self.tables)
|
||||
.consume_body(body);
|
||||
|
||||
self.visit_body(body);
|
||||
|
@ -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(¶m_env.caller_bounds);
|
||||
infcx.resolve_regions_and_report_errors(impl_m.def_id, ®ion_maps, &free_regions);
|
||||
infcx.resolve_regions_and_report_errors(impl_m.def_id,
|
||||
®ion_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, &[]);
|
||||
|
@ -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, ®ion_maps, &free_regions);
|
||||
infcx.resolve_regions_and_report_errors(drop_impl_did, ®ion_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.
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(¶m_env.caller_bounds);
|
||||
infcx.resolve_regions_and_report_errors(impl_did, ®ion_maps, &free_regions);
|
||||
infcx.resolve_regions_and_report_errors(impl_did, ®ion_scope_tree, &free_regions);
|
||||
|
||||
CoerceUnsizedInfo {
|
||||
custom_kind: kind
|
||||
|
@ -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;
|
||||
// }
|
||||
|
@ -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;
|
||||
// }
|
||||
|
@ -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
|
||||
|
@ -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: {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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: {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
// }
|
||||
// }
|
||||
|
@ -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;
|
||||
// }
|
||||
|
@ -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;
|
||||
// }
|
||||
|
Loading…
x
Reference in New Issue
Block a user