mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 10:13:54 +00:00
intern CodeExtents
Make a `CodeExtent<'tcx>` be something allocated in an arena instead of an index into the `RegionMaps`.
This commit is contained in:
parent
55d6066c05
commit
c7dc39dbf0
@ -583,10 +583,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||||||
scope_id: ast::NodeId,
|
scope_id: ast::NodeId,
|
||||||
to_index: CFGIndex) {
|
to_index: CFGIndex) {
|
||||||
let mut data = CFGEdgeData { exiting_scopes: vec![] };
|
let mut data = CFGEdgeData { exiting_scopes: vec![] };
|
||||||
let mut scope = self.tcx.region_maps().node_extent(from_expr.id);
|
let mut scope = self.tcx.node_extent(from_expr.id);
|
||||||
let target_scope = self.tcx.region_maps().node_extent(scope_id);
|
let target_scope = self.tcx.node_extent(scope_id);
|
||||||
while scope != target_scope {
|
while scope != target_scope {
|
||||||
data.exiting_scopes.push(scope.node_id(&self.tcx.region_maps()));
|
data.exiting_scopes.push(scope.node_id());
|
||||||
scope = self.tcx.region_maps().encl_scope(scope);
|
scope = self.tcx.region_maps().encl_scope(scope);
|
||||||
}
|
}
|
||||||
self.graph.add_edge(from_index, to_index, data);
|
self.graph.add_edge(from_index, to_index, data);
|
||||||
|
@ -39,7 +39,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Region {
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionKind<'tcx> {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
hcx: &mut StableHashingContext<'a, 'tcx>,
|
hcx: &mut StableHashingContext<'a, 'tcx>,
|
||||||
hasher: &mut StableHasher<W>) {
|
hasher: &mut StableHasher<W>) {
|
||||||
@ -432,17 +432,6 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
|
|||||||
FnPtrAddrCast
|
FnPtrAddrCast
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtent
|
|
||||||
{
|
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a, 'tcx>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
|
||||||
hcx.tcx().region_maps().code_extent_data(*self).hash_stable(hcx, hasher);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtentData
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtentData
|
||||||
{
|
{
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
@ -477,7 +466,7 @@ impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
|
|||||||
custom_kind
|
custom_kind
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ty::FreeRegion {
|
impl_stable_hash_for!(struct ty::FreeRegion<'tcx> {
|
||||||
scope,
|
scope,
|
||||||
bound_region
|
bound_region
|
||||||
});
|
});
|
||||||
|
@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
// Never make variables for regions bound within the type itself,
|
// Never make variables for regions bound within the type itself,
|
||||||
// nor for erased regions.
|
// nor for erased regions.
|
||||||
|
@ -78,8 +78,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
-> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?})",
|
debug!("{}.regions({:?}, {:?})",
|
||||||
self.tag(),
|
self.tag(),
|
||||||
a,
|
a,
|
||||||
|
@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn note_and_explain_region(self,
|
pub fn note_and_explain_region(self,
|
||||||
err: &mut DiagnosticBuilder,
|
err: &mut DiagnosticBuilder,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
suffix: &str) {
|
suffix: &str) {
|
||||||
fn item_scope_tag(item: &hir::Item) -> &'static str {
|
fn item_scope_tag(item: &hir::Item) -> &'static str {
|
||||||
match item.node {
|
match item.node {
|
||||||
@ -124,14 +124,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
format!("{}unknown scope: {:?}{}. Please report a bug.",
|
format!("{}unknown scope: {:?}{}. Please report a bug.",
|
||||||
prefix, scope, suffix)
|
prefix, scope, suffix)
|
||||||
};
|
};
|
||||||
let span = match scope.span(&self.region_maps(), &self.hir) {
|
let span = match scope.span(&self.hir) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
err.note(&unknown_scope());
|
err.note(&unknown_scope());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let tag = match self.hir.find(scope.node_id(&self.region_maps())) {
|
let tag = match self.hir.find(scope.node_id()) {
|
||||||
Some(hir_map::NodeBlock(_)) => "block",
|
Some(hir_map::NodeBlock(_)) => "block",
|
||||||
Some(hir_map::NodeExpr(expr)) => match expr.node {
|
Some(hir_map::NodeExpr(expr)) => match expr.node {
|
||||||
hir::ExprCall(..) => "call",
|
hir::ExprCall(..) => "call",
|
||||||
@ -151,7 +151,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let scope_decorated_tag = match self.region_maps().code_extent_data(scope) {
|
let scope_decorated_tag = match *scope {
|
||||||
region::CodeExtentData::Misc(_) => tag,
|
region::CodeExtentData::Misc(_) => tag,
|
||||||
region::CodeExtentData::CallSiteScope { .. } => {
|
region::CodeExtentData::CallSiteScope { .. } => {
|
||||||
"scope of call-site for function"
|
"scope of call-site for function"
|
||||||
@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = fr.scope.map(|s| s.node_id(&self.region_maps()))
|
let node = fr.scope.map(|s| s.node_id())
|
||||||
.unwrap_or(DUMMY_NODE_ID);
|
.unwrap_or(DUMMY_NODE_ID);
|
||||||
let unknown;
|
let unknown;
|
||||||
let tag = match self.hir.find(node) {
|
let tag = match self.hir.find(node) {
|
||||||
@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
values.1.push_normal("<");
|
values.1.push_normal("<");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lifetime_display(lifetime: &Region) -> String {
|
fn lifetime_display(lifetime: Region) -> String {
|
||||||
let s = format!("{}", lifetime);
|
let s = format!("{}", lifetime);
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
"'_".to_string()
|
"'_".to_string()
|
||||||
@ -769,7 +769,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn report_generic_bound_failure(&self,
|
fn report_generic_bound_failure(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
bound_kind: GenericKind<'tcx>,
|
bound_kind: GenericKind<'tcx>,
|
||||||
sub: &'tcx Region)
|
sub: Region<'tcx>)
|
||||||
{
|
{
|
||||||
// FIXME: it would be better to report the first error message
|
// FIXME: it would be better to report the first error message
|
||||||
// with the span of the parameter itself, rather than the span
|
// with the span of the parameter itself, rather than the span
|
||||||
@ -848,9 +848,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn report_sub_sup_conflict(&self,
|
fn report_sub_sup_conflict(&self,
|
||||||
var_origin: RegionVariableOrigin,
|
var_origin: RegionVariableOrigin,
|
||||||
sub_origin: SubregionOrigin<'tcx>,
|
sub_origin: SubregionOrigin<'tcx>,
|
||||||
sub_region: &'tcx Region,
|
sub_region: Region<'tcx>,
|
||||||
sup_origin: SubregionOrigin<'tcx>,
|
sup_origin: SubregionOrigin<'tcx>,
|
||||||
sup_region: &'tcx Region) {
|
sup_region: Region<'tcx>) {
|
||||||
let mut err = self.report_inference_failure(var_origin);
|
let mut err = self.report_inference_failure(var_origin);
|
||||||
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
@ -146,8 +146,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub(super) fn report_concrete_failure(&self,
|
pub(super) fn report_concrete_failure(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: &'tcx Region,
|
sub: Region<'tcx>,
|
||||||
sup: &'tcx Region)
|
sup: Region<'tcx>)
|
||||||
-> DiagnosticBuilder<'tcx> {
|
-> DiagnosticBuilder<'tcx> {
|
||||||
match origin {
|
match origin {
|
||||||
infer::Subtype(trace) => {
|
infer::Subtype(trace) => {
|
||||||
|
@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReEarlyBound(..) |
|
ty::ReEarlyBound(..) |
|
||||||
ty::ReLateBound(..) => {
|
ty::ReLateBound(..) => {
|
||||||
|
@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(v) if self.region_vars.contains(&v) => {
|
ty::ReVar(v) if self.region_vars.contains(&v) => {
|
||||||
self.infcx.next_region_var(self.origin.clone())
|
self.infcx.next_region_var(self.origin.clone())
|
||||||
|
@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
|||||||
lattice::super_lattice_tys(self, a, b)
|
lattice::super_lattice_tys(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
-> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?})",
|
debug!("{}.regions({:?}, {:?})",
|
||||||
self.tag(),
|
self.tag(),
|
||||||
a,
|
a,
|
||||||
|
@ -269,9 +269,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||||||
snapshot: &CombinedSnapshot,
|
snapshot: &CombinedSnapshot,
|
||||||
debruijn: ty::DebruijnIndex,
|
debruijn: ty::DebruijnIndex,
|
||||||
new_vars: &[ty::RegionVid],
|
new_vars: &[ty::RegionVid],
|
||||||
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
|
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||||
r0: &'tcx ty::Region)
|
r0: ty::Region<'tcx>)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
// Regions that pre-dated the LUB computation stay as they are.
|
// Regions that pre-dated the LUB computation stay as they are.
|
||||||
if !is_var_in_set(new_vars, r0) {
|
if !is_var_in_set(new_vars, r0) {
|
||||||
assert!(!r0.is_bound());
|
assert!(!r0.is_bound());
|
||||||
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||||||
// Variables created during LUB computation which are
|
// Variables created during LUB computation which are
|
||||||
// *related* to regions that pre-date the LUB computation
|
// *related* to regions that pre-date the LUB computation
|
||||||
// stay as they are.
|
// stay as they are.
|
||||||
if !tainted.iter().all(|r| is_var_in_set(new_vars, *r)) {
|
if !tainted.iter().all(|&r| is_var_in_set(new_vars, r)) {
|
||||||
debug!("generalize_region(r0={:?}): \
|
debug!("generalize_region(r0={:?}): \
|
||||||
non-new-variables found in {:?}",
|
non-new-variables found in {:?}",
|
||||||
r0, tainted);
|
r0, tainted);
|
||||||
@ -365,11 +365,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||||||
snapshot: &CombinedSnapshot,
|
snapshot: &CombinedSnapshot,
|
||||||
debruijn: ty::DebruijnIndex,
|
debruijn: ty::DebruijnIndex,
|
||||||
new_vars: &[ty::RegionVid],
|
new_vars: &[ty::RegionVid],
|
||||||
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
|
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||||
a_vars: &[ty::RegionVid],
|
a_vars: &[ty::RegionVid],
|
||||||
b_vars: &[ty::RegionVid],
|
b_vars: &[ty::RegionVid],
|
||||||
r0: &'tcx ty::Region)
|
r0: ty::Region<'tcx>)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
if !is_var_in_set(new_vars, r0) {
|
if !is_var_in_set(new_vars, r0) {
|
||||||
assert!(!r0.is_bound());
|
assert!(!r0.is_bound());
|
||||||
return r0;
|
return r0;
|
||||||
@ -434,8 +434,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
a_map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>,
|
a_map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||||
r: &'tcx ty::Region) -> &'tcx ty::Region
|
r: ty::Region<'tcx>) -> ty::Region<'tcx>
|
||||||
{
|
{
|
||||||
for (a_br, a_r) in a_map {
|
for (a_br, a_r) in a_map {
|
||||||
if *a_r == r {
|
if *a_r == r {
|
||||||
@ -450,14 +450,14 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
debruijn: ty::DebruijnIndex)
|
debruijn: ty::DebruijnIndex)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
infcx.region_vars.new_bound(debruijn)
|
infcx.region_vars.new_bound(debruijn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
|
fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
|
||||||
map: &FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
|
map: &FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||||
-> Vec<ty::RegionVid> {
|
-> Vec<ty::RegionVid> {
|
||||||
map.iter()
|
map.iter()
|
||||||
.map(|(_, &r)| match *r {
|
.map(|(_, &r)| match *r {
|
||||||
@ -472,7 +472,7 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>,
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_var_in_set(new_vars: &[ty::RegionVid], r: &ty::Region) -> bool {
|
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
|
ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
|
||||||
_ => false
|
_ => false
|
||||||
@ -484,7 +484,7 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
mut fldr: F)
|
mut fldr: F)
|
||||||
-> T
|
-> T
|
||||||
where T: TypeFoldable<'tcx>,
|
where T: TypeFoldable<'tcx>,
|
||||||
F: FnMut(&'tcx ty::Region, ty::DebruijnIndex) -> &'tcx ty::Region,
|
F: FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
|
||||||
{
|
{
|
||||||
tcx.fold_regions(unbound_value, &mut false, |region, current_depth| {
|
tcx.fold_regions(unbound_value, &mut false, |region, current_depth| {
|
||||||
// we should only be encountering "escaping" late-bound regions here,
|
// we should only be encountering "escaping" late-bound regions here,
|
||||||
@ -502,9 +502,9 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
fn tainted_regions(&self,
|
fn tainted_regions(&self,
|
||||||
snapshot: &CombinedSnapshot,
|
snapshot: &CombinedSnapshot,
|
||||||
r: &'tcx ty::Region,
|
r: ty::Region<'tcx>,
|
||||||
directions: TaintDirections)
|
directions: TaintDirections)
|
||||||
-> FxHashSet<&'tcx ty::Region> {
|
-> FxHashSet<ty::Region<'tcx>> {
|
||||||
self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions)
|
self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,7 +731,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// region back to the `ty::BoundRegion` that it originally
|
// region back to the `ty::BoundRegion` that it originally
|
||||||
// represented. Because `leak_check` passed, we know that
|
// represented. Because `leak_check` passed, we know that
|
||||||
// these taint sets are mutually disjoint.
|
// these taint sets are mutually disjoint.
|
||||||
let inv_skol_map: FxHashMap<&'tcx ty::Region, ty::BoundRegion> =
|
let inv_skol_map: FxHashMap<ty::Region<'tcx>, ty::BoundRegion> =
|
||||||
skol_map
|
skol_map
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(&skol_br, &skol)| {
|
.flat_map(|(&skol_br, &skol)| {
|
||||||
|
@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
|||||||
lattice::super_lattice_tys(self, a, b)
|
lattice::super_lattice_tys(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
-> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?})",
|
debug!("{}.regions({:?}, {:?})",
|
||||||
self.tag(),
|
self.tag(),
|
||||||
a,
|
a,
|
||||||
|
@ -205,7 +205,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||||||
|
|
||||||
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
|
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
|
||||||
/// region that each late-bound region was replaced with.
|
/// region that each late-bound region was replaced with.
|
||||||
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
|
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, ty::Region<'tcx>>;
|
||||||
|
|
||||||
/// See `error_reporting` module for more details
|
/// See `error_reporting` module for more details
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -1008,7 +1008,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_given(&self,
|
pub fn add_given(&self,
|
||||||
sub: ty::FreeRegion,
|
sub: ty::FreeRegion<'tcx>,
|
||||||
sup: ty::RegionVid)
|
sup: ty::RegionVid)
|
||||||
{
|
{
|
||||||
self.region_vars.add_given(sub, sup);
|
self.region_vars.add_given(sub, sup);
|
||||||
@ -1107,8 +1107,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn sub_regions(&self,
|
pub fn sub_regions(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
a: &'tcx ty::Region,
|
a: ty::Region<'tcx>,
|
||||||
b: &'tcx ty::Region) {
|
b: ty::Region<'tcx>) {
|
||||||
debug!("sub_regions({:?} <: {:?})", a, b);
|
debug!("sub_regions({:?} <: {:?})", a, b);
|
||||||
self.region_vars.make_subregion(origin, a, b);
|
self.region_vars.make_subregion(origin, a, b);
|
||||||
}
|
}
|
||||||
@ -1210,7 +1210,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_region_var(&self, origin: RegionVariableOrigin)
|
pub fn next_region_var(&self, origin: RegionVariableOrigin)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
|
self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1219,7 +1219,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn region_var_for_def(&self,
|
pub fn region_var_for_def(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
def: &ty::RegionParameterDef)
|
def: &ty::RegionParameterDef)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
|
self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1270,7 +1270,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region {
|
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region<'tcx> {
|
||||||
self.region_vars.new_bound(debruijn)
|
self.region_vars.new_bound(debruijn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,7 +1322,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_regions_and_report_errors(&self,
|
pub fn resolve_regions_and_report_errors(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
subject_node_id: ast::NodeId) {
|
subject_node_id: ast::NodeId) {
|
||||||
let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
|
let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
|
||||||
if !self.is_tainted_by_errors() {
|
if !self.is_tainted_by_errors() {
|
||||||
@ -1531,7 +1531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
lbrct: LateBoundRegionConversionTime,
|
lbrct: LateBoundRegionConversionTime,
|
||||||
value: &ty::Binder<T>)
|
value: &ty::Binder<T>)
|
||||||
-> (T, FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
|
-> (T, FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||||
where T : TypeFoldable<'tcx>
|
where T : TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
self.tcx.replace_late_bound_regions(
|
self.tcx.replace_late_bound_regions(
|
||||||
@ -1577,7 +1577,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn verify_generic_bound(&self,
|
pub fn verify_generic_bound(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
kind: GenericKind<'tcx>,
|
kind: GenericKind<'tcx>,
|
||||||
a: &'tcx ty::Region,
|
a: ty::Region<'tcx>,
|
||||||
bound: VerifyBound<'tcx>) {
|
bound: VerifyBound<'tcx>) {
|
||||||
debug!("verify_generic_bound({:?}, {:?} <: {:?})",
|
debug!("verify_generic_bound({:?}, {:?} <: {:?})",
|
||||||
kind,
|
kind,
|
||||||
|
@ -123,20 +123,20 @@ struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
graph_name: String,
|
graph_name: String,
|
||||||
map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
|
map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
|
||||||
node_ids: FxHashMap<Node, usize>,
|
node_ids: FxHashMap<Node<'tcx>, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
|
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
|
||||||
enum Node {
|
enum Node<'tcx> {
|
||||||
RegionVid(ty::RegionVid),
|
RegionVid(ty::RegionVid),
|
||||||
Region(ty::Region),
|
Region(ty::RegionKind<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// type Edge = Constraint;
|
// type Edge = Constraint;
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
|
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
|
||||||
enum Edge<'tcx> {
|
enum Edge<'tcx> {
|
||||||
Constraint(Constraint<'tcx>),
|
Constraint(Constraint<'tcx>),
|
||||||
EnclScope(CodeExtent, CodeExtent),
|
EnclScope(CodeExtent<'tcx>, CodeExtent<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
|
||||||
@ -160,8 +160,8 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcx.region_maps().each_encl_scope(|sub, sup| {
|
tcx.region_maps().each_encl_scope(|sub, sup| {
|
||||||
add_node(Node::Region(ty::ReScope(*sub)));
|
add_node(Node::Region(ty::ReScope(sub)));
|
||||||
add_node(Node::Region(ty::ReScope(*sup)));
|
add_node(Node::Region(ty::ReScope(sup)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
||||||
type Node = Node;
|
type Node = Node<'tcx>;
|
||||||
type Edge = Edge<'tcx>;
|
type Edge = Edge<'tcx>;
|
||||||
fn graph_id(&self) -> dot::Id {
|
fn graph_id(&self) -> dot::Id {
|
||||||
dot::Id::new(&*self.graph_name).unwrap()
|
dot::Id::new(&*self.graph_name).unwrap()
|
||||||
@ -208,7 +208,7 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
|
fn constraint_to_nodes<'tcx>(c: &Constraint<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
|
||||||
match *c {
|
match *c {
|
||||||
Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
|
Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
|
||||||
(Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
|
(Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
|
||||||
@ -221,7 +221,7 @@ fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edge_to_nodes(e: &Edge) -> (Node, Node) {
|
fn edge_to_nodes<'tcx>(e: &Edge<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
|
||||||
match *e {
|
match *e {
|
||||||
Edge::Constraint(ref c) => constraint_to_nodes(c),
|
Edge::Constraint(ref c) => constraint_to_nodes(c),
|
||||||
Edge::EnclScope(sub, sup) => {
|
Edge::EnclScope(sub, sup) => {
|
||||||
@ -232,9 +232,9 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
||||||
type Node = Node;
|
type Node = Node<'tcx>;
|
||||||
type Edge = Edge<'tcx>;
|
type Edge = Edge<'tcx>;
|
||||||
fn nodes(&self) -> dot::Nodes<Node> {
|
fn nodes(&self) -> dot::Nodes<Node<'tcx>> {
|
||||||
let mut set = FxHashSet();
|
let mut set = FxHashSet();
|
||||||
for node in self.node_ids.keys() {
|
for node in self.node_ids.keys() {
|
||||||
set.insert(*node);
|
set.insert(*node);
|
||||||
@ -245,16 +245,16 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
|
|||||||
fn edges(&self) -> dot::Edges<Edge<'tcx>> {
|
fn edges(&self) -> dot::Edges<Edge<'tcx>> {
|
||||||
debug!("constraint graph has {} edges", self.map.len());
|
debug!("constraint graph has {} edges", self.map.len());
|
||||||
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
|
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
|
||||||
self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
|
self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
|
||||||
debug!("region graph has {} edges", v.len());
|
debug!("region graph has {} edges", v.len());
|
||||||
Cow::Owned(v)
|
Cow::Owned(v)
|
||||||
}
|
}
|
||||||
fn source(&self, edge: &Edge<'tcx>) -> Node {
|
fn source(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
|
||||||
let (n1, _) = edge_to_nodes(edge);
|
let (n1, _) = edge_to_nodes(edge);
|
||||||
debug!("edge {:?} has source {:?}", edge, n1);
|
debug!("edge {:?} has source {:?}", edge, n1);
|
||||||
n1
|
n1
|
||||||
}
|
}
|
||||||
fn target(&self, edge: &Edge<'tcx>) -> Node {
|
fn target(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
|
||||||
let (_, n2) = edge_to_nodes(edge);
|
let (_, n2) = edge_to_nodes(edge);
|
||||||
debug!("edge {:?} has target {:?}", edge, n2);
|
debug!("edge {:?} has target {:?}", edge, n2);
|
||||||
n2
|
n2
|
||||||
|
@ -44,17 +44,17 @@ pub enum Constraint<'tcx> {
|
|||||||
ConstrainVarSubVar(RegionVid, RegionVid),
|
ConstrainVarSubVar(RegionVid, RegionVid),
|
||||||
|
|
||||||
// Concrete region is subregion of region variable
|
// Concrete region is subregion of region variable
|
||||||
ConstrainRegSubVar(&'tcx Region, RegionVid),
|
ConstrainRegSubVar(Region<'tcx>, RegionVid),
|
||||||
|
|
||||||
// Region variable is subregion of concrete region. This does not
|
// Region variable is subregion of concrete region. This does not
|
||||||
// directly affect inference, but instead is checked after
|
// directly affect inference, but instead is checked after
|
||||||
// inference is complete.
|
// inference is complete.
|
||||||
ConstrainVarSubReg(RegionVid, &'tcx Region),
|
ConstrainVarSubReg(RegionVid, Region<'tcx>),
|
||||||
|
|
||||||
// A constraint where neither side is a variable. This does not
|
// A constraint where neither side is a variable. This does not
|
||||||
// directly affect inference, but instead is checked after
|
// directly affect inference, but instead is checked after
|
||||||
// inference is complete.
|
// inference is complete.
|
||||||
ConstrainRegSubReg(&'tcx Region, &'tcx Region),
|
ConstrainRegSubReg(Region<'tcx>, Region<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
|
// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
|
||||||
@ -66,7 +66,7 @@ pub enum Constraint<'tcx> {
|
|||||||
pub struct Verify<'tcx> {
|
pub struct Verify<'tcx> {
|
||||||
kind: GenericKind<'tcx>,
|
kind: GenericKind<'tcx>,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
region: &'tcx Region,
|
region: Region<'tcx>,
|
||||||
bound: VerifyBound<'tcx>,
|
bound: VerifyBound<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,14 +86,14 @@ pub enum VerifyBound<'tcx> {
|
|||||||
// Put another way, the subject value is known to outlive all
|
// Put another way, the subject value is known to outlive all
|
||||||
// regions in {R}, so if any of those outlives 'min, then the
|
// regions in {R}, so if any of those outlives 'min, then the
|
||||||
// bound is met.
|
// bound is met.
|
||||||
AnyRegion(Vec<&'tcx Region>),
|
AnyRegion(Vec<Region<'tcx>>),
|
||||||
|
|
||||||
// B = forall {R} --> all 'r in {R} must outlive 'min
|
// B = forall {R} --> all 'r in {R} must outlive 'min
|
||||||
//
|
//
|
||||||
// Put another way, the subject value is known to outlive some
|
// Put another way, the subject value is known to outlive some
|
||||||
// region in {R}, so if all of those outlives 'min, then the bound
|
// region in {R}, so if all of those outlives 'min, then the bound
|
||||||
// is met.
|
// is met.
|
||||||
AllRegions(Vec<&'tcx Region>),
|
AllRegions(Vec<Region<'tcx>>),
|
||||||
|
|
||||||
// B = exists {B} --> 'min must meet some bound b in {B}
|
// B = exists {B} --> 'min must meet some bound b in {B}
|
||||||
AnyBound(Vec<VerifyBound<'tcx>>),
|
AnyBound(Vec<VerifyBound<'tcx>>),
|
||||||
@ -104,8 +104,8 @@ pub enum VerifyBound<'tcx> {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct TwoRegions<'tcx> {
|
pub struct TwoRegions<'tcx> {
|
||||||
a: &'tcx Region,
|
a: Region<'tcx>,
|
||||||
b: &'tcx Region,
|
b: Region<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
@ -128,7 +128,7 @@ pub enum UndoLogEntry<'tcx> {
|
|||||||
AddVerify(usize),
|
AddVerify(usize),
|
||||||
|
|
||||||
/// We added the given `given`
|
/// We added the given `given`
|
||||||
AddGiven(ty::FreeRegion, ty::RegionVid),
|
AddGiven(ty::FreeRegion<'tcx>, ty::RegionVid),
|
||||||
|
|
||||||
/// We added a GLB/LUB "combinaton variable"
|
/// We added a GLB/LUB "combinaton variable"
|
||||||
AddCombination(CombineMapType, TwoRegions<'tcx>),
|
AddCombination(CombineMapType, TwoRegions<'tcx>),
|
||||||
@ -153,13 +153,13 @@ pub enum RegionResolutionError<'tcx> {
|
|||||||
/// `ConcreteFailure(o, a, b)`:
|
/// `ConcreteFailure(o, a, b)`:
|
||||||
///
|
///
|
||||||
/// `o` requires that `a <= b`, but this does not hold
|
/// `o` requires that `a <= b`, but this does not hold
|
||||||
ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
|
ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>),
|
||||||
|
|
||||||
/// `GenericBoundFailure(p, s, a)
|
/// `GenericBoundFailure(p, s, a)
|
||||||
///
|
///
|
||||||
/// The parameter/associated-type `p` must be known to outlive the lifetime
|
/// The parameter/associated-type `p` must be known to outlive the lifetime
|
||||||
/// `a` (but none of the known bounds are sufficient).
|
/// `a` (but none of the known bounds are sufficient).
|
||||||
GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, &'tcx Region),
|
GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region<'tcx>),
|
||||||
|
|
||||||
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
|
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
|
||||||
///
|
///
|
||||||
@ -168,14 +168,14 @@ pub enum RegionResolutionError<'tcx> {
|
|||||||
/// `sub_r <= sup_r` does not hold.
|
/// `sub_r <= sup_r` does not hold.
|
||||||
SubSupConflict(RegionVariableOrigin,
|
SubSupConflict(RegionVariableOrigin,
|
||||||
SubregionOrigin<'tcx>,
|
SubregionOrigin<'tcx>,
|
||||||
&'tcx Region,
|
Region<'tcx>,
|
||||||
SubregionOrigin<'tcx>,
|
SubregionOrigin<'tcx>,
|
||||||
&'tcx Region),
|
Region<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ProcessedErrorOrigin<'tcx> {
|
pub enum ProcessedErrorOrigin<'tcx> {
|
||||||
ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region),
|
ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>),
|
||||||
VariableFailure(RegionVariableOrigin),
|
VariableFailure(RegionVariableOrigin),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||||||
// record the fact that `'a <= 'b` is implied by the fn signature,
|
// record the fact that `'a <= 'b` is implied by the fn signature,
|
||||||
// and then ignore the constraint when solving equations. This is
|
// and then ignore the constraint when solving equations. This is
|
||||||
// a bit of a hack but seems to work.
|
// a bit of a hack but seems to work.
|
||||||
givens: RefCell<FxHashSet<(ty::FreeRegion, ty::RegionVid)>>,
|
givens: RefCell<FxHashSet<(ty::FreeRegion<'tcx>, ty::RegionVid)>>,
|
||||||
|
|
||||||
lubs: RefCell<CombineMap<'tcx>>,
|
lubs: RefCell<CombineMap<'tcx>>,
|
||||||
glbs: RefCell<CombineMap<'tcx>>,
|
glbs: RefCell<CombineMap<'tcx>>,
|
||||||
@ -271,12 +271,12 @@ impl TaintDirections {
|
|||||||
|
|
||||||
struct TaintSet<'tcx> {
|
struct TaintSet<'tcx> {
|
||||||
directions: TaintDirections,
|
directions: TaintDirections,
|
||||||
regions: FxHashSet<&'tcx ty::Region>
|
regions: FxHashSet<ty::Region<'tcx>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
|
impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
|
||||||
fn new(directions: TaintDirections,
|
fn new(directions: TaintDirections,
|
||||||
initial_region: &'tcx ty::Region)
|
initial_region: ty::Region<'tcx>)
|
||||||
-> Self {
|
-> Self {
|
||||||
let mut regions = FxHashSet();
|
let mut regions = FxHashSet();
|
||||||
regions.insert(initial_region);
|
regions.insert(initial_region);
|
||||||
@ -328,7 +328,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_set(self) -> FxHashSet<&'tcx ty::Region> {
|
fn into_set(self) -> FxHashSet<ty::Region<'tcx>> {
|
||||||
self.regions
|
self.regions
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,8 +337,8 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_edge(&mut self,
|
fn add_edge(&mut self,
|
||||||
source: &'tcx ty::Region,
|
source: ty::Region<'tcx>,
|
||||||
target: &'tcx ty::Region) {
|
target: ty::Region<'tcx>) {
|
||||||
if self.directions.incoming {
|
if self.directions.incoming {
|
||||||
if self.regions.contains(&target) {
|
if self.regions.contains(&target) {
|
||||||
self.regions.insert(source);
|
self.regions.insert(source);
|
||||||
@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// it's just there to make it explicit which snapshot bounds the
|
/// it's just there to make it explicit which snapshot bounds the
|
||||||
/// skolemized region that results. It should always be the top-most snapshot.
|
/// skolemized region that results. It should always be the top-most snapshot.
|
||||||
pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot)
|
pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot)
|
||||||
-> &'tcx Region {
|
-> Region<'tcx> {
|
||||||
assert!(self.in_snapshot());
|
assert!(self.in_snapshot());
|
||||||
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
|
assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// completes to remove all trace of the skolemized regions
|
/// completes to remove all trace of the skolemized regions
|
||||||
/// created in that time.
|
/// created in that time.
|
||||||
pub fn pop_skolemized(&self,
|
pub fn pop_skolemized(&self,
|
||||||
skols: &FxHashSet<&'tcx ty::Region>,
|
skols: &FxHashSet<ty::Region<'tcx>>,
|
||||||
snapshot: &RegionSnapshot) {
|
snapshot: &RegionSnapshot) {
|
||||||
debug!("pop_skolemized_regions(skols={:?})", skols);
|
debug!("pop_skolemized_regions(skols={:?})", skols);
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
self.skolemization_count.set(snapshot.skolemization_count);
|
self.skolemization_count.set(snapshot.skolemization_count);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fn kill_constraint<'tcx>(skols: &FxHashSet<&'tcx ty::Region>,
|
fn kill_constraint<'tcx>(skols: &FxHashSet<ty::Region<'tcx>>,
|
||||||
undo_entry: &UndoLogEntry<'tcx>)
|
undo_entry: &UndoLogEntry<'tcx>)
|
||||||
-> bool {
|
-> bool {
|
||||||
match undo_entry {
|
match undo_entry {
|
||||||
@ -596,7 +596,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> &'tcx Region {
|
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region<'tcx> {
|
||||||
// Creates a fresh bound variable for use in GLB computations.
|
// Creates a fresh bound variable for use in GLB computations.
|
||||||
// See discussion of GLB computation in the large comment at
|
// See discussion of GLB computation in the large comment at
|
||||||
// the top of this file for more details.
|
// the top of this file for more details.
|
||||||
@ -662,7 +662,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
|
pub fn add_given(&self, sub: ty::FreeRegion<'tcx>, sup: ty::RegionVid) {
|
||||||
// cannot add givens once regions are resolved
|
// cannot add givens once regions are resolved
|
||||||
assert!(self.values_are_none());
|
assert!(self.values_are_none());
|
||||||
|
|
||||||
@ -676,8 +676,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn make_eqregion(&self,
|
pub fn make_eqregion(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: &'tcx Region,
|
sub: Region<'tcx>,
|
||||||
sup: &'tcx Region) {
|
sup: Region<'tcx>) {
|
||||||
if sub != sup {
|
if sub != sup {
|
||||||
// Eventually, it would be nice to add direct support for
|
// Eventually, it would be nice to add direct support for
|
||||||
// equating regions.
|
// equating regions.
|
||||||
@ -692,8 +692,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn make_subregion(&self,
|
pub fn make_subregion(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
sub: &'tcx Region,
|
sub: Region<'tcx>,
|
||||||
sup: &'tcx Region) {
|
sup: Region<'tcx>) {
|
||||||
// cannot add constraints once regions are resolved
|
// cannot add constraints once regions are resolved
|
||||||
assert!(self.values_are_none());
|
assert!(self.values_are_none());
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
pub fn verify_generic_bound(&self,
|
pub fn verify_generic_bound(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
kind: GenericKind<'tcx>,
|
kind: GenericKind<'tcx>,
|
||||||
sub: &'tcx Region,
|
sub: Region<'tcx>,
|
||||||
bound: VerifyBound<'tcx>) {
|
bound: VerifyBound<'tcx>) {
|
||||||
self.add_verify(Verify {
|
self.add_verify(Verify {
|
||||||
kind: kind,
|
kind: kind,
|
||||||
@ -746,9 +746,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn lub_regions(&self,
|
pub fn lub_regions(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
a: &'tcx Region,
|
a: Region<'tcx>,
|
||||||
b: &'tcx Region)
|
b: Region<'tcx>)
|
||||||
-> &'tcx Region {
|
-> Region<'tcx> {
|
||||||
// cannot add constraints once regions are resolved
|
// cannot add constraints once regions are resolved
|
||||||
assert!(self.values_are_none());
|
assert!(self.values_are_none());
|
||||||
|
|
||||||
@ -772,9 +772,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn glb_regions(&self,
|
pub fn glb_regions(&self,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
a: &'tcx Region,
|
a: Region<'tcx>,
|
||||||
b: &'tcx Region)
|
b: Region<'tcx>)
|
||||||
-> &'tcx Region {
|
-> Region<'tcx> {
|
||||||
// cannot add constraints once regions are resolved
|
// cannot add constraints once regions are resolved
|
||||||
assert!(self.values_are_none());
|
assert!(self.values_are_none());
|
||||||
|
|
||||||
@ -796,7 +796,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
|
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
|
||||||
match *self.values.borrow() {
|
match *self.values.borrow() {
|
||||||
None => {
|
None => {
|
||||||
span_bug!((*self.var_origins.borrow())[rid.index as usize].span(),
|
span_bug!((*self.var_origins.borrow())[rid.index as usize].span(),
|
||||||
@ -811,7 +811,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> &'tcx ty::Region {
|
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
|
||||||
let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
|
let vid = self.unification_table.borrow_mut().find_value(rid).min_vid;
|
||||||
self.tcx.mk_region(ty::ReVar(vid))
|
self.tcx.mk_region(ty::ReVar(vid))
|
||||||
}
|
}
|
||||||
@ -825,12 +825,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn combine_vars<F>(&self,
|
pub fn combine_vars<F>(&self,
|
||||||
t: CombineMapType,
|
t: CombineMapType,
|
||||||
a: &'tcx Region,
|
a: Region<'tcx>,
|
||||||
b: &'tcx Region,
|
b: Region<'tcx>,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
mut relate: F)
|
mut relate: F)
|
||||||
-> &'tcx Region
|
-> Region<'tcx>
|
||||||
where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, &'tcx Region, &'tcx Region)
|
where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region<'tcx>, Region<'tcx>)
|
||||||
{
|
{
|
||||||
let vars = TwoRegions { a: a, b: b };
|
let vars = TwoRegions { a: a, b: b };
|
||||||
if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
|
if let Some(&c) = self.combine_map(t).borrow().get(&vars) {
|
||||||
@ -869,9 +869,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// related to other regions.
|
/// related to other regions.
|
||||||
pub fn tainted(&self,
|
pub fn tainted(&self,
|
||||||
mark: &RegionSnapshot,
|
mark: &RegionSnapshot,
|
||||||
r0: &'tcx Region,
|
r0: Region<'tcx>,
|
||||||
directions: TaintDirections)
|
directions: TaintDirections)
|
||||||
-> FxHashSet<&'tcx ty::Region> {
|
-> FxHashSet<ty::Region<'tcx>> {
|
||||||
debug!("tainted(mark={:?}, r0={:?}, directions={:?})",
|
debug!("tainted(mark={:?}, r0={:?}, directions={:?})",
|
||||||
mark, r0, directions);
|
mark, r0, directions);
|
||||||
|
|
||||||
@ -892,7 +892,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// constraints, assuming such values can be found; if they cannot,
|
/// constraints, assuming such values can be found; if they cannot,
|
||||||
/// errors are reported.
|
/// errors are reported.
|
||||||
pub fn resolve_regions(&self,
|
pub fn resolve_regions(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
subject_node: ast::NodeId)
|
subject_node: ast::NodeId)
|
||||||
-> Vec<RegionResolutionError<'tcx>> {
|
-> Vec<RegionResolutionError<'tcx>> {
|
||||||
debug!("RegionVarBindings: resolve_regions()");
|
debug!("RegionVarBindings: resolve_regions()");
|
||||||
@ -903,10 +903,10 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lub_concrete_regions(&self,
|
fn lub_concrete_regions(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
a: &'tcx Region,
|
a: Region<'tcx>,
|
||||||
b: &'tcx Region)
|
b: Region<'tcx>)
|
||||||
-> &'tcx Region {
|
-> Region<'tcx> {
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(&ReLateBound(..), _) |
|
(&ReLateBound(..), _) |
|
||||||
(_, &ReLateBound(..)) |
|
(_, &ReLateBound(..)) |
|
||||||
@ -961,8 +961,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
self.tcx.region_maps().nearest_common_ancestor(a_id, b_id)))
|
self.tcx.region_maps().nearest_common_ancestor(a_id, b_id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ReFree(a_fr), &ReFree(b_fr)) => {
|
(&ReFree(_), &ReFree(_)) => {
|
||||||
self.tcx.mk_region(free_regions.lub_free_regions(a_fr, b_fr))
|
free_regions.lub_free_regions(self.tcx, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For these types, we cannot define any additional
|
// For these types, we cannot define any additional
|
||||||
@ -983,12 +983,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum VarValue<'tcx> {
|
pub enum VarValue<'tcx> {
|
||||||
Value(&'tcx Region),
|
Value(Region<'tcx>),
|
||||||
ErrorValue,
|
ErrorValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RegionAndOrigin<'tcx> {
|
struct RegionAndOrigin<'tcx> {
|
||||||
region: &'tcx Region,
|
region: Region<'tcx>,
|
||||||
origin: SubregionOrigin<'tcx>,
|
origin: SubregionOrigin<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,7 +996,7 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>;
|
|||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
||||||
fn infer_variable_values(&self,
|
fn infer_variable_values(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
errors: &mut Vec<RegionResolutionError<'tcx>>,
|
errors: &mut Vec<RegionResolutionError<'tcx>>,
|
||||||
subject: ast::NodeId)
|
subject: ast::NodeId)
|
||||||
-> Vec<VarValue<'tcx>> {
|
-> Vec<VarValue<'tcx>> {
|
||||||
@ -1056,7 +1056,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expansion(&self, free_regions: &FreeRegionMap, var_values: &mut [VarValue<'tcx>]) {
|
fn expansion(&self, free_regions: &FreeRegionMap<'tcx>, var_values: &mut [VarValue<'tcx>]) {
|
||||||
self.iterate_until_fixed_point("Expansion", |constraint, origin| {
|
self.iterate_until_fixed_point("Expansion", |constraint, origin| {
|
||||||
debug!("expansion: constraint={:?} origin={:?}",
|
debug!("expansion: constraint={:?} origin={:?}",
|
||||||
constraint, origin);
|
constraint, origin);
|
||||||
@ -1085,8 +1085,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expand_node(&self,
|
fn expand_node(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
a_region: &'tcx Region,
|
a_region: Region<'tcx>,
|
||||||
b_vid: RegionVid,
|
b_vid: RegionVid,
|
||||||
b_data: &mut VarValue<'tcx>)
|
b_data: &mut VarValue<'tcx>)
|
||||||
-> bool {
|
-> bool {
|
||||||
@ -1132,7 +1132,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// cases where the region cannot grow larger than a fixed point)
|
/// cases where the region cannot grow larger than a fixed point)
|
||||||
/// and check that they are satisfied.
|
/// and check that they are satisfied.
|
||||||
fn collect_errors(&self,
|
fn collect_errors(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
var_data: &mut Vec<VarValue<'tcx>>,
|
var_data: &mut Vec<VarValue<'tcx>>,
|
||||||
errors: &mut Vec<RegionResolutionError<'tcx>>) {
|
errors: &mut Vec<RegionResolutionError<'tcx>>) {
|
||||||
let constraints = self.constraints.borrow();
|
let constraints = self.constraints.borrow();
|
||||||
@ -1209,7 +1209,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
/// Go over the variables that were declared to be error variables
|
/// Go over the variables that were declared to be error variables
|
||||||
/// and create a `RegionResolutionError` for each of them.
|
/// and create a `RegionResolutionError` for each of them.
|
||||||
fn collect_var_errors(&self,
|
fn collect_var_errors(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
var_data: &[VarValue<'tcx>],
|
var_data: &[VarValue<'tcx>],
|
||||||
graph: &RegionGraph<'tcx>,
|
graph: &RegionGraph<'tcx>,
|
||||||
errors: &mut Vec<RegionResolutionError<'tcx>>) {
|
errors: &mut Vec<RegionResolutionError<'tcx>>) {
|
||||||
@ -1311,7 +1311,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn collect_error_for_expanding_node(&self,
|
fn collect_error_for_expanding_node(&self,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
graph: &RegionGraph<'tcx>,
|
graph: &RegionGraph<'tcx>,
|
||||||
dup_vec: &mut [u32],
|
dup_vec: &mut [u32],
|
||||||
node_idx: RegionVid,
|
node_idx: RegionVid,
|
||||||
@ -1480,8 +1480,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
values: &Vec<VarValue<'tcx>>,
|
values: &Vec<VarValue<'tcx>>,
|
||||||
r: &'tcx ty::Region)
|
r: ty::Region<'tcx>)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(rid) => lookup(tcx, values, rid),
|
ty::ReVar(rid) => lookup(tcx, values, rid),
|
||||||
_ => r,
|
_ => r,
|
||||||
@ -1491,7 +1491,7 @@ fn normalize<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
values: &Vec<VarValue<'tcx>>,
|
values: &Vec<VarValue<'tcx>>,
|
||||||
rid: ty::RegionVid)
|
rid: ty::RegionVid)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
match values[rid.index as usize] {
|
match values[rid.index as usize] {
|
||||||
Value(r) => r,
|
Value(r) => r,
|
||||||
ErrorValue => tcx.types.re_static, // Previously reported error.
|
ErrorValue => tcx.types.re_static, // Previously reported error.
|
||||||
@ -1539,7 +1539,7 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
|
impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
|
||||||
fn for_each_region(&self, f: &mut FnMut(&'tcx ty::Region)) {
|
fn for_each_region(&self, f: &mut FnMut(ty::Region<'tcx>)) {
|
||||||
match self {
|
match self {
|
||||||
&VerifyBound::AnyRegion(ref rs) |
|
&VerifyBound::AnyRegion(ref rs) |
|
||||||
&VerifyBound::AllRegions(ref rs) => for &r in rs {
|
&VerifyBound::AllRegions(ref rs) => for &r in rs {
|
||||||
@ -1592,9 +1592,9 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
free_regions: &FreeRegionMap,
|
free_regions: &FreeRegionMap<'tcx>,
|
||||||
var_values: &Vec<VarValue<'tcx>>,
|
var_values: &Vec<VarValue<'tcx>>,
|
||||||
min: &'tcx ty::Region)
|
min: ty::Region<'tcx>)
|
||||||
-> bool {
|
-> bool {
|
||||||
match self {
|
match self {
|
||||||
&VerifyBound::AnyRegion(ref rs) =>
|
&VerifyBound::AnyRegion(ref rs) =>
|
||||||
|
@ -72,7 +72,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
|
ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid),
|
||||||
_ => r,
|
_ => r,
|
||||||
@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
|
ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
|
||||||
_ => r,
|
_ => r,
|
||||||
|
@ -127,8 +127,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
-> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?}) self.cause={:?}",
|
debug!("{}.regions({:?}, {:?}) self.cause={:?}",
|
||||||
self.tag(), a, b, self.fields.cause);
|
self.tag(), a, b, self.fields.cause);
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub trait Delegate<'tcx> {
|
|||||||
borrow_id: ast::NodeId,
|
borrow_id: ast::NodeId,
|
||||||
borrow_span: Span,
|
borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
loan_cause: LoanCause);
|
loan_cause: LoanCause);
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn borrow_expr(&mut self,
|
fn borrow_expr(&mut self,
|
||||||
expr: &hir::Expr,
|
expr: &hir::Expr,
|
||||||
r: &'tcx ty::Region,
|
r: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
cause: LoanCause) {
|
cause: LoanCause) {
|
||||||
debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})",
|
debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})",
|
||||||
|
@ -15,18 +15,21 @@
|
|||||||
//! `TransitiveRelation` type and use that to decide when one free
|
//! `TransitiveRelation` type and use that to decide when one free
|
||||||
//! region outlives another and so forth.
|
//! region outlives another and so forth.
|
||||||
|
|
||||||
use ty::{self, TyCtxt, FreeRegion, Region};
|
use ty::{self, Lift, TyCtxt, Region};
|
||||||
use ty::wf::ImpliedBound;
|
use ty::wf::ImpliedBound;
|
||||||
use rustc_data_structures::transitive_relation::TransitiveRelation;
|
use rustc_data_structures::transitive_relation::TransitiveRelation;
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||||
pub struct FreeRegionMap {
|
pub struct FreeRegionMap<'tcx> {
|
||||||
// Stores the relation `a < b`, where `a` and `b` are regions.
|
// Stores the relation `a < b`, where `a` and `b` are regions.
|
||||||
relation: TransitiveRelation<Region>
|
//
|
||||||
|
// Invariant: only free regions like `'x` or `'static` are stored
|
||||||
|
// in this relation, not scopes.
|
||||||
|
relation: TransitiveRelation<Region<'tcx>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FreeRegionMap {
|
impl<'tcx> FreeRegionMap<'tcx> {
|
||||||
pub fn new() -> FreeRegionMap {
|
pub fn new() -> Self {
|
||||||
FreeRegionMap { relation: TransitiveRelation::new() }
|
FreeRegionMap { relation: TransitiveRelation::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,15 +37,16 @@ impl FreeRegionMap {
|
|||||||
self.relation.is_empty()
|
self.relation.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
|
pub fn relate_free_regions_from_implied_bounds(&mut self,
|
||||||
implied_bounds: &[ImpliedBound<'tcx>])
|
implied_bounds: &[ImpliedBound<'tcx>])
|
||||||
{
|
{
|
||||||
debug!("relate_free_regions_from_implied_bounds()");
|
debug!("relate_free_regions_from_implied_bounds()");
|
||||||
for implied_bound in implied_bounds {
|
for implied_bound in implied_bounds {
|
||||||
debug!("implied bound: {:?}", implied_bound);
|
debug!("implied bound: {:?}", implied_bound);
|
||||||
match *implied_bound {
|
match *implied_bound {
|
||||||
ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
|
ImpliedBound::RegionSubRegion(a @ &ty::ReFree(_), b @ &ty::ReFree(_)) |
|
||||||
self.relate_free_regions(free_a, free_b);
|
ImpliedBound::RegionSubRegion(a @ &ty::ReStatic, b @ &ty::ReFree(_)) => {
|
||||||
|
self.relate_regions(a, b);
|
||||||
}
|
}
|
||||||
ImpliedBound::RegionSubRegion(..) |
|
ImpliedBound::RegionSubRegion(..) |
|
||||||
ImpliedBound::RegionSubParam(..) |
|
ImpliedBound::RegionSubParam(..) |
|
||||||
@ -53,7 +57,7 @@ impl FreeRegionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn relate_free_regions_from_predicates(&mut self,
|
pub fn relate_free_regions_from_predicates(&mut self,
|
||||||
predicates: &[ty::Predicate]) {
|
predicates: &[ty::Predicate<'tcx>]) {
|
||||||
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
|
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
|
||||||
for predicate in predicates {
|
for predicate in predicates {
|
||||||
match *predicate {
|
match *predicate {
|
||||||
@ -69,12 +73,15 @@ impl FreeRegionMap {
|
|||||||
}
|
}
|
||||||
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
|
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
|
||||||
match (r_a, r_b) {
|
match (r_a, r_b) {
|
||||||
|
// `'static: 'x` is not notable
|
||||||
(&ty::ReStatic, &ty::ReFree(_)) => {},
|
(&ty::ReStatic, &ty::ReFree(_)) => {},
|
||||||
(&ty::ReFree(fr_a), &ty::ReStatic) => self.relate_to_static(fr_a),
|
|
||||||
(&ty::ReFree(fr_a), &ty::ReFree(fr_b)) => {
|
(&ty::ReFree(_), &ty::ReStatic) |
|
||||||
|
(&ty::ReFree(_), &ty::ReFree(_)) => {
|
||||||
// Record that `'a:'b`. Or, put another way, `'b <= 'a`.
|
// Record that `'a:'b`. Or, put another way, `'b <= 'a`.
|
||||||
self.relate_free_regions(fr_b, fr_a);
|
self.relate_regions(r_b, r_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
// All named regions are instantiated with free regions.
|
// All named regions are instantiated with free regions.
|
||||||
bug!("record_region_bounds: non free region: {:?} / {:?}",
|
bug!("record_region_bounds: non free region: {:?} / {:?}",
|
||||||
@ -87,48 +94,36 @@ impl FreeRegionMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relate_to_static(&mut self, sup: FreeRegion) {
|
fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
|
||||||
self.relation.add(ty::ReStatic, ty::ReFree(sup));
|
assert!(match *sub { ty::ReFree(_) | ty::ReStatic => true, _ => false });
|
||||||
|
assert!(match *sup { ty::ReFree(_) | ty::ReStatic => true, _ => false });
|
||||||
|
self.relation.add(sub, sup)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) {
|
pub fn lub_free_regions<'a, 'gcx>(&self,
|
||||||
self.relation.add(ty::ReFree(sub), ty::ReFree(sup))
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
}
|
r_a: Region<'tcx>,
|
||||||
|
r_b: Region<'tcx>)
|
||||||
/// Determines whether two free regions have a subregion relationship
|
-> Region<'tcx> {
|
||||||
/// by walking the graph encoded in `map`. Note that
|
assert!(match *r_a { ty::ReFree(_) => true, _ => false });
|
||||||
/// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
|
assert!(match *r_b { ty::ReFree(_) => true, _ => false });
|
||||||
/// (that is, the user can give two different names to the same lifetime).
|
let result = if r_a == r_b { r_a } else {
|
||||||
pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool {
|
|
||||||
let result = sub == sup || {
|
|
||||||
let sub = ty::ReFree(sub);
|
|
||||||
let sup = ty::ReFree(sup);
|
|
||||||
self.relation.contains(&sub, &sup) || self.relation.contains(&ty::ReStatic, &sup)
|
|
||||||
};
|
|
||||||
debug!("sub_free_region(sub={:?}, sup={:?}) = {:?}", sub, sup, result);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lub_free_regions(&self, fr_a: FreeRegion, fr_b: FreeRegion) -> Region {
|
|
||||||
let r_a = ty::ReFree(fr_a);
|
|
||||||
let r_b = ty::ReFree(fr_b);
|
|
||||||
let result = if fr_a == fr_b { r_a } else {
|
|
||||||
match self.relation.postdom_upper_bound(&r_a, &r_b) {
|
match self.relation.postdom_upper_bound(&r_a, &r_b) {
|
||||||
None => ty::ReStatic,
|
None => tcx.mk_region(ty::ReStatic),
|
||||||
Some(r) => *r,
|
Some(r) => *r,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("lub_free_regions(fr_a={:?}, fr_b={:?}) = {:?}", fr_a, fr_b, result);
|
debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether one region is a subregion of another. This is intended to run *after
|
/// Determines whether one region is a subregion of another. This is intended to run *after
|
||||||
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
|
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
|
||||||
pub fn is_subregion_of(&self,
|
pub fn is_subregion_of<'a, 'gcx>(&self,
|
||||||
tcx: TyCtxt,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
sub_region: &ty::Region,
|
sub_region: ty::Region<'tcx>,
|
||||||
super_region: &ty::Region)
|
super_region: ty::Region<'tcx>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let result = sub_region == super_region || {
|
let result = sub_region == super_region || {
|
||||||
match (sub_region, super_region) {
|
match (sub_region, super_region) {
|
||||||
(&ty::ReEmpty, _) |
|
(&ty::ReEmpty, _) |
|
||||||
@ -141,17 +136,18 @@ impl FreeRegionMap {
|
|||||||
(&ty::ReScope(sub_scope), &ty::ReFree(fr)) => {
|
(&ty::ReScope(sub_scope), &ty::ReFree(fr)) => {
|
||||||
// 1. It is safe to unwrap `fr.scope` because we
|
// 1. It is safe to unwrap `fr.scope` because we
|
||||||
// should only ever wind up comparing against
|
// should only ever wind up comparing against
|
||||||
// `ReScope` in the context of a method or fn
|
// `ReScope` in the context of a method or
|
||||||
// body, where `fr.scope` should be `Some`.
|
// body, where `fr.scope` should be `Some`.
|
||||||
tcx.region_maps().is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) ||
|
tcx.region_maps().is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) ||
|
||||||
self.is_static(fr)
|
self.is_static(tcx, super_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) =>
|
(&ty::ReFree(_), &ty::ReFree(_)) =>
|
||||||
self.sub_free_region(sub_fr, super_fr),
|
self.relation.contains(&sub_region, &super_region) ||
|
||||||
|
self.is_static(tcx, super_region),
|
||||||
|
|
||||||
(&ty::ReStatic, &ty::ReFree(sup_fr)) =>
|
(&ty::ReStatic, &ty::ReFree(_)) =>
|
||||||
self.is_static(sup_fr),
|
self.is_static(tcx, super_region),
|
||||||
|
|
||||||
_ =>
|
_ =>
|
||||||
false,
|
false,
|
||||||
@ -163,28 +159,28 @@ impl FreeRegionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether this free-region is required to be 'static
|
/// Determines whether this free-region is required to be 'static
|
||||||
pub fn is_static(&self, super_region: ty::FreeRegion) -> bool {
|
fn is_static<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, super_region: ty::Region<'tcx>)
|
||||||
|
-> bool {
|
||||||
debug!("is_static(super_region={:?})", super_region);
|
debug!("is_static(super_region={:?})", super_region);
|
||||||
self.relation.contains(&ty::ReStatic, &ty::ReFree(super_region))
|
match *super_region {
|
||||||
|
ty::ReStatic => true,
|
||||||
|
ty::ReFree(_) => {
|
||||||
|
let re_static = tcx.mk_region(ty::ReStatic);
|
||||||
|
self.relation.contains(&re_static, &super_region)
|
||||||
|
}
|
||||||
|
_ => bug!("only free regions should be given to `is_static`")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
|
||||||
fn free_region(index: u32) -> FreeRegion {
|
|
||||||
FreeRegion { scope: None, bound_region: ty::BoundRegion::BrAnon(index) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lub() {
|
|
||||||
// a very VERY basic test, but see the tests in
|
|
||||||
// TransitiveRelation, which are much more thorough.
|
|
||||||
let frs: Vec<_> = (0..3).map(|i| free_region(i)).collect();
|
|
||||||
let mut map = FreeRegionMap::new();
|
|
||||||
map.relate_free_regions(frs[0], frs[2]);
|
|
||||||
map.relate_free_regions(frs[1], frs[2]);
|
|
||||||
assert_eq!(map.lub_free_regions(frs[0], frs[1]), ty::ReFree(frs[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_stable_hash_for!(struct FreeRegionMap {
|
|
||||||
relation
|
relation
|
||||||
});
|
});
|
||||||
|
|
||||||
|
impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
|
||||||
|
type Lifted = FreeRegionMap<'tcx>;
|
||||||
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
|
||||||
|
self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx))
|
||||||
|
.map(|relation| FreeRegionMap { relation })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1441,7 +1441,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
// and must outlive the *call-site* of the function.
|
// and must outlive the *call-site* of the function.
|
||||||
let fn_ret =
|
let fn_ret =
|
||||||
self.ir.tcx.liberate_late_bound_regions(
|
self.ir.tcx.liberate_late_bound_regions(
|
||||||
Some(self.ir.tcx.region_maps().call_site_extent(id, body.value.id)),
|
Some(self.ir.tcx.call_site_extent(id, body.value.id)),
|
||||||
&fn_ret);
|
&fn_ret);
|
||||||
|
|
||||||
if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
|
if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
|
||||||
|
@ -89,7 +89,7 @@ use std::rc::Rc;
|
|||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum Categorization<'tcx> {
|
pub enum Categorization<'tcx> {
|
||||||
// temporary val, argument is its scope
|
// temporary val, argument is its scope
|
||||||
Rvalue(&'tcx ty::Region, &'tcx ty::Region),
|
Rvalue(ty::Region<'tcx>, ty::Region<'tcx>),
|
||||||
StaticItem,
|
StaticItem,
|
||||||
Upvar(Upvar), // upvar referenced by closure env
|
Upvar(Upvar), // upvar referenced by closure env
|
||||||
Local(ast::NodeId), // local variable
|
Local(ast::NodeId), // local variable
|
||||||
@ -114,13 +114,13 @@ pub enum PointerKind<'tcx> {
|
|||||||
Unique,
|
Unique,
|
||||||
|
|
||||||
/// `&T`
|
/// `&T`
|
||||||
BorrowedPtr(ty::BorrowKind, &'tcx ty::Region),
|
BorrowedPtr(ty::BorrowKind, ty::Region<'tcx>),
|
||||||
|
|
||||||
/// `*T`
|
/// `*T`
|
||||||
UnsafePtr(hir::Mutability),
|
UnsafePtr(hir::Mutability),
|
||||||
|
|
||||||
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
|
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
|
||||||
Implicit(ty::BorrowKind, &'tcx ty::Region),
|
Implicit(ty::BorrowKind, ty::Region<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use the term "interior" to mean "something reachable from the
|
// We use the term "interior" to mean "something reachable from the
|
||||||
@ -796,7 +796,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
// The environment of a closure is guaranteed to
|
// The environment of a closure is guaranteed to
|
||||||
// outlive any bindings introduced in the body of the
|
// outlive any bindings introduced in the body of the
|
||||||
// closure itself.
|
// closure itself.
|
||||||
scope: Some(self.tcx().region_maps().item_extent(fn_body_id)),
|
scope: Some(self.tcx().item_extent(fn_body_id)),
|
||||||
bound_region: ty::BrEnv
|
bound_region: ty::BrEnv
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -842,10 +842,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
/// Returns the lifetime of a temporary created by expr with id `id`.
|
/// Returns the lifetime of a temporary created by expr with id `id`.
|
||||||
/// This could be `'static` if `id` is part of a constant expression.
|
/// This could be `'static` if `id` is part of a constant expression.
|
||||||
pub fn temporary_scope(&self, id: ast::NodeId) -> (&'tcx ty::Region, &'tcx ty::Region)
|
pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>)
|
||||||
{
|
{
|
||||||
let (scope, old_scope) =
|
let (scope, old_scope) =
|
||||||
self.tcx().region_maps().old_and_new_temporary_scope(id);
|
self.tcx().region_maps().old_and_new_temporary_scope(self.tcx(), id);
|
||||||
(self.tcx().mk_region(match scope {
|
(self.tcx().mk_region(match scope {
|
||||||
Some(scope) => ty::ReScope(scope),
|
Some(scope) => ty::ReScope(scope),
|
||||||
None => ty::ReStatic
|
None => ty::ReStatic
|
||||||
@ -887,8 +887,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||||||
pub fn cat_rvalue(&self,
|
pub fn cat_rvalue(&self,
|
||||||
cmt_id: ast::NodeId,
|
cmt_id: ast::NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
temp_scope: &'tcx ty::Region,
|
temp_scope: ty::Region<'tcx>,
|
||||||
old_temp_scope: &'tcx ty::Region,
|
old_temp_scope: ty::Region<'tcx>,
|
||||||
expr_ty: Ty<'tcx>) -> cmt<'tcx> {
|
expr_ty: Ty<'tcx>) -> cmt<'tcx> {
|
||||||
let ret = Rc::new(cmt_ {
|
let ret = Rc::new(cmt_ {
|
||||||
id:cmt_id,
|
id:cmt_id,
|
||||||
|
@ -17,14 +17,12 @@
|
|||||||
//! `middle/infer/region_inference/README.md`
|
//! `middle/infer/region_inference/README.md`
|
||||||
|
|
||||||
use hir::map as hir_map;
|
use hir::map as hir_map;
|
||||||
use session::Session;
|
|
||||||
use util::nodemap::{FxHashMap, NodeMap, NodeSet};
|
use util::nodemap::{FxHashMap, NodeMap, NodeSet};
|
||||||
use ty;
|
use ty;
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
|
||||||
use std::fmt;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use serialize;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::ast::{self, NodeId};
|
use syntax::ast::{self, NodeId};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
@ -34,33 +32,12 @@ use ty::maps::Providers;
|
|||||||
use hir;
|
use hir;
|
||||||
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
use hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
|
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
|
||||||
use hir::{Body, Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
|
use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
|
pub type CodeExtent<'tcx> = &'tcx CodeExtentData;
|
||||||
RustcDecodable, Copy)]
|
|
||||||
pub struct CodeExtent(u32);
|
|
||||||
|
|
||||||
impl fmt::Debug for CodeExtent {
|
impl<'tcx> serialize::UseSpecializedEncodable for CodeExtent<'tcx> {}
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl<'tcx> serialize::UseSpecializedDecodable for CodeExtent<'tcx> {}
|
||||||
write!(f, "CodeExtent({:?}", self.0)?;
|
|
||||||
|
|
||||||
ty::tls::with_opt(|opt_tcx| {
|
|
||||||
if let Some(tcx) = opt_tcx {
|
|
||||||
let region_maps = tcx.region_maps();
|
|
||||||
{
|
|
||||||
let code_extents = ®ion_maps.code_extents;
|
|
||||||
if let Some(data) = code_extents.get(self.0 as usize) {
|
|
||||||
write!(f, "/{:?}", data)?;
|
|
||||||
}
|
|
||||||
mem::drop(code_extents); // FIXME why is this necessary?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
write!(f, ")")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CodeExtent represents a statically-describable extent that can be
|
/// CodeExtent represents a statically-describable extent that can be
|
||||||
/// used to bound the lifetime/region for values.
|
/// used to bound the lifetime/region for values.
|
||||||
@ -123,7 +100,7 @@ impl fmt::Debug for CodeExtent {
|
|||||||
/// placate the same deriving in `ty::FreeRegion`, but we may want to
|
/// placate the same deriving in `ty::FreeRegion`, but we may want to
|
||||||
/// actually attach a more meaningful ordering to scopes than the one
|
/// actually attach a more meaningful ordering to scopes than the one
|
||||||
/// generated via deriving here.
|
/// generated via deriving here.
|
||||||
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy)]
|
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)]
|
||||||
pub enum CodeExtentData {
|
pub enum CodeExtentData {
|
||||||
Misc(ast::NodeId),
|
Misc(ast::NodeId),
|
||||||
|
|
||||||
@ -150,8 +127,8 @@ pub struct CallSiteScopeData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CallSiteScopeData {
|
impl CallSiteScopeData {
|
||||||
pub fn to_code_extent(&self, region_maps: &RegionMaps) -> CodeExtent {
|
pub fn to_code_extent<'a, 'tcx, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CodeExtent<'tcx> {
|
||||||
region_maps.lookup_code_extent(
|
tcx.intern_code_extent(
|
||||||
match *self {
|
match *self {
|
||||||
CallSiteScopeData { fn_id, body_id } =>
|
CallSiteScopeData { fn_id, body_id } =>
|
||||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id },
|
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id },
|
||||||
@ -200,20 +177,14 @@ impl CodeExtentData {
|
|||||||
CodeExtentData::ParameterScope { fn_id: _, body_id } => body_id,
|
CodeExtentData::ParameterScope { fn_id: _, body_id } => body_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl CodeExtent {
|
|
||||||
pub fn node_id(&self, region_maps: &RegionMaps) -> ast::NodeId {
|
|
||||||
region_maps.code_extent_data(*self).node_id()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the span of this CodeExtent. Note that in general the
|
/// Returns the span of this CodeExtent. Note that in general the
|
||||||
/// returned span may not correspond to the span of any node id in
|
/// returned span may not correspond to the span of any node id in
|
||||||
/// the AST.
|
/// the AST.
|
||||||
pub fn span(&self, region_maps: &RegionMaps, hir_map: &hir_map::Map) -> Option<Span> {
|
pub fn span(&self, hir_map: &hir_map::Map) -> Option<Span> {
|
||||||
match hir_map.find(self.node_id(region_maps)) {
|
match hir_map.find(self.node_id()) {
|
||||||
Some(hir_map::NodeBlock(ref blk)) => {
|
Some(hir_map::NodeBlock(ref blk)) => {
|
||||||
match region_maps.code_extent_data(*self) {
|
match *self {
|
||||||
CodeExtentData::CallSiteScope { .. } |
|
CodeExtentData::CallSiteScope { .. } |
|
||||||
CodeExtentData::ParameterScope { .. } |
|
CodeExtentData::ParameterScope { .. } |
|
||||||
CodeExtentData::Misc(_) |
|
CodeExtentData::Misc(_) |
|
||||||
@ -242,20 +213,18 @@ impl CodeExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The region maps encode information about region relationships.
|
/// The region maps encode information about region relationships.
|
||||||
pub struct RegionMaps {
|
pub struct RegionMaps<'tcx> {
|
||||||
code_extents: Vec<CodeExtentData>,
|
|
||||||
code_extent_interner: FxHashMap<CodeExtentData, CodeExtent>,
|
|
||||||
/// `scope_map` maps from a scope id to the enclosing scope id;
|
/// `scope_map` maps from a scope id to the enclosing scope id;
|
||||||
/// this is usually corresponding to the lexical nesting, though
|
/// this is usually corresponding to the lexical nesting, though
|
||||||
/// in the case of closures the parent scope is the innermost
|
/// in the case of closures the parent scope is the innermost
|
||||||
/// conditional expression or repeating block. (Note that the
|
/// conditional expression or repeating block. (Note that the
|
||||||
/// enclosing scope id for the block associated with a closure is
|
/// enclosing scope id for the block associated with a closure is
|
||||||
/// the closure itself.)
|
/// the closure itself.)
|
||||||
scope_map: Vec<Option<CodeExtent>>,
|
scope_map: FxHashMap<CodeExtent<'tcx>, CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// `var_map` maps from a variable or binding id to the block in
|
/// `var_map` maps from a variable or binding id to the block in
|
||||||
/// which that variable is declared.
|
/// which that variable is declared.
|
||||||
var_map: NodeMap<CodeExtent>,
|
var_map: NodeMap<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
|
/// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
|
||||||
/// larger than the default. The map goes from the expression id
|
/// larger than the default. The map goes from the expression id
|
||||||
@ -263,14 +232,14 @@ pub struct RegionMaps {
|
|||||||
/// table, the appropriate cleanup scope is the innermost
|
/// table, the appropriate cleanup scope is the innermost
|
||||||
/// enclosing statement, conditional expression, or repeating
|
/// enclosing statement, conditional expression, or repeating
|
||||||
/// block (see `terminating_scopes`).
|
/// block (see `terminating_scopes`).
|
||||||
rvalue_scopes: NodeMap<CodeExtent>,
|
rvalue_scopes: NodeMap<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// Records the value of rvalue scopes before they were shrunk by
|
/// Records the value of rvalue scopes before they were shrunk by
|
||||||
/// #36082, for error reporting.
|
/// #36082, for error reporting.
|
||||||
///
|
///
|
||||||
/// FIXME: this should be temporary. Remove this by 1.18.0 or
|
/// FIXME: this should be temporary. Remove this by 1.18.0 or
|
||||||
/// so.
|
/// so.
|
||||||
shrunk_rvalue_scopes: NodeMap<CodeExtent>,
|
shrunk_rvalue_scopes: NodeMap<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// Encodes the hierarchy of fn bodies. Every fn body (including
|
/// Encodes the hierarchy of fn bodies. Every fn body (including
|
||||||
/// closures) forms its own distinct region hierarchy, rooted in
|
/// closures) forms its own distinct region hierarchy, rooted in
|
||||||
@ -286,7 +255,7 @@ pub struct RegionMaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Context {
|
pub struct Context<'tcx> {
|
||||||
/// the root of the current region tree. This is typically the id
|
/// the root of the current region tree. This is typically the id
|
||||||
/// of the innermost fn body. Each fn forms its own disjoint tree
|
/// of the innermost fn body. Each fn forms its own disjoint tree
|
||||||
/// in the region hierarchy. These fn bodies are themselves
|
/// in the region hierarchy. These fn bodies are themselves
|
||||||
@ -296,21 +265,21 @@ pub struct Context {
|
|||||||
root_id: Option<ast::NodeId>,
|
root_id: Option<ast::NodeId>,
|
||||||
|
|
||||||
/// the scope that contains any new variables declared
|
/// the scope that contains any new variables declared
|
||||||
var_parent: Option<CodeExtent>,
|
var_parent: Option<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// region parent of expressions etc
|
/// region parent of expressions etc
|
||||||
parent: Option<CodeExtent>,
|
parent: Option<CodeExtent<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RegionResolutionVisitor<'hir: 'a, 'a> {
|
struct RegionResolutionVisitor<'a, 'tcx: 'a> {
|
||||||
sess: &'a Session,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
|
||||||
// Generated maps:
|
// Generated maps:
|
||||||
region_maps: &'a mut RegionMaps,
|
region_maps: &'a mut RegionMaps<'tcx>,
|
||||||
|
|
||||||
cx: Context,
|
cx: Context<'tcx>,
|
||||||
|
|
||||||
map: &'a hir_map::Map<'hir>,
|
map: &'a hir_map::Map<'tcx>,
|
||||||
|
|
||||||
/// `terminating_scopes` is a set containing the ids of each
|
/// `terminating_scopes` is a set containing the ids of each
|
||||||
/// statement, or conditional/repeating expression. These scopes
|
/// statement, or conditional/repeating expression. These scopes
|
||||||
@ -336,64 +305,13 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl RegionMaps {
|
impl<'tcx> RegionMaps<'tcx> {
|
||||||
pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent {
|
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(CodeExtent<'tcx>, CodeExtent<'tcx>) {
|
||||||
match self.code_extent_interner.get(&e) {
|
for (&child, &parent) in &self.scope_map {
|
||||||
Some(&d) => d,
|
e(child, parent)
|
||||||
None => bug!("unknown code extent {:?}", e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn node_extent(&self, n: ast::NodeId) -> CodeExtent {
|
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, CodeExtent<'tcx>) {
|
||||||
self.lookup_code_extent(CodeExtentData::Misc(n))
|
|
||||||
}
|
|
||||||
// Returns the code extent for an item - the destruction scope.
|
|
||||||
pub fn item_extent(&self, n: ast::NodeId) -> CodeExtent {
|
|
||||||
self.lookup_code_extent(CodeExtentData::DestructionScope(n))
|
|
||||||
}
|
|
||||||
pub fn call_site_extent(&self, fn_id: ast::NodeId, body_id: ast::NodeId) -> CodeExtent {
|
|
||||||
assert!(fn_id != body_id);
|
|
||||||
self.lookup_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id })
|
|
||||||
}
|
|
||||||
pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option<CodeExtent> {
|
|
||||||
self.code_extent_interner.get(&CodeExtentData::DestructionScope(n)).cloned()
|
|
||||||
}
|
|
||||||
pub fn intern_code_extent(&mut self,
|
|
||||||
e: CodeExtentData,
|
|
||||||
parent: Option<CodeExtent>) -> CodeExtent {
|
|
||||||
match self.code_extent_interner.entry(e) {
|
|
||||||
Entry::Occupied(_) => {
|
|
||||||
bug!("intern_code_extent: already exists")
|
|
||||||
}
|
|
||||||
Entry::Vacant(v) => {
|
|
||||||
if self.code_extents.len() > 0xffffffffusize {
|
|
||||||
bug!() // should pass a sess,
|
|
||||||
// but this isn't the only place
|
|
||||||
}
|
|
||||||
let idx = CodeExtent(self.code_extents.len() as u32);
|
|
||||||
debug!("CodeExtent({:?}) = {:?} [parent={:?}]", idx, e, parent);
|
|
||||||
self.code_extents.push(e);
|
|
||||||
self.scope_map.push(parent);
|
|
||||||
*v.insert(idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn intern_node(&mut self,
|
|
||||||
n: ast::NodeId,
|
|
||||||
parent: Option<CodeExtent>) -> CodeExtent {
|
|
||||||
self.intern_code_extent(CodeExtentData::Misc(n), parent)
|
|
||||||
}
|
|
||||||
pub fn code_extent_data(&self, e: CodeExtent) -> CodeExtentData {
|
|
||||||
self.code_extents[e.0 as usize]
|
|
||||||
}
|
|
||||||
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) {
|
|
||||||
for child_id in 1..self.code_extents.len() {
|
|
||||||
let child = CodeExtent(child_id as u32);
|
|
||||||
if let Some(parent) = self.opt_encl_scope(child) {
|
|
||||||
e(&child, &parent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
|
|
||||||
for (child, parent) in self.var_map.iter() {
|
for (child, parent) in self.var_map.iter() {
|
||||||
e(child, parent)
|
e(child, parent)
|
||||||
}
|
}
|
||||||
@ -419,45 +337,48 @@ impl RegionMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_var_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
|
fn record_var_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
|
||||||
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
|
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
|
||||||
assert!(var != lifetime.node_id(self));
|
assert!(var != lifetime.node_id());
|
||||||
self.var_map.insert(var, lifetime);
|
self.var_map.insert(var, lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
|
fn record_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
|
||||||
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
|
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
|
||||||
assert!(var != lifetime.node_id(self));
|
assert!(var != lifetime.node_id());
|
||||||
self.rvalue_scopes.insert(var, lifetime);
|
self.rvalue_scopes.insert(var, lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
|
fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent<'tcx>) {
|
||||||
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
|
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
|
||||||
assert!(var != lifetime.node_id(self));
|
assert!(var != lifetime.node_id());
|
||||||
self.shrunk_rvalue_scopes.insert(var, lifetime);
|
self.shrunk_rvalue_scopes.insert(var, lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
|
pub fn opt_encl_scope(&self, id: CodeExtent<'tcx>) -> Option<CodeExtent<'tcx>> {
|
||||||
//! Returns the narrowest scope that encloses `id`, if any.
|
//! Returns the narrowest scope that encloses `id`, if any.
|
||||||
self.scope_map[id.0 as usize]
|
self.scope_map.get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)] // used in cfg
|
#[allow(dead_code)] // used in cfg
|
||||||
pub fn encl_scope(&self, id: CodeExtent) -> CodeExtent {
|
pub fn encl_scope(&self, id: CodeExtent<'tcx>) -> CodeExtent<'tcx> {
|
||||||
//! Returns the narrowest scope that encloses `id`, if any.
|
//! Returns the narrowest scope that encloses `id`, if any.
|
||||||
self.opt_encl_scope(id).unwrap()
|
self.opt_encl_scope(id).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the lifetime of the local variable `var_id`
|
/// Returns the lifetime of the local variable `var_id`
|
||||||
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent {
|
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent<'tcx> {
|
||||||
match self.var_map.get(&var_id) {
|
match self.var_map.get(&var_id) {
|
||||||
Some(&r) => r,
|
Some(&r) => r,
|
||||||
None => { bug!("no enclosing scope for id {:?}", var_id); }
|
None => { bug!("no enclosing scope for id {:?}", var_id); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option<CodeExtent>, bool) {
|
pub fn temporary_scope2<'a, 'gcx: 'tcx>(&self,
|
||||||
let temporary_scope = self.temporary_scope(expr_id);
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
expr_id: ast::NodeId)
|
||||||
|
-> (Option<CodeExtent<'tcx>>, bool) {
|
||||||
|
let temporary_scope = self.temporary_scope(tcx, expr_id);
|
||||||
let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) {
|
let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) {
|
||||||
Some(&s) => {
|
Some(&s) => {
|
||||||
info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})",
|
info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})",
|
||||||
@ -470,17 +391,23 @@ impl RegionMaps {
|
|||||||
(temporary_scope, was_shrunk)
|
(temporary_scope, was_shrunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn old_and_new_temporary_scope(&self, expr_id: ast::NodeId) ->
|
pub fn old_and_new_temporary_scope<'a, 'gcx: 'tcx>(&self,
|
||||||
(Option<CodeExtent>, Option<CodeExtent>)
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
expr_id: ast::NodeId)
|
||||||
|
-> (Option<CodeExtent<'tcx>>,
|
||||||
|
Option<CodeExtent<'tcx>>)
|
||||||
{
|
{
|
||||||
let temporary_scope = self.temporary_scope(expr_id);
|
let temporary_scope = self.temporary_scope(tcx, expr_id);
|
||||||
(temporary_scope,
|
(temporary_scope,
|
||||||
self.shrunk_rvalue_scopes
|
self.shrunk_rvalue_scopes
|
||||||
.get(&expr_id).cloned()
|
.get(&expr_id).cloned()
|
||||||
.or(temporary_scope))
|
.or(temporary_scope))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option<CodeExtent> {
|
pub fn temporary_scope<'a, 'gcx: 'tcx>(&self,
|
||||||
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
expr_id: ast::NodeId)
|
||||||
|
-> Option<CodeExtent<'tcx>> {
|
||||||
//! Returns the scope when temp created by expr_id will be cleaned up
|
//! Returns the scope when temp created by expr_id will be cleaned up
|
||||||
|
|
||||||
// check for a designated rvalue scope
|
// check for a designated rvalue scope
|
||||||
@ -489,17 +416,14 @@ impl RegionMaps {
|
|||||||
return Some(s);
|
return Some(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
let scope_map : &[Option<CodeExtent>] = &self.scope_map;
|
|
||||||
let code_extents: &[CodeExtentData] = &self.code_extents;
|
|
||||||
|
|
||||||
// else, locate the innermost terminating scope
|
// else, locate the innermost terminating scope
|
||||||
// if there's one. Static items, for instance, won't
|
// if there's one. Static items, for instance, won't
|
||||||
// have an enclosing scope, hence no scope will be
|
// have an enclosing scope, hence no scope will be
|
||||||
// returned.
|
// returned.
|
||||||
let mut id = self.node_extent(expr_id);
|
let mut id = tcx.node_extent(expr_id);
|
||||||
|
|
||||||
while let Some(p) = scope_map[id.0 as usize] {
|
while let Some(&p) = self.scope_map.get(id) {
|
||||||
match code_extents[p.0 as usize] {
|
match *p {
|
||||||
CodeExtentData::DestructionScope(..) => {
|
CodeExtentData::DestructionScope(..) => {
|
||||||
debug!("temporary_scope({:?}) = {:?} [enclosing]",
|
debug!("temporary_scope({:?}) = {:?} [enclosing]",
|
||||||
expr_id, id);
|
expr_id, id);
|
||||||
@ -513,7 +437,7 @@ impl RegionMaps {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var_region(&self, id: ast::NodeId) -> ty::Region {
|
pub fn var_region(&self, id: ast::NodeId) -> ty::RegionKind<'tcx> {
|
||||||
//! Returns the lifetime of the variable `id`.
|
//! Returns the lifetime of the variable `id`.
|
||||||
|
|
||||||
let scope = ty::ReScope(self.var_scope(id));
|
let scope = ty::ReScope(self.var_scope(id));
|
||||||
@ -555,9 +479,9 @@ impl RegionMaps {
|
|||||||
/// Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest
|
/// 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`.
|
/// scope which is greater than or equal to both `scope_a` and `scope_b`.
|
||||||
pub fn nearest_common_ancestor(&self,
|
pub fn nearest_common_ancestor(&self,
|
||||||
scope_a: CodeExtent,
|
scope_a: CodeExtent<'tcx>,
|
||||||
scope_b: CodeExtent)
|
scope_b: CodeExtent<'tcx>)
|
||||||
-> CodeExtent {
|
-> CodeExtent<'tcx> {
|
||||||
if scope_a == scope_b { return scope_a; }
|
if scope_a == scope_b { return scope_a; }
|
||||||
|
|
||||||
/// [1] The initial values for `a_buf` and `b_buf` are not used.
|
/// [1] The initial values for `a_buf` and `b_buf` are not used.
|
||||||
@ -565,10 +489,10 @@ impl RegionMaps {
|
|||||||
/// is re-initialized with new values (or else fallback to a
|
/// is re-initialized with new values (or else fallback to a
|
||||||
/// heap-allocated vector).
|
/// heap-allocated vector).
|
||||||
let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32];
|
let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32];
|
||||||
let mut a_vec: Vec<CodeExtent> = vec![];
|
let mut a_vec: Vec<CodeExtent<'tcx>> = vec![];
|
||||||
let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32];
|
let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32];
|
||||||
let mut b_vec: Vec<CodeExtent> = vec![];
|
let mut b_vec: Vec<CodeExtent<'tcx>> = vec![];
|
||||||
let scope_map : &[Option<CodeExtent>] = &self.scope_map;
|
let scope_map = &self.scope_map;
|
||||||
let a_ancestors = ancestors_of(scope_map, scope_a, &mut a_buf, &mut a_vec);
|
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 b_ancestors = ancestors_of(scope_map, scope_b, &mut b_buf, &mut b_vec);
|
||||||
let mut a_index = a_ancestors.len() - 1;
|
let mut a_index = a_ancestors.len() - 1;
|
||||||
@ -588,11 +512,11 @@ impl RegionMaps {
|
|||||||
// nesting. The reasoning behind this is subtle. See the
|
// nesting. The reasoning behind this is subtle. See the
|
||||||
// "Modeling closures" section of the README in
|
// "Modeling closures" section of the README in
|
||||||
// infer::region_inference for more details.
|
// infer::region_inference for more details.
|
||||||
let a_root_scope = self.code_extent_data(a_ancestors[a_index]);
|
let a_root_scope = a_ancestors[a_index];
|
||||||
let b_root_scope = self.code_extent_data(a_ancestors[a_index]);
|
let b_root_scope = a_ancestors[a_index];
|
||||||
return match (a_root_scope, b_root_scope) {
|
return match (a_root_scope, b_root_scope) {
|
||||||
(CodeExtentData::DestructionScope(a_root_id),
|
(&CodeExtentData::DestructionScope(a_root_id),
|
||||||
CodeExtentData::DestructionScope(b_root_id)) => {
|
&CodeExtentData::DestructionScope(b_root_id)) => {
|
||||||
if self.fn_is_enclosed_by(a_root_id, b_root_id) {
|
if self.fn_is_enclosed_by(a_root_id, b_root_id) {
|
||||||
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
|
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
|
||||||
scope_b
|
scope_b
|
||||||
@ -623,18 +547,18 @@ impl RegionMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ancestors_of<'a>(scope_map: &[Option<CodeExtent>],
|
fn ancestors_of<'a, 'tcx>(scope_map: &FxHashMap<CodeExtent<'tcx>, CodeExtent<'tcx>>,
|
||||||
scope: CodeExtent,
|
scope: CodeExtent<'tcx>,
|
||||||
buf: &'a mut [CodeExtent; 32],
|
buf: &'a mut [CodeExtent<'tcx>; 32],
|
||||||
vec: &'a mut Vec<CodeExtent>)
|
vec: &'a mut Vec<CodeExtent<'tcx>>)
|
||||||
-> &'a [CodeExtent] {
|
-> &'a [CodeExtent<'tcx>] {
|
||||||
// debug!("ancestors_of(scope={:?})", scope);
|
// debug!("ancestors_of(scope={:?})", scope);
|
||||||
let mut scope = scope;
|
let mut scope = scope;
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < 32 {
|
while i < 32 {
|
||||||
buf[i] = scope;
|
buf[i] = scope;
|
||||||
match scope_map[scope.0 as usize] {
|
match scope_map.get(&scope) {
|
||||||
Some(superscope) => scope = superscope,
|
Some(superscope) => scope = superscope,
|
||||||
_ => return &buf[..i+1]
|
_ => return &buf[..i+1]
|
||||||
}
|
}
|
||||||
@ -645,7 +569,7 @@ impl RegionMaps {
|
|||||||
vec.extend_from_slice(buf);
|
vec.extend_from_slice(buf);
|
||||||
loop {
|
loop {
|
||||||
vec.push(scope);
|
vec.push(scope);
|
||||||
match scope_map[scope.0 as usize] {
|
match scope_map.get(&scope) {
|
||||||
Some(superscope) => scope = superscope,
|
Some(superscope) => scope = superscope,
|
||||||
_ => return &*vec
|
_ => return &*vec
|
||||||
}
|
}
|
||||||
@ -669,7 +593,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: &'tcx hir::Block) {
|
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk: &'tcx hir::Block) {
|
||||||
debug!("resolve_block(blk.id={:?})", blk.id);
|
debug!("resolve_block(blk.id={:?})", blk.id);
|
||||||
|
|
||||||
let prev_cx = visitor.cx;
|
let prev_cx = visitor.cx;
|
||||||
@ -740,7 +664,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk:
|
|||||||
visitor.cx = prev_cx;
|
visitor.cx = prev_cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) {
|
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) {
|
||||||
visitor.terminating_scopes.insert(arm.body.id);
|
visitor.terminating_scopes.insert(arm.body.id);
|
||||||
|
|
||||||
if let Some(ref expr) = arm.guard {
|
if let Some(ref expr) = arm.guard {
|
||||||
@ -750,7 +674,7 @@ fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &
|
|||||||
intravisit::walk_arm(visitor, arm);
|
intravisit::walk_arm(visitor, arm);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) {
|
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: &'tcx hir::Pat) {
|
||||||
visitor.new_node_extent(pat.id);
|
visitor.new_node_extent(pat.id);
|
||||||
|
|
||||||
// If this is a binding then record the lifetime of that binding.
|
// If this is a binding then record the lifetime of that binding.
|
||||||
@ -761,7 +685,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &
|
|||||||
intravisit::walk_pat(visitor, pat);
|
intravisit::walk_pat(visitor, pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) {
|
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) {
|
||||||
let stmt_id = stmt.node.id();
|
let stmt_id = stmt.node.id();
|
||||||
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
|
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
|
||||||
|
|
||||||
@ -779,7 +703,7 @@ fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt:
|
|||||||
visitor.cx.parent = prev_parent;
|
visitor.cx.parent = prev_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) {
|
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||||
debug!("resolve_expr(expr.id={:?})", expr.id);
|
debug!("resolve_expr(expr.id={:?})", expr.id);
|
||||||
|
|
||||||
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
|
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
|
||||||
@ -857,7 +781,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr:
|
|||||||
visitor.cx = prev_cx;
|
visitor.cx = prev_cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||||
local: &'tcx hir::Local) {
|
local: &'tcx hir::Local) {
|
||||||
debug!("resolve_local(local.id={:?},local.init={:?})",
|
debug!("resolve_local(local.id={:?},local.init={:?})",
|
||||||
local.id,local.init.is_some());
|
local.id,local.init.is_some());
|
||||||
@ -998,9 +922,11 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
|||||||
/// | box E&
|
/// | box E&
|
||||||
/// | E& as ...
|
/// | E& as ...
|
||||||
/// | ( E& )
|
/// | ( E& )
|
||||||
fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor,
|
fn record_rvalue_scope_if_borrow_expr<'a, 'tcx>(
|
||||||
expr: &hir::Expr,
|
visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||||
blk_id: CodeExtent) {
|
expr: &hir::Expr,
|
||||||
|
blk_id: CodeExtent<'tcx>)
|
||||||
|
{
|
||||||
match expr.node {
|
match expr.node {
|
||||||
hir::ExprAddrOf(_, ref subexpr) => {
|
hir::ExprAddrOf(_, ref subexpr) => {
|
||||||
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
|
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
|
||||||
@ -1047,10 +973,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
|||||||
/// | <rvalue>
|
/// | <rvalue>
|
||||||
///
|
///
|
||||||
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
|
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
|
||||||
fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor,
|
fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||||
expr: &'a hir::Expr,
|
expr: &hir::Expr,
|
||||||
blk_scope: CodeExtent,
|
blk_scope: CodeExtent<'tcx>,
|
||||||
is_shrunk: bool) {
|
is_shrunk: bool) {
|
||||||
let mut expr = expr;
|
let mut expr = expr;
|
||||||
loop {
|
loop {
|
||||||
// Note: give all the expressions matching `ET` with the
|
// Note: give all the expressions matching `ET` with the
|
||||||
@ -1081,10 +1007,8 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, walk: F)
|
||||||
id: ast::NodeId,
|
where F: FnOnce(&mut RegionResolutionVisitor<'a, 'tcx>)
|
||||||
walk: F)
|
|
||||||
where F: FnOnce(&mut RegionResolutionVisitor<'tcx, 'a>)
|
|
||||||
{
|
{
|
||||||
// Items create a new outer block scope as far as we're concerned.
|
// Items create a new outer block scope as far as we're concerned.
|
||||||
let prev_cx = visitor.cx;
|
let prev_cx = visitor.cx;
|
||||||
@ -1095,12 +1019,11 @@ fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a
|
|||||||
parent: None,
|
parent: None,
|
||||||
};
|
};
|
||||||
walk(visitor);
|
walk(visitor);
|
||||||
visitor.create_item_scope_if_needed(id);
|
|
||||||
visitor.cx = prev_cx;
|
visitor.cx = prev_cx;
|
||||||
visitor.terminating_scopes = prev_ts;
|
visitor.terminating_scopes = prev_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||||
kind: FnKind<'tcx>,
|
kind: FnKind<'tcx>,
|
||||||
decl: &'tcx hir::FnDecl,
|
decl: &'tcx hir::FnDecl,
|
||||||
body_id: hir::BodyId,
|
body_id: hir::BodyId,
|
||||||
@ -1111,7 +1034,7 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
|||||||
body.id={:?}, \
|
body.id={:?}, \
|
||||||
cx.parent={:?})",
|
cx.parent={:?})",
|
||||||
id,
|
id,
|
||||||
visitor.sess.codemap().span_to_string(sp),
|
visitor.tcx.sess.codemap().span_to_string(sp),
|
||||||
body_id,
|
body_id,
|
||||||
visitor.cx.parent);
|
visitor.cx.parent);
|
||||||
|
|
||||||
@ -1152,17 +1075,37 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
|
|||||||
visitor.terminating_scopes = outer_ts;
|
visitor.terminating_scopes = outer_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> {
|
impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> {
|
||||||
/// Records the current parent (if any) as the parent of `child_scope`.
|
pub fn intern_code_extent(&mut self,
|
||||||
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent {
|
data: CodeExtentData,
|
||||||
self.region_maps.intern_code_extent(child_scope, self.cx.parent)
|
parent: Option<CodeExtent<'tcx>>)
|
||||||
|
-> CodeExtent<'tcx> {
|
||||||
|
let code_extent = self.tcx.intern_code_extent(data);
|
||||||
|
debug!("{:?}.parent = {:?}", code_extent, parent);
|
||||||
|
if let Some(p) = parent {
|
||||||
|
let prev = self.region_maps.scope_map.insert(code_extent, p);
|
||||||
|
assert!(prev.is_none());
|
||||||
|
}
|
||||||
|
code_extent
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_node_extent(&mut self, child_scope: ast::NodeId) -> CodeExtent {
|
pub fn intern_node(&mut self,
|
||||||
|
n: ast::NodeId,
|
||||||
|
parent: Option<CodeExtent<'tcx>>) -> CodeExtent<'tcx> {
|
||||||
|
self.intern_code_extent(CodeExtentData::Misc(n), parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Records the current parent (if any) as the parent of `child_scope`.
|
||||||
|
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent<'tcx> {
|
||||||
|
let parent = self.cx.parent;
|
||||||
|
self.intern_code_extent(child_scope, parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_node_extent(&mut self, child_scope: ast::NodeId) -> CodeExtent<'tcx> {
|
||||||
self.new_code_extent(CodeExtentData::Misc(child_scope))
|
self.new_code_extent(CodeExtentData::Misc(child_scope))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent {
|
fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent<'tcx> {
|
||||||
// If node was previously marked as a terminating scope during the
|
// If node was previously marked as a terminating scope during the
|
||||||
// recursive visit of its parent node in the AST, then we need to
|
// 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 extent of
|
||||||
@ -1170,101 +1113,79 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> {
|
|||||||
if self.terminating_scopes.contains(&id) {
|
if self.terminating_scopes.contains(&id) {
|
||||||
let ds = self.new_code_extent(
|
let ds = self.new_code_extent(
|
||||||
CodeExtentData::DestructionScope(id));
|
CodeExtentData::DestructionScope(id));
|
||||||
self.region_maps.intern_node(id, Some(ds))
|
self.intern_node(id, Some(ds))
|
||||||
} else {
|
} else {
|
||||||
self.new_node_extent(id)
|
self.new_node_extent(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_item_scope_if_needed(&mut self, id: ast::NodeId) {
|
|
||||||
// create a region for the destruction scope - this is needed
|
|
||||||
// for constructing parameter environments based on the item.
|
|
||||||
// functions put their destruction scopes *inside* their parameter
|
|
||||||
// scopes.
|
|
||||||
let scope = CodeExtentData::DestructionScope(id);
|
|
||||||
if !self.region_maps.code_extent_interner.contains_key(&scope) {
|
|
||||||
self.region_maps.intern_code_extent(scope, None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> {
|
impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
|
||||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
|
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||||
NestedVisitorMap::OnlyBodies(&self.map)
|
NestedVisitorMap::OnlyBodies(&self.map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_body(&mut self, b: &'hir Body) {
|
fn visit_block(&mut self, b: &'tcx Block) {
|
||||||
// make sure that every body owner has an item scope, since
|
|
||||||
// MIR construction wants that
|
|
||||||
let owner = self.map.body_owner(b.id());
|
|
||||||
self.create_item_scope_if_needed(owner);
|
|
||||||
|
|
||||||
intravisit::walk_body(self, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_block(&mut self, b: &'hir Block) {
|
|
||||||
resolve_block(self, b);
|
resolve_block(self, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(&mut self, i: &'hir Item) {
|
fn visit_item(&mut self, i: &'tcx Item) {
|
||||||
resolve_item_like(self, i.id, |this| intravisit::walk_item(this, i));
|
resolve_item_like(self, |this| intravisit::walk_item(this, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) {
|
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
|
||||||
resolve_item_like(self, ii.id, |this| intravisit::walk_impl_item(this, ii));
|
resolve_item_like(self, |this| intravisit::walk_impl_item(this, ii));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) {
|
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
|
||||||
resolve_item_like(self, ti.id, |this| intravisit::walk_trait_item(this, ti));
|
resolve_item_like(self, |this| intravisit::walk_trait_item(this, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_fn(&mut self, fk: FnKind<'hir>, fd: &'hir FnDecl,
|
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx FnDecl,
|
||||||
b: hir::BodyId, s: Span, n: NodeId) {
|
b: hir::BodyId, s: Span, n: NodeId) {
|
||||||
resolve_fn(self, fk, fd, b, s, n);
|
resolve_fn(self, fk, fd, b, s, n);
|
||||||
}
|
}
|
||||||
fn visit_arm(&mut self, a: &'hir Arm) {
|
fn visit_arm(&mut self, a: &'tcx Arm) {
|
||||||
resolve_arm(self, a);
|
resolve_arm(self, a);
|
||||||
}
|
}
|
||||||
fn visit_pat(&mut self, p: &'hir Pat) {
|
fn visit_pat(&mut self, p: &'tcx Pat) {
|
||||||
resolve_pat(self, p);
|
resolve_pat(self, p);
|
||||||
}
|
}
|
||||||
fn visit_stmt(&mut self, s: &'hir Stmt) {
|
fn visit_stmt(&mut self, s: &'tcx Stmt) {
|
||||||
resolve_stmt(self, s);
|
resolve_stmt(self, s);
|
||||||
}
|
}
|
||||||
fn visit_expr(&mut self, ex: &'hir Expr) {
|
fn visit_expr(&mut self, ex: &'tcx Expr) {
|
||||||
resolve_expr(self, ex);
|
resolve_expr(self, ex);
|
||||||
}
|
}
|
||||||
fn visit_local(&mut self, l: &'hir Local) {
|
fn visit_local(&mut self, l: &'tcx Local) {
|
||||||
resolve_local(self, l);
|
resolve_local(self, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<RegionMaps> {
|
pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<RegionMaps<'tcx>> {
|
||||||
tcx.region_resolve_crate(LOCAL_CRATE)
|
tcx.region_resolve_crate(LOCAL_CRATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
|
fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
|
||||||
-> Rc<RegionMaps>
|
-> Rc<RegionMaps<'tcx>>
|
||||||
{
|
{
|
||||||
debug_assert!(crate_num == LOCAL_CRATE);
|
debug_assert!(crate_num == LOCAL_CRATE);
|
||||||
|
|
||||||
let sess = &tcx.sess;
|
|
||||||
let hir_map = &tcx.hir;
|
let hir_map = &tcx.hir;
|
||||||
|
|
||||||
let krate = hir_map.krate();
|
let krate = hir_map.krate();
|
||||||
|
|
||||||
let mut maps = RegionMaps {
|
let mut maps = RegionMaps {
|
||||||
code_extents: vec![],
|
scope_map: FxHashMap(),
|
||||||
code_extent_interner: FxHashMap(),
|
|
||||||
scope_map: vec![],
|
|
||||||
var_map: NodeMap(),
|
var_map: NodeMap(),
|
||||||
rvalue_scopes: NodeMap(),
|
rvalue_scopes: NodeMap(),
|
||||||
shrunk_rvalue_scopes: NodeMap(),
|
shrunk_rvalue_scopes: NodeMap(),
|
||||||
fn_tree: NodeMap(),
|
fn_tree: NodeMap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut visitor = RegionResolutionVisitor {
|
let mut visitor = RegionResolutionVisitor {
|
||||||
sess: sess,
|
tcx: tcx,
|
||||||
region_maps: &mut maps,
|
region_maps: &mut maps,
|
||||||
map: hir_map,
|
map: hir_map,
|
||||||
cx: Context {
|
cx: Context {
|
||||||
|
@ -1034,7 +1034,7 @@ pub enum Rvalue<'tcx> {
|
|||||||
Repeat(Operand<'tcx>, ConstUsize),
|
Repeat(Operand<'tcx>, ConstUsize),
|
||||||
|
|
||||||
/// &x or &mut x
|
/// &x or &mut x
|
||||||
Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>),
|
Ref(Region<'tcx>, BorrowKind, Lvalue<'tcx>),
|
||||||
|
|
||||||
/// length of a [X] or [X;n] value
|
/// length of a [X] or [X;n] value
|
||||||
Len(Lvalue<'tcx>),
|
Len(Lvalue<'tcx>),
|
||||||
|
@ -747,7 +747,7 @@ pub enum LvalueContext<'tcx> {
|
|||||||
Inspect,
|
Inspect,
|
||||||
|
|
||||||
// Being borrowed
|
// Being borrowed
|
||||||
Borrow { region: &'tcx Region, kind: BorrowKind },
|
Borrow { region: Region<'tcx>, kind: BorrowKind },
|
||||||
|
|
||||||
// Used as base for another lvalue, e.g. `x` in `x.y`.
|
// Used as base for another lvalue, e.g. `x` in `x.y`.
|
||||||
//
|
//
|
||||||
|
@ -84,7 +84,7 @@ pub struct FulfillmentContext<'tcx> {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RegionObligation<'tcx> {
|
pub struct RegionObligation<'tcx> {
|
||||||
pub sub_region: &'tcx ty::Region,
|
pub sub_region: ty::Region<'tcx>,
|
||||||
pub sup_type: Ty<'tcx>,
|
pub sup_type: Ty<'tcx>,
|
||||||
pub cause: ObligationCause<'tcx>,
|
pub cause: ObligationCause<'tcx>,
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
|
|||||||
|
|
||||||
pub fn register_region_obligation(&mut self,
|
pub fn register_region_obligation(&mut self,
|
||||||
t_a: Ty<'tcx>,
|
t_a: Ty<'tcx>,
|
||||||
r_b: &'tcx ty::Region,
|
r_b: ty::Region<'tcx>,
|
||||||
cause: ObligationCause<'tcx>)
|
cause: ObligationCause<'tcx>)
|
||||||
{
|
{
|
||||||
register_region_obligation(t_a, r_b, cause, &mut self.region_obligations);
|
register_region_obligation(t_a, r_b, cause, &mut self.region_obligations);
|
||||||
@ -566,7 +566,7 @@ fn coinductive_obligation<'a,'gcx,'tcx>(selcx: &SelectionContext<'a,'gcx,'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
|
fn register_region_obligation<'tcx>(t_a: Ty<'tcx>,
|
||||||
r_b: &'tcx ty::Region,
|
r_b: ty::Region<'tcx>,
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
|
region_obligations: &mut NodeMap<Vec<RegionObligation<'tcx>>>)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ pub enum ObligationCauseCode<'tcx> {
|
|||||||
ReferenceOutlivesReferent(Ty<'tcx>),
|
ReferenceOutlivesReferent(Ty<'tcx>),
|
||||||
|
|
||||||
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
|
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
|
||||||
ObjectTypeBound(Ty<'tcx>, &'tcx ty::Region),
|
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
|
||||||
|
|
||||||
/// Obligation incurred due to an object cast.
|
/// Obligation incurred due to an object cast.
|
||||||
ObjectCastObligation(/* Object type */ Ty<'tcx>),
|
ObjectCastObligation(/* Object type */ Ty<'tcx>),
|
||||||
|
@ -52,8 +52,8 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> {
|
|||||||
self.relate(a, b)
|
self.relate(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region> {
|
-> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?})",
|
debug!("{}.regions({:?}, {:?})",
|
||||||
self.tag(),
|
self.tag(),
|
||||||
a,
|
a,
|
||||||
|
@ -133,7 +133,7 @@ impl<'tcx> Adjustment<'tcx> {
|
|||||||
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub enum AutoBorrow<'tcx> {
|
pub enum AutoBorrow<'tcx> {
|
||||||
/// Convert from T to &T.
|
/// Convert from T to &T.
|
||||||
Ref(&'tcx ty::Region, hir::Mutability),
|
Ref(ty::Region<'tcx>, hir::Mutability),
|
||||||
|
|
||||||
/// Convert from T to *T.
|
/// Convert from T to *T.
|
||||||
RawPtr(hir::Mutability),
|
RawPtr(hir::Mutability),
|
||||||
|
@ -21,7 +21,7 @@ use hir::map as hir_map;
|
|||||||
use hir::map::DisambiguatedDefPathData;
|
use hir::map::DisambiguatedDefPathData;
|
||||||
use middle::free_region::FreeRegionMap;
|
use middle::free_region::FreeRegionMap;
|
||||||
use middle::lang_items;
|
use middle::lang_items;
|
||||||
use middle::region::RegionMaps;
|
use middle::region::{CodeExtent, CodeExtentData, RegionMaps};
|
||||||
use middle::resolve_lifetime;
|
use middle::resolve_lifetime;
|
||||||
use middle::stability;
|
use middle::stability;
|
||||||
use mir::Mir;
|
use mir::Mir;
|
||||||
@ -33,6 +33,7 @@ use ty::{TyS, TypeVariants, Slice};
|
|||||||
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
|
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
|
||||||
use hir::FreevarMap;
|
use hir::FreevarMap;
|
||||||
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||||
|
use ty::RegionKind;
|
||||||
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
|
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
|
||||||
use ty::TypeVariants::*;
|
use ty::TypeVariants::*;
|
||||||
use ty::layout::{Layout, TargetDataLayout};
|
use ty::layout::{Layout, TargetDataLayout};
|
||||||
@ -94,7 +95,7 @@ pub struct CtxtInterners<'tcx> {
|
|||||||
type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
|
type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>,
|
||||||
type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
|
type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>,
|
||||||
substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
|
substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>,
|
||||||
region: RefCell<FxHashSet<Interned<'tcx, Region>>>,
|
region: RefCell<FxHashSet<Interned<'tcx, RegionKind<'tcx>>>>,
|
||||||
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
|
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,9 +193,9 @@ pub struct CommonTypes<'tcx> {
|
|||||||
pub never: Ty<'tcx>,
|
pub never: Ty<'tcx>,
|
||||||
pub err: Ty<'tcx>,
|
pub err: Ty<'tcx>,
|
||||||
|
|
||||||
pub re_empty: &'tcx Region,
|
pub re_empty: Region<'tcx>,
|
||||||
pub re_static: &'tcx Region,
|
pub re_static: Region<'tcx>,
|
||||||
pub re_erased: &'tcx Region,
|
pub re_erased: Region<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
#[derive(RustcEncodable, RustcDecodable)]
|
||||||
@ -257,7 +258,7 @@ pub struct TypeckTables<'tcx> {
|
|||||||
/// Stores the free-region relationships that were deduced from
|
/// Stores the free-region relationships that were deduced from
|
||||||
/// its where clauses and parameter types. These are then
|
/// its where clauses and parameter types. These are then
|
||||||
/// read-again by borrowck.
|
/// read-again by borrowck.
|
||||||
pub free_region_map: FreeRegionMap,
|
pub free_region_map: FreeRegionMap<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeckTables<'tcx> {
|
impl<'tcx> TypeckTables<'tcx> {
|
||||||
@ -393,9 +394,9 @@ impl<'tcx> CommonTypes<'tcx> {
|
|||||||
f32: mk(TyFloat(ast::FloatTy::F32)),
|
f32: mk(TyFloat(ast::FloatTy::F32)),
|
||||||
f64: mk(TyFloat(ast::FloatTy::F64)),
|
f64: mk(TyFloat(ast::FloatTy::F64)),
|
||||||
|
|
||||||
re_empty: mk_region(Region::ReEmpty),
|
re_empty: mk_region(RegionKind::ReEmpty),
|
||||||
re_static: mk_region(Region::ReStatic),
|
re_static: mk_region(RegionKind::ReStatic),
|
||||||
re_erased: mk_region(Region::ReErased),
|
re_erased: mk_region(RegionKind::ReErased),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -549,6 +550,8 @@ pub struct GlobalCtxt<'tcx> {
|
|||||||
|
|
||||||
layout_interner: RefCell<FxHashSet<&'tcx Layout>>,
|
layout_interner: RefCell<FxHashSet<&'tcx Layout>>,
|
||||||
|
|
||||||
|
code_extent_interner: RefCell<FxHashSet<CodeExtent<'tcx>>>,
|
||||||
|
|
||||||
/// A vector of every trait accessible in the whole crate
|
/// A vector of every trait accessible in the whole crate
|
||||||
/// (i.e. including those from subcrates). This is used only for
|
/// (i.e. including those from subcrates). This is used only for
|
||||||
/// error reporting, and so is lazily initialised and generally
|
/// error reporting, and so is lazily initialised and generally
|
||||||
@ -649,6 +652,38 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
interned
|
interned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
|
||||||
|
self.intern_code_extent(CodeExtentData::Misc(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this is revealing side-effects of query, bad
|
||||||
|
pub fn opt_destruction_extent(self, n: ast::NodeId) -> Option<CodeExtent<'gcx>> {
|
||||||
|
let s = CodeExtentData::DestructionScope(n);
|
||||||
|
self.code_extent_interner.borrow().get(&s).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the code extent for an item - the destruction scope.
|
||||||
|
pub fn item_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
|
||||||
|
self.intern_code_extent(CodeExtentData::DestructionScope(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_site_extent(self, fn_id: ast::NodeId, body_id: ast::NodeId) -> CodeExtent<'gcx> {
|
||||||
|
assert!(fn_id != body_id);
|
||||||
|
self.intern_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern_code_extent(self, data: CodeExtentData) -> CodeExtent<'gcx> {
|
||||||
|
if let Some(st) = self.code_extent_interner.borrow().get(&data) {
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
let interned = self.global_interners.arena.alloc(data);
|
||||||
|
if let Some(prev) = self.code_extent_interner.borrow_mut().replace(interned) {
|
||||||
|
bug!("Tried to overwrite interned code-extent: {:?}", prev)
|
||||||
|
}
|
||||||
|
interned
|
||||||
|
}
|
||||||
|
|
||||||
pub fn intern_layout(self, layout: Layout) -> &'gcx Layout {
|
pub fn intern_layout(self, layout: Layout) -> &'gcx Layout {
|
||||||
if let Some(layout) = self.layout_interner.borrow().get(&layout) {
|
if let Some(layout) = self.layout_interner.borrow().get(&layout) {
|
||||||
return layout;
|
return layout;
|
||||||
@ -677,7 +712,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
local as usize == global as usize
|
local as usize == global as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn region_maps(self) -> Rc<RegionMaps> {
|
pub fn region_maps(self) -> Rc<RegionMaps<'tcx>> {
|
||||||
self.region_resolve_crate(LOCAL_CRATE)
|
self.region_resolve_crate(LOCAL_CRATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,6 +776,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
data_layout: data_layout,
|
data_layout: data_layout,
|
||||||
layout_cache: RefCell::new(FxHashMap()),
|
layout_cache: RefCell::new(FxHashMap()),
|
||||||
layout_interner: RefCell::new(FxHashSet()),
|
layout_interner: RefCell::new(FxHashSet()),
|
||||||
|
code_extent_interner: RefCell::new(FxHashSet()),
|
||||||
layout_depth: Cell::new(0),
|
layout_depth: Cell::new(0),
|
||||||
derive_macros: RefCell::new(NodeMap()),
|
derive_macros: RefCell::new(NodeMap()),
|
||||||
stability_interner: RefCell::new(FxHashSet()),
|
stability_interner: RefCell::new(FxHashSet()),
|
||||||
@ -820,9 +856,18 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Lift<'tcx> for &'a Region {
|
impl<'a, 'tcx> Lift<'tcx> for ty::FreeRegion<'a> {
|
||||||
type Lifted = &'tcx Region;
|
type Lifted = ty::FreeRegion<'tcx>;
|
||||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Region> {
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||||
|
let scope = self.scope.map(|code_extent| tcx.intern_code_extent(*code_extent));
|
||||||
|
let bound_region = self.bound_region;
|
||||||
|
Some(ty::FreeRegion { scope, bound_region })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
|
||||||
|
type Lifted = Region<'tcx>;
|
||||||
|
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Region<'tcx>> {
|
||||||
if tcx.interners.arena.in_arena(*self as *const _) {
|
if tcx.interners.arena.in_arena(*self as *const _) {
|
||||||
return Some(unsafe { mem::transmute(*self) });
|
return Some(unsafe { mem::transmute(*self) });
|
||||||
}
|
}
|
||||||
@ -1083,9 +1128,9 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, Substs<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
|
impl<'tcx> Borrow<RegionKind<'tcx>> for Interned<'tcx, RegionKind<'tcx>> {
|
||||||
fn borrow<'a>(&'a self) -> &'a Region {
|
fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> {
|
||||||
self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,7 +1221,7 @@ direct_interners!('tcx,
|
|||||||
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
|
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}) -> Region
|
}) -> RegionKind<'tcx>
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! slice_interners {
|
macro_rules! slice_interners {
|
||||||
@ -1268,15 +1313,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.mk_ty(TyRawPtr(tm))
|
self.mk_ty(TyRawPtr(tm))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_ref(self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
|
pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
|
||||||
self.mk_ty(TyRef(r, tm))
|
self.mk_ty(TyRef(r, tm))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_mut_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
|
pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
|
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_imm_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
|
pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
|
self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,7 +1383,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn mk_dynamic(
|
pub fn mk_dynamic(
|
||||||
self,
|
self,
|
||||||
obj: ty::Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>,
|
obj: ty::Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>,
|
||||||
reg: &'tcx ty::Region
|
reg: ty::Region<'tcx>
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
self.mk_ty(TyDynamic(obj, reg))
|
self.mk_ty(TyDynamic(obj, reg))
|
||||||
}
|
}
|
||||||
|
@ -36,11 +36,11 @@ pub enum TypeError<'tcx> {
|
|||||||
TupleSize(ExpectedFound<usize>),
|
TupleSize(ExpectedFound<usize>),
|
||||||
FixedArraySize(ExpectedFound<usize>),
|
FixedArraySize(ExpectedFound<usize>),
|
||||||
ArgCount,
|
ArgCount,
|
||||||
RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
|
RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
|
||||||
RegionsNotSame(&'tcx Region, &'tcx Region),
|
RegionsNotSame(Region<'tcx>, Region<'tcx>),
|
||||||
RegionsNoOverlap(&'tcx Region, &'tcx Region),
|
RegionsNoOverlap(Region<'tcx>, Region<'tcx>),
|
||||||
RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
|
RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
|
||||||
RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
|
RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
|
||||||
Sorts(ExpectedFound<Ty<'tcx>>),
|
Sorts(ExpectedFound<Ty<'tcx>>),
|
||||||
IntMismatch(ExpectedFound<ty::IntVarValue>),
|
IntMismatch(ExpectedFound<ty::IntVarValue>),
|
||||||
FloatMismatch(ExpectedFound<ast::FloatTy>),
|
FloatMismatch(ExpectedFound<ast::FloatTy>),
|
||||||
|
@ -186,7 +186,7 @@ impl FlagComputation {
|
|||||||
self.add_bound_computation(&computation);
|
self.add_bound_computation(&computation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_region(&mut self, r: &ty::Region) {
|
fn add_region(&mut self, r: ty::Region) {
|
||||||
self.add_flags(r.type_flags());
|
self.add_flags(r.type_flags());
|
||||||
if let ty::ReLateBound(debruijn, _) = *r {
|
if let ty::ReLateBound(debruijn, _) = *r {
|
||||||
self.add_depth(debruijn.depth);
|
self.add_depth(debruijn.depth);
|
||||||
|
@ -159,7 +159,7 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized {
|
|||||||
sig.super_fold_with(self)
|
sig.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
r.super_fold_with(self)
|
r.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ pub trait TypeVisitor<'tcx> : Sized {
|
|||||||
trait_ref.super_visit_with(self)
|
trait_ref.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
r.super_visit_with(self)
|
r.super_visit_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// whether any late-bound regions were skipped
|
/// whether any late-bound regions were skipped
|
||||||
pub fn collect_regions<T>(self,
|
pub fn collect_regions<T>(self,
|
||||||
value: &T,
|
value: &T,
|
||||||
region_set: &mut FxHashSet<&'tcx ty::Region>)
|
region_set: &mut FxHashSet<ty::Region<'tcx>>)
|
||||||
-> bool
|
-> bool
|
||||||
where T : TypeFoldable<'tcx>
|
where T : TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
@ -236,7 +236,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
skipped_regions: &mut bool,
|
skipped_regions: &mut bool,
|
||||||
mut f: F)
|
mut f: F)
|
||||||
-> T
|
-> T
|
||||||
where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region,
|
where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx>,
|
||||||
T : TypeFoldable<'tcx>,
|
T : TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
|
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
|
||||||
@ -256,14 +256,14 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
skipped_regions: &'a mut bool,
|
skipped_regions: &'a mut bool,
|
||||||
current_depth: u32,
|
current_depth: u32,
|
||||||
fld_r: &'a mut (FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + 'a),
|
fld_r: &'a mut (FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> + 'a),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
|
||||||
pub fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
skipped_regions: &'a mut bool,
|
skipped_regions: &'a mut bool,
|
||||||
fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx>
|
fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx>
|
||||||
where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region
|
where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx>
|
||||||
{
|
{
|
||||||
RegionFolder {
|
RegionFolder {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
|
|||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => {
|
ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => {
|
||||||
debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})",
|
debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})",
|
||||||
@ -309,16 +309,16 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
|
|||||||
struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
current_depth: u32,
|
current_depth: u32,
|
||||||
fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a),
|
fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
|
||||||
map: FxHashMap<ty::BoundRegion, &'tcx ty::Region>
|
map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
pub fn replace_late_bound_regions<T,F>(self,
|
pub fn replace_late_bound_regions<T,F>(self,
|
||||||
value: &Binder<T>,
|
value: &Binder<T>,
|
||||||
mut f: F)
|
mut f: F)
|
||||||
-> (T, FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
|
-> (T, FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||||
where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region,
|
where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
|
||||||
T : TypeFoldable<'tcx>,
|
T : TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let mut replacer = RegionReplacer::new(self, &mut f);
|
let mut replacer = RegionReplacer::new(self, &mut f);
|
||||||
@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
|
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
|
||||||
/// `scope_id`.
|
/// `scope_id`.
|
||||||
pub fn liberate_late_bound_regions<T>(self,
|
pub fn liberate_late_bound_regions<T>(self,
|
||||||
all_outlive_scope: Option<region::CodeExtent>,
|
all_outlive_scope: Option<region::CodeExtent<'tcx>>,
|
||||||
value: &Binder<T>)
|
value: &Binder<T>)
|
||||||
-> T
|
-> T
|
||||||
where T : TypeFoldable<'tcx>
|
where T : TypeFoldable<'tcx>
|
||||||
@ -435,7 +435,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> {
|
||||||
fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F)
|
fn new<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F)
|
||||||
-> RegionReplacer<'a, 'gcx, 'tcx>
|
-> RegionReplacer<'a, 'gcx, 'tcx>
|
||||||
where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region
|
where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>
|
||||||
{
|
{
|
||||||
RegionReplacer {
|
RegionReplacer {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
@ -464,7 +464,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
|
|||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r:&'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
|
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
|
||||||
let fld_r = &mut self.fld_r;
|
let fld_r = &mut self.fld_r;
|
||||||
@ -527,7 +527,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
u.super_fold_with(self)
|
u.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
// because late-bound regions affect subtyping, we can't
|
// because late-bound regions affect subtyping, we can't
|
||||||
// erase the bound/free distinction, but we can replace
|
// erase the bound/free distinction, but we can replace
|
||||||
// all free regions with 'erased.
|
// all free regions with 'erased.
|
||||||
@ -554,7 +554,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// regions. See comment on `shift_regions_through_binders` method in
|
// regions. See comment on `shift_regions_through_binders` method in
|
||||||
// `subst.rs` for more details.
|
// `subst.rs` for more details.
|
||||||
|
|
||||||
pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
|
pub fn shift_region<'tcx>(region: ty::RegionKind<'tcx>, amount: u32) -> ty::RegionKind<'tcx> {
|
||||||
match region {
|
match region {
|
||||||
ty::ReLateBound(debruijn, br) => {
|
ty::ReLateBound(debruijn, br) => {
|
||||||
ty::ReLateBound(debruijn.shifted(amount), br)
|
ty::ReLateBound(debruijn.shifted(amount), br)
|
||||||
@ -567,9 +567,9 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
|
|||||||
|
|
||||||
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
|
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
amount: u32)
|
amount: u32)
|
||||||
-> &'tcx ty::Region
|
-> ty::Region<'tcx>
|
||||||
{
|
{
|
||||||
match region {
|
match region {
|
||||||
&ty::ReLateBound(debruijn, br) if amount > 0 => {
|
&ty::ReLateBound(debruijn, br) if amount > 0 => {
|
||||||
@ -582,7 +582,8 @@ pub fn shift_region_ref<'a, 'gcx, 'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
amount: u32, value: &T) -> T
|
amount: u32,
|
||||||
|
value: &T) -> T
|
||||||
where T: TypeFoldable<'tcx>
|
where T: TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
debug!("shift_regions(value={:?}, amount={})",
|
debug!("shift_regions(value={:?}, amount={})",
|
||||||
@ -631,7 +632,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
|
|||||||
t.region_depth > self.depth
|
t.region_depth > self.depth
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
r.escapes_depth(self.depth)
|
r.escapes_depth(self.depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -647,7 +648,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
|
|||||||
flags.intersects(self.flags)
|
flags.intersects(self.flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
let flags = r.type_flags();
|
let flags = r.type_flags();
|
||||||
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
|
debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags);
|
||||||
flags.intersects(self.flags)
|
flags.intersects(self.flags)
|
||||||
@ -693,7 +694,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
|
|||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
|
ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => {
|
||||||
self.regions.insert(br);
|
self.regions.insert(br);
|
||||||
|
@ -578,7 +578,7 @@ define_maps! { <'tcx>
|
|||||||
|
|
||||||
[] reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
|
[] reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
|
||||||
|
|
||||||
[] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc<RegionMaps>,
|
[] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc<RegionMaps<'tcx>>,
|
||||||
|
|
||||||
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||||
|
|
||||||
|
@ -67,11 +67,12 @@ pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
|
|||||||
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
|
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
|
||||||
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
|
pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
|
||||||
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
|
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
|
||||||
|
pub use self::sty::RegionKind;
|
||||||
pub use self::sty::Issue32330;
|
pub use self::sty::Issue32330;
|
||||||
pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
|
pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
|
||||||
pub use self::sty::BoundRegion::*;
|
pub use self::sty::BoundRegion::*;
|
||||||
pub use self::sty::InferTy::*;
|
pub use self::sty::InferTy::*;
|
||||||
pub use self::sty::Region::*;
|
pub use self::sty::RegionKind::*;
|
||||||
pub use self::sty::TypeVariants::*;
|
pub use self::sty::TypeVariants::*;
|
||||||
|
|
||||||
pub use self::context::{TyCtxt, GlobalArenas, tls};
|
pub use self::context::{TyCtxt, GlobalArenas, tls};
|
||||||
@ -601,7 +602,7 @@ pub struct UpvarBorrow<'tcx> {
|
|||||||
pub kind: BorrowKind,
|
pub kind: BorrowKind,
|
||||||
|
|
||||||
/// Region of the resulting reference.
|
/// Region of the resulting reference.
|
||||||
pub region: &'tcx ty::Region,
|
pub region: ty::Region<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
|
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
|
||||||
@ -934,9 +935,9 @@ pub type PolyEquatePredicate<'tcx> = ty::Binder<EquatePredicate<'tcx>>;
|
|||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
|
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
|
||||||
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
|
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
|
||||||
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region,
|
pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<ty::Region<'tcx>,
|
||||||
&'tcx ty::Region>;
|
ty::Region<'tcx>>;
|
||||||
pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>;
|
pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct SubtypePredicate<'tcx> {
|
pub struct SubtypePredicate<'tcx> {
|
||||||
@ -1167,7 +1168,7 @@ pub struct ParameterEnvironment<'tcx> {
|
|||||||
/// region of the callee. If it is `None`, then the parameter
|
/// region of the callee. If it is `None`, then the parameter
|
||||||
/// environment is for an item or something where the "callee" is
|
/// environment is for an item or something where the "callee" is
|
||||||
/// not clear.
|
/// not clear.
|
||||||
pub implicit_region_bound: Option<&'tcx ty::Region>,
|
pub implicit_region_bound: Option<ty::Region<'tcx>>,
|
||||||
|
|
||||||
/// Obligations that the caller must satisfy. This is basically
|
/// Obligations that the caller must satisfy. This is basically
|
||||||
/// the set of bounds on the in-scope type parameters, translated
|
/// the set of bounds on the in-scope type parameters, translated
|
||||||
@ -1181,7 +1182,7 @@ pub struct ParameterEnvironment<'tcx> {
|
|||||||
/// FIXME(#3696). It would be nice to refactor so that free
|
/// FIXME(#3696). It would be nice to refactor so that free
|
||||||
/// regions don't have this implicit scope and instead introduce
|
/// regions don't have this implicit scope and instead introduce
|
||||||
/// relationships in the environment.
|
/// relationships in the environment.
|
||||||
pub free_id_outlive: Option<CodeExtent>,
|
pub free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// A cache for `moves_by_default`.
|
/// A cache for `moves_by_default`.
|
||||||
pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
pub is_copy_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
|
||||||
@ -1222,13 +1223,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
let impl_def_id = tcx.hir.local_def_id(impl_id);
|
let impl_def_id = tcx.hir.local_def_id(impl_id);
|
||||||
tcx.construct_parameter_environment(impl_item.span,
|
tcx.construct_parameter_environment(impl_item.span,
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
Some(tcx.region_maps().item_extent(id)))
|
Some(tcx.item_extent(id)))
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::Method(_, ref body) => {
|
hir::ImplItemKind::Method(_, ref body) => {
|
||||||
tcx.construct_parameter_environment(
|
tcx.construct_parameter_environment(
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
tcx.hir.local_def_id(id),
|
tcx.hir.local_def_id(id),
|
||||||
Some(tcx.region_maps().call_site_extent(id, body.node_id)))
|
Some(tcx.call_site_extent(id, body.node_id)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1241,7 +1242,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
let trait_def_id = tcx.hir.local_def_id(trait_id);
|
let trait_def_id = tcx.hir.local_def_id(trait_id);
|
||||||
tcx.construct_parameter_environment(trait_item.span,
|
tcx.construct_parameter_environment(trait_item.span,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
Some(tcx.region_maps().item_extent(id)))
|
Some(tcx.item_extent(id)))
|
||||||
}
|
}
|
||||||
hir::TraitItemKind::Method(_, ref body) => {
|
hir::TraitItemKind::Method(_, ref body) => {
|
||||||
// Use call-site for extent (unless this is a
|
// Use call-site for extent (unless this is a
|
||||||
@ -1249,10 +1250,10 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
// to the method id).
|
// to the method id).
|
||||||
let extent = if let hir::TraitMethod::Provided(body_id) = *body {
|
let extent = if let hir::TraitMethod::Provided(body_id) = *body {
|
||||||
// default impl: use call_site extent as free_id_outlive bound.
|
// default impl: use call_site extent as free_id_outlive bound.
|
||||||
tcx.region_maps().call_site_extent(id, body_id.node_id)
|
tcx.call_site_extent(id, body_id.node_id)
|
||||||
} else {
|
} else {
|
||||||
// no default impl: use item extent as free_id_outlive bound.
|
// no default impl: use item extent as free_id_outlive bound.
|
||||||
tcx.region_maps().item_extent(id)
|
tcx.item_extent(id)
|
||||||
};
|
};
|
||||||
tcx.construct_parameter_environment(
|
tcx.construct_parameter_environment(
|
||||||
trait_item.span,
|
trait_item.span,
|
||||||
@ -1270,7 +1271,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
tcx.construct_parameter_environment(
|
tcx.construct_parameter_environment(
|
||||||
item.span,
|
item.span,
|
||||||
fn_def_id,
|
fn_def_id,
|
||||||
Some(tcx.region_maps().call_site_extent(id, body_id.node_id)))
|
Some(tcx.call_site_extent(id, body_id.node_id)))
|
||||||
}
|
}
|
||||||
hir::ItemEnum(..) |
|
hir::ItemEnum(..) |
|
||||||
hir::ItemStruct(..) |
|
hir::ItemStruct(..) |
|
||||||
@ -1282,13 +1283,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
let def_id = tcx.hir.local_def_id(id);
|
let def_id = tcx.hir.local_def_id(id);
|
||||||
tcx.construct_parameter_environment(item.span,
|
tcx.construct_parameter_environment(item.span,
|
||||||
def_id,
|
def_id,
|
||||||
Some(tcx.region_maps().item_extent(id)))
|
Some(tcx.item_extent(id)))
|
||||||
}
|
}
|
||||||
hir::ItemTrait(..) => {
|
hir::ItemTrait(..) => {
|
||||||
let def_id = tcx.hir.local_def_id(id);
|
let def_id = tcx.hir.local_def_id(id);
|
||||||
tcx.construct_parameter_environment(item.span,
|
tcx.construct_parameter_environment(item.span,
|
||||||
def_id,
|
def_id,
|
||||||
Some(tcx.region_maps().item_extent(id)))
|
Some(tcx.item_extent(id)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(item.span,
|
span_bug!(item.span,
|
||||||
@ -1306,7 +1307,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
|
|||||||
tcx.construct_parameter_environment(
|
tcx.construct_parameter_environment(
|
||||||
expr.span,
|
expr.span,
|
||||||
base_def_id,
|
base_def_id,
|
||||||
Some(tcx.region_maps().call_site_extent(id, body.node_id)))
|
Some(tcx.call_site_extent(id, body.node_id)))
|
||||||
} else {
|
} else {
|
||||||
tcx.empty_parameter_environment()
|
tcx.empty_parameter_environment()
|
||||||
}
|
}
|
||||||
@ -2454,8 +2455,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// In general, this means converting from bound parameters to
|
/// In general, this means converting from bound parameters to
|
||||||
/// free parameters. Since we currently represent bound/free type
|
/// free parameters. Since we currently represent bound/free type
|
||||||
/// parameters in the same way, this only has an effect on regions.
|
/// parameters in the same way, this only has an effect on regions.
|
||||||
pub fn construct_free_substs(self, def_id: DefId,
|
pub fn construct_free_substs(self,
|
||||||
free_id_outlive: Option<CodeExtent>)
|
def_id: DefId,
|
||||||
|
free_id_outlive: Option<CodeExtent<'gcx>>)
|
||||||
-> &'gcx Substs<'gcx> {
|
-> &'gcx Substs<'gcx> {
|
||||||
|
|
||||||
let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
|
let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
|
||||||
@ -2479,7 +2481,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn construct_parameter_environment(self,
|
pub fn construct_parameter_environment(self,
|
||||||
span: Span,
|
span: Span,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
free_id_outlive: Option<CodeExtent>)
|
free_id_outlive: Option<CodeExtent<'gcx>>)
|
||||||
-> ParameterEnvironment<'gcx>
|
-> ParameterEnvironment<'gcx>
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -2521,14 +2523,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
is_freeze_cache: RefCell::new(FxHashMap()),
|
is_freeze_cache: RefCell::new(FxHashMap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let body_id = free_id_outlive.map(|f| f.node_id(&self.region_maps()))
|
let body_id = free_id_outlive.map(|f| f.node_id())
|
||||||
.unwrap_or(DUMMY_NODE_ID);
|
.unwrap_or(DUMMY_NODE_ID);
|
||||||
let cause = traits::ObligationCause::misc(span, body_id);
|
let cause = traits::ObligationCause::misc(span, body_id);
|
||||||
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
|
traits::normalize_param_env_or_error(tcx, unnormalized_env, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_scope_region(self, id: NodeId) -> &'tcx Region {
|
pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> {
|
||||||
self.mk_region(ty::ReScope(self.region_maps().node_extent(id)))
|
self.mk_region(ty::ReScope(self.node_extent(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_all_item_likes_in_krate<V,F>(self,
|
pub fn visit_all_item_likes_in_krate<V,F>(self,
|
||||||
|
@ -16,7 +16,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Component<'tcx> {
|
pub enum Component<'tcx> {
|
||||||
Region(&'tcx ty::Region),
|
Region(ty::Region<'tcx>),
|
||||||
Param(ty::ParamTy),
|
Param(ty::ParamTy),
|
||||||
UnresolvedInferenceVariable(ty::InferTy),
|
UnresolvedInferenceVariable(ty::InferTy),
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<&'tcx ty::Region>) {
|
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region<'tcx>>) {
|
||||||
for r in regions {
|
for r in regions {
|
||||||
if !r.is_bound() {
|
if !r.is_bound() {
|
||||||
out.push(Component::Region(r));
|
out.push(Component::Region(r));
|
||||||
|
@ -67,8 +67,8 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
|
|||||||
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>)
|
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>)
|
||||||
-> RelateResult<'tcx, Ty<'tcx>>;
|
-> RelateResult<'tcx, Ty<'tcx>>;
|
||||||
|
|
||||||
fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region)
|
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region>;
|
-> RelateResult<'tcx, ty::Region<'tcx>>;
|
||||||
|
|
||||||
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
|
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
|
||||||
-> RelateResult<'tcx, ty::Binder<T>>
|
-> RelateResult<'tcx, ty::Binder<T>>
|
||||||
@ -529,11 +529,11 @@ impl<'tcx> Relate<'tcx> for &'tcx Substs<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for &'tcx ty::Region {
|
impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
|
||||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||||
a: &&'tcx ty::Region,
|
a: &ty::Region<'tcx>,
|
||||||
b: &&'tcx ty::Region)
|
b: &ty::Region<'tcx>)
|
||||||
-> RelateResult<'tcx, &'tcx ty::Region>
|
-> RelateResult<'tcx, ty::Region<'tcx>>
|
||||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||||
{
|
{
|
||||||
relation.regions(*a, *b)
|
relation.regions(*a, *b)
|
||||||
|
@ -624,7 +624,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ pub struct TypeAndMut<'tcx> {
|
|||||||
/// If `fr.scope` is None, then this is in some context (e.g., an
|
/// If `fr.scope` is None, then this is in some context (e.g., an
|
||||||
/// impl) where lifetimes are more abstract and the notion of the
|
/// impl) where lifetimes are more abstract and the notion of the
|
||||||
/// caller/callee stack frames are not applicable.
|
/// caller/callee stack frames are not applicable.
|
||||||
pub struct FreeRegion {
|
pub struct FreeRegion<'tcx> {
|
||||||
pub scope: Option<region::CodeExtent>,
|
pub scope: Option<region::CodeExtent<'tcx>>,
|
||||||
pub bound_region: BoundRegion,
|
pub bound_region: BoundRegion,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ pub enum TypeVariants<'tcx> {
|
|||||||
|
|
||||||
/// A reference; a pointer with an associated lifetime. Written as
|
/// A reference; a pointer with an associated lifetime. Written as
|
||||||
/// `&'a mut T` or `&'a T`.
|
/// `&'a mut T` or `&'a T`.
|
||||||
TyRef(&'tcx Region, TypeAndMut<'tcx>),
|
TyRef(Region<'tcx>, TypeAndMut<'tcx>),
|
||||||
|
|
||||||
/// The anonymous type of a function declaration/definition. Each
|
/// The anonymous type of a function declaration/definition. Each
|
||||||
/// function has a unique type.
|
/// function has a unique type.
|
||||||
@ -140,7 +140,7 @@ pub enum TypeVariants<'tcx> {
|
|||||||
TyFnPtr(PolyFnSig<'tcx>),
|
TyFnPtr(PolyFnSig<'tcx>),
|
||||||
|
|
||||||
/// A trait, defined with `trait`.
|
/// A trait, defined with `trait`.
|
||||||
TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, &'tcx ty::Region),
|
TyDynamic(Binder<&'tcx Slice<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
|
||||||
|
|
||||||
/// The anonymous type of a closure. Used to represent the type of
|
/// The anonymous type of a closure. Used to represent the type of
|
||||||
/// `|a| a`.
|
/// `|a| a`.
|
||||||
@ -679,6 +679,8 @@ pub struct DebruijnIndex {
|
|||||||
pub depth: u32,
|
pub depth: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Region<'tcx> = &'tcx RegionKind<'tcx>;
|
||||||
|
|
||||||
/// Representation of regions.
|
/// Representation of regions.
|
||||||
///
|
///
|
||||||
/// Unlike types, most region variants are "fictitious", not concrete,
|
/// Unlike types, most region variants are "fictitious", not concrete,
|
||||||
@ -736,7 +738,7 @@ pub struct DebruijnIndex {
|
|||||||
/// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
|
/// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
|
||||||
/// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
|
/// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
|
||||||
pub enum Region {
|
pub enum RegionKind<'tcx> {
|
||||||
// Region bound in a type or fn declaration which will be
|
// Region bound in a type or fn declaration which will be
|
||||||
// substituted 'early' -- that is, at the same time when type
|
// substituted 'early' -- that is, at the same time when type
|
||||||
// parameters are substituted.
|
// parameters are substituted.
|
||||||
@ -749,12 +751,12 @@ pub enum Region {
|
|||||||
/// When checking a function body, the types of all arguments and so forth
|
/// When checking a function body, the types of all arguments and so forth
|
||||||
/// that refer to bound region parameters are modified to refer to free
|
/// that refer to bound region parameters are modified to refer to free
|
||||||
/// region parameters.
|
/// region parameters.
|
||||||
ReFree(FreeRegion),
|
ReFree(FreeRegion<'tcx>),
|
||||||
|
|
||||||
/// A concrete region naming some statically determined extent
|
/// A concrete region naming some statically determined extent
|
||||||
/// (e.g. an expression or sequence of statements) within the
|
/// (e.g. an expression or sequence of statements) within the
|
||||||
/// current function.
|
/// current function.
|
||||||
ReScope(region::CodeExtent),
|
ReScope(region::CodeExtent<'tcx>),
|
||||||
|
|
||||||
/// Static data that has an "infinite" lifetime. Top in the region lattice.
|
/// Static data that has an "infinite" lifetime. Top in the region lattice.
|
||||||
ReStatic,
|
ReStatic,
|
||||||
@ -779,7 +781,7 @@ pub enum Region {
|
|||||||
ReErased,
|
ReErased,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Region {}
|
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct EarlyBoundRegion {
|
pub struct EarlyBoundRegion {
|
||||||
@ -898,7 +900,7 @@ impl DebruijnIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Region utilities
|
// Region utilities
|
||||||
impl Region {
|
impl<'tcx> RegionKind<'tcx> {
|
||||||
pub fn is_bound(&self) -> bool {
|
pub fn is_bound(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
ty::ReEarlyBound(..) => true,
|
ty::ReEarlyBound(..) => true,
|
||||||
@ -922,7 +924,7 @@ impl Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the depth of `self` from the (1-based) binding level `depth`
|
/// Returns the depth of `self` from the (1-based) binding level `depth`
|
||||||
pub fn from_depth(&self, depth: u32) -> Region {
|
pub fn from_depth(&self, depth: u32) -> RegionKind<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex {
|
ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex {
|
||||||
depth: debruijn.depth - (depth - 1)
|
depth: debruijn.depth - (depth - 1)
|
||||||
@ -1334,7 +1336,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||||||
/// Returns the regions directly referenced from this type (but
|
/// Returns the regions directly referenced from this type (but
|
||||||
/// not types reachable from this type via `walk_tys`). This
|
/// not types reachable from this type via `walk_tys`). This
|
||||||
/// ignores late-bound regions binders.
|
/// ignores late-bound regions binders.
|
||||||
pub fn regions(&self) -> Vec<&'tcx ty::Region> {
|
pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyRef(region, _) => {
|
TyRef(region, _) => {
|
||||||
vec![region]
|
vec![region]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// Type substitutions.
|
// Type substitutions.
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use ty::{self, Slice, Ty, TyCtxt};
|
use ty::{self, Slice, Region, Ty, TyCtxt};
|
||||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
|
|
||||||
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
|
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
|
||||||
@ -32,7 +32,7 @@ use std::mem;
|
|||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Kind<'tcx> {
|
pub struct Kind<'tcx> {
|
||||||
ptr: NonZero<usize>,
|
ptr: NonZero<usize>,
|
||||||
marker: PhantomData<(Ty<'tcx>, &'tcx ty::Region)>
|
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)>
|
||||||
}
|
}
|
||||||
|
|
||||||
const TAG_MASK: usize = 0b11;
|
const TAG_MASK: usize = 0b11;
|
||||||
@ -54,8 +54,8 @@ impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> From<&'tcx ty::Region> for Kind<'tcx> {
|
impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
|
||||||
fn from(r: &'tcx ty::Region) -> Kind<'tcx> {
|
fn from(r: ty::Region<'tcx>) -> Kind<'tcx> {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(r) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(r) & TAG_MASK, 0);
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ impl<'tcx> Kind<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_region(self) -> Option<&'tcx ty::Region> {
|
pub fn as_region(self) -> Option<ty::Region<'tcx>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.downcast(REGION_TAG)
|
self.downcast(REGION_TAG)
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ impl<'tcx> Decodable for Kind<'tcx> {
|
|||||||
d.read_enum_variant(&["Ty", "Region"], |d, tag| {
|
d.read_enum_variant(&["Ty", "Region"], |d, tag| {
|
||||||
match tag {
|
match tag {
|
||||||
TYPE_TAG => Ty::decode(d).map(Kind::from),
|
TYPE_TAG => Ty::decode(d).map(Kind::from),
|
||||||
REGION_TAG => <&ty::Region>::decode(d).map(Kind::from),
|
REGION_TAG => Region::decode(d).map(Kind::from),
|
||||||
_ => Err(d.error("invalid Kind tag"))
|
_ => Err(d.error("invalid Kind tag"))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
mut mk_region: FR,
|
mut mk_region: FR,
|
||||||
mut mk_type: FT)
|
mut mk_type: FT)
|
||||||
-> &'tcx Substs<'tcx>
|
-> &'tcx Substs<'tcx>
|
||||||
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
|
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||||
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||||
let defs = tcx.generics_of(def_id);
|
let defs = tcx.generics_of(def_id);
|
||||||
let mut substs = Vec::with_capacity(defs.count());
|
let mut substs = Vec::with_capacity(defs.count());
|
||||||
@ -197,7 +197,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
mut mk_region: FR,
|
mut mk_region: FR,
|
||||||
mut mk_type: FT)
|
mut mk_type: FT)
|
||||||
-> &'tcx Substs<'tcx>
|
-> &'tcx Substs<'tcx>
|
||||||
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
|
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||||
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx>
|
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx>
|
||||||
{
|
{
|
||||||
let defs = tcx.generics_of(def_id);
|
let defs = tcx.generics_of(def_id);
|
||||||
@ -212,7 +212,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
defs: &ty::Generics,
|
defs: &ty::Generics,
|
||||||
mk_region: &mut FR,
|
mk_region: &mut FR,
|
||||||
mk_type: &mut FT)
|
mk_type: &mut FT)
|
||||||
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
|
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||||
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||||
|
|
||||||
if let Some(def_id) = defs.parent {
|
if let Some(def_id) = defs.parent {
|
||||||
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
defs: &ty::Generics,
|
defs: &ty::Generics,
|
||||||
mk_region: &mut FR,
|
mk_region: &mut FR,
|
||||||
mk_type: &mut FT)
|
mk_type: &mut FT)
|
||||||
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
|
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||||
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||||
// Handle Self first, before all regions.
|
// Handle Self first, before all regions.
|
||||||
let mut types = defs.types.iter();
|
let mut types = defs.types.iter();
|
||||||
@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=&'tcx ty::Region> + 'a {
|
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
|
||||||
self.iter().filter_map(|k| k.as_region())
|
self.iter().filter_map(|k| k.as_region())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn region_at(&self, i: usize) -> &'tcx ty::Region {
|
pub fn region_at(&self, i: usize) -> ty::Region<'tcx> {
|
||||||
self[i].as_region().unwrap_or_else(|| {
|
self[i].as_region().unwrap_or_else(|| {
|
||||||
bug!("expected region for param #{} in {:?}", i, self);
|
bug!("expected region for param #{} in {:?}", i, self);
|
||||||
})
|
})
|
||||||
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> &'tcx ty::Region {
|
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region<'tcx> {
|
||||||
self.region_at(def.index as usize)
|
self.region_at(def.index as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +396,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
|
|||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
// Note: This routine only handles regions that are bound on
|
// Note: This routine only handles regions that are bound on
|
||||||
// type declarations and other outer declarations, not those
|
// type declarations and other outer declarations, not those
|
||||||
// bound in *fn types*. Region substitution of the bound
|
// bound in *fn types*. Region substitution of the bound
|
||||||
@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
if self.region_binders_passed == 0 || !region.has_escaping_regions() {
|
if self.region_binders_passed == 0 || !region.has_escaping_regions() {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn required_region_bounds(self,
|
pub fn required_region_bounds(self,
|
||||||
erased_self_ty: Ty<'tcx>,
|
erased_self_ty: Ty<'tcx>,
|
||||||
predicates: Vec<ty::Predicate<'tcx>>)
|
predicates: Vec<ty::Predicate<'tcx>>)
|
||||||
-> Vec<&'tcx ty::Region> {
|
-> Vec<ty::Region<'tcx>> {
|
||||||
debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
|
debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
|
||||||
erased_self_ty,
|
erased_self_ty,
|
||||||
predicates);
|
predicates);
|
||||||
@ -457,7 +457,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let result = item_substs.iter().zip(impl_substs.iter())
|
let result = item_substs.iter().zip(impl_substs.iter())
|
||||||
.filter(|&(_, &k)| {
|
.filter(|&(_, &k)| {
|
||||||
if let Some(&ty::Region::ReEarlyBound(ref ebr)) = k.as_region() {
|
if let Some(&ty::RegionKind::ReEarlyBound(ref ebr)) = k.as_region() {
|
||||||
!impl_generics.region_param(ebr).pure_wrt_drop
|
!impl_generics.region_param(ebr).pure_wrt_drop
|
||||||
} else if let Some(&ty::TyS {
|
} else if let Some(&ty::TyS {
|
||||||
sty: ty::TypeVariants::TyParam(ref pt), ..
|
sty: ty::TypeVariants::TyParam(ref pt), ..
|
||||||
@ -673,7 +673,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
|||||||
ty.super_visit_with(self)
|
ty.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
self.hash_discriminant_u8(r);
|
self.hash_discriminant_u8(r);
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReErased |
|
ty::ReErased |
|
||||||
|
@ -116,9 +116,9 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
|||||||
/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
|
/// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ImpliedBound<'tcx> {
|
pub enum ImpliedBound<'tcx> {
|
||||||
RegionSubRegion(&'tcx ty::Region, &'tcx ty::Region),
|
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
|
||||||
RegionSubParam(&'tcx ty::Region, ty::ParamTy),
|
RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
|
||||||
RegionSubProjection(&'tcx ty::Region, ty::ProjectionTy<'tcx>),
|
RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the implied bounds that a callee/impl can assume based on
|
/// Compute the implied bounds that a callee/impl can assume based on
|
||||||
@ -198,7 +198,7 @@ pub fn implied_bounds<'a, 'gcx, 'tcx>(
|
|||||||
/// this down to determine what relationships would have to hold for
|
/// this down to determine what relationships would have to hold for
|
||||||
/// `T: 'a` to hold. We get to assume that the caller has validated
|
/// `T: 'a` to hold. We get to assume that the caller has validated
|
||||||
/// those relationships.
|
/// those relationships.
|
||||||
fn implied_bounds_from_components<'tcx>(sub_region: &'tcx ty::Region,
|
fn implied_bounds_from_components<'tcx>(sub_region: ty::Region<'tcx>,
|
||||||
sup_components: Vec<Component<'tcx>>)
|
sup_components: Vec<Component<'tcx>>)
|
||||||
-> Vec<ImpliedBound<'tcx>>
|
-> Vec<ImpliedBound<'tcx>>
|
||||||
{
|
{
|
||||||
@ -455,7 +455,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn from_object_ty(&mut self, ty: Ty<'tcx>,
|
fn from_object_ty(&mut self, ty: Ty<'tcx>,
|
||||||
data: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>,
|
data: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>,
|
||||||
region: &'tcx ty::Region) {
|
region: ty::Region<'tcx>) {
|
||||||
// Imagine a type like this:
|
// Imagine a type like this:
|
||||||
//
|
//
|
||||||
// trait Foo { }
|
// trait Foo { }
|
||||||
@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||||||
pub fn object_region_bounds<'a, 'gcx, 'tcx>(
|
pub fn object_region_bounds<'a, 'gcx, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
|
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
|
||||||
-> Vec<&'tcx ty::Region>
|
-> Vec<ty::Region<'tcx>>
|
||||||
{
|
{
|
||||||
// Since we don't actually *know* the self type for an object,
|
// Since we don't actually *know* the self type for an object,
|
||||||
// this "open(err)" serves as a kind of dummy standin -- basically
|
// this "open(err)" serves as a kind of dummy standin -- basically
|
||||||
|
@ -177,12 +177,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||||||
let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| {
|
let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| {
|
||||||
// Don't print any regions if they're all erased.
|
// Don't print any regions if they're all erased.
|
||||||
let regions = || substs.regions().skip(skip).take(count);
|
let regions = || substs.regions().skip(skip).take(count);
|
||||||
if regions().all(|r: &ty::Region| *r == ty::ReErased) {
|
if regions().all(|r: ty::Region| *r == ty::ReErased) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
for region in regions() {
|
for region in regions() {
|
||||||
let region: &ty::Region = region;
|
let region: ty::Region = region;
|
||||||
start_or_continue(f, start, ", ")?;
|
start_or_continue(f, start, ", ")?;
|
||||||
if verbose {
|
if verbose {
|
||||||
write!(f, "{:?}", region)?;
|
write!(f, "{:?}", region)?;
|
||||||
@ -458,7 +458,7 @@ impl fmt::Debug for ty::BoundRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ty::Region {
|
impl<'tcx> fmt::Debug for ty::RegionKind<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
@ -516,7 +516,7 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ty::Region {
|
impl<'tcx> fmt::Display for ty::RegionKind<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if verbose() {
|
if verbose() {
|
||||||
return write!(f, "{:?}", *self);
|
return write!(f, "{:?}", *self);
|
||||||
@ -544,7 +544,7 @@ impl fmt::Display for ty::Region {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ty::FreeRegion {
|
impl<'tcx> fmt::Debug for ty::FreeRegion<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "ReFree({:?}, {:?})",
|
write!(f, "ReFree({:?}, {:?})",
|
||||||
self.scope, self.bound_region)
|
self.scope, self.bound_region)
|
||||||
@ -689,14 +689,14 @@ impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, &'tcx ty::Region>> {
|
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
|
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region,
|
impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>,
|
||||||
&'tcx ty::Region>> {
|
ty::Region<'tcx>>> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
|
ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
|
|||||||
borrow_id: ast::NodeId,
|
borrow_id: ast::NodeId,
|
||||||
borrow_span: Span,
|
borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
loan_cause: euv::LoanCause)
|
loan_cause: euv::LoanCause)
|
||||||
{
|
{
|
||||||
@ -232,14 +232,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
|
pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent<'tcx>, mut op: F) -> bool where
|
||||||
F: FnMut(&Loan<'tcx>) -> bool,
|
F: FnMut(&Loan<'tcx>) -> bool,
|
||||||
{
|
{
|
||||||
//! Like `each_issued_loan()`, but only considers loans that are
|
//! Like `each_issued_loan()`, but only considers loans that are
|
||||||
//! currently in scope.
|
//! currently in scope.
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
self.each_issued_loan(scope.node_id(&tcx.region_maps()), |loan| {
|
self.each_issued_loan(scope.node_id(), |loan| {
|
||||||
if tcx.region_maps().is_subscope_of(scope, loan.kill_scope) {
|
if tcx.region_maps().is_subscope_of(scope, loan.kill_scope) {
|
||||||
op(loan)
|
op(loan)
|
||||||
} else {
|
} else {
|
||||||
@ -249,7 +249,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn each_in_scope_loan_affecting_path<F>(&self,
|
fn each_in_scope_loan_affecting_path<F>(&self,
|
||||||
scope: region::CodeExtent,
|
scope: region::CodeExtent<'tcx>,
|
||||||
loan_path: &LoanPath<'tcx>,
|
loan_path: &LoanPath<'tcx>,
|
||||||
mut op: F)
|
mut op: F)
|
||||||
-> bool where
|
-> bool where
|
||||||
@ -460,8 +460,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
// 3. Where does old loan expire.
|
// 3. Where does old loan expire.
|
||||||
|
|
||||||
let previous_end_span =
|
let previous_end_span =
|
||||||
self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps()))
|
self.tcx().hir.span(old_loan.kill_scope.node_id()).end_point();
|
||||||
.end_point();
|
|
||||||
|
|
||||||
let mut err = match (new_loan.kind, old_loan.kind) {
|
let mut err = match (new_loan.kind, old_loan.kind) {
|
||||||
(ty::MutBorrow, ty::MutBorrow) => {
|
(ty::MutBorrow, ty::MutBorrow) => {
|
||||||
@ -710,7 +709,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
let mut ret = UseOk;
|
let mut ret = UseOk;
|
||||||
|
|
||||||
self.each_in_scope_loan_affecting_path(
|
self.each_in_scope_loan_affecting_path(
|
||||||
self.tcx().region_maps().node_extent(expr_id), use_path, |loan| {
|
self.tcx().node_extent(expr_id), use_path, |loan| {
|
||||||
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
|
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
|
||||||
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
|
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
|
||||||
false
|
false
|
||||||
@ -824,7 +823,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Check that we don't invalidate any outstanding loans
|
// Check that we don't invalidate any outstanding loans
|
||||||
if let Some(loan_path) = opt_loan_path(&assignee_cmt) {
|
if let Some(loan_path) = opt_loan_path(&assignee_cmt) {
|
||||||
let scope = self.tcx().region_maps().node_extent(assignment_id);
|
let scope = self.tcx().node_extent(assignment_id);
|
||||||
self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| {
|
self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| {
|
||||||
self.report_illegal_mutation(assignment_span, &loan_path, loan);
|
self.report_illegal_mutation(assignment_span, &loan_path, loan);
|
||||||
false
|
false
|
||||||
|
@ -24,11 +24,11 @@ use syntax_pos::Span;
|
|||||||
type R = Result<(),()>;
|
type R = Result<(),()>;
|
||||||
|
|
||||||
pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||||
item_scope: region::CodeExtent,
|
item_scope: region::CodeExtent<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
cause: euv::LoanCause,
|
cause: euv::LoanCause,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
_: ty::BorrowKind)
|
_: ty::BorrowKind)
|
||||||
-> Result<(),()> {
|
-> Result<(),()> {
|
||||||
//! Reports error if `loan_region` is larger than S
|
//! Reports error if `loan_region` is larger than S
|
||||||
@ -52,11 +52,11 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> {
|
|||||||
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
// the scope of the function body for the enclosing item
|
// the scope of the function body for the enclosing item
|
||||||
item_scope: region::CodeExtent,
|
item_scope: region::CodeExtent<'tcx>,
|
||||||
|
|
||||||
span: Span,
|
span: Span,
|
||||||
cause: euv::LoanCause,
|
cause: euv::LoanCause,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
cmt_original: mc::cmt<'tcx>
|
cmt_original: mc::cmt<'tcx>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_scope(&self, max_scope: &'tcx ty::Region) -> R {
|
fn check_scope(&self, max_scope: ty::Region<'tcx>) -> R {
|
||||||
//! Reports an error if `loan_region` is larger than `max_scope`
|
//! Reports an error if `loan_region` is larger than `max_scope`
|
||||||
|
|
||||||
if !self.bccx.is_subregion_of(self.loan_region, max_scope) {
|
if !self.bccx.is_subregion_of(self.loan_region, max_scope) {
|
||||||
@ -102,7 +102,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scope(&self, cmt: &mc::cmt<'tcx>) -> &'tcx ty::Region {
|
fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'tcx> {
|
||||||
//! Returns the maximal region scope for the which the
|
//! Returns the maximal region scope for the which the
|
||||||
//! lvalue `cmt` is guaranteed to be valid without any
|
//! lvalue `cmt` is guaranteed to be valid without any
|
||||||
//! rooting etc, and presuming `cmt` is not mutated.
|
//! rooting etc, and presuming `cmt` is not mutated.
|
||||||
|
@ -45,7 +45,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
|||||||
bccx: bccx,
|
bccx: bccx,
|
||||||
infcx: &infcx,
|
infcx: &infcx,
|
||||||
all_loans: Vec::new(),
|
all_loans: Vec::new(),
|
||||||
item_ub: bccx.tcx.region_maps().node_extent(body.node_id),
|
item_ub: bccx.tcx.node_extent(body.node_id),
|
||||||
move_data: MoveData::new(),
|
move_data: MoveData::new(),
|
||||||
move_error_collector: move_error::MoveErrorCollector::new(),
|
move_error_collector: move_error::MoveErrorCollector::new(),
|
||||||
};
|
};
|
||||||
@ -66,7 +66,7 @@ struct GatherLoanCtxt<'a, 'tcx: 'a> {
|
|||||||
all_loans: Vec<Loan<'tcx>>,
|
all_loans: Vec<Loan<'tcx>>,
|
||||||
/// `item_ub` is used as an upper-bound on the lifetime whenever we
|
/// `item_ub` is used as an upper-bound on the lifetime whenever we
|
||||||
/// ask for the scope of an expression categorized as an upvar.
|
/// ask for the scope of an expression categorized as an upvar.
|
||||||
item_ub: region::CodeExtent,
|
item_ub: region::CodeExtent<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
|
||||||
@ -127,7 +127,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
|
|||||||
borrow_id: ast::NodeId,
|
borrow_id: ast::NodeId,
|
||||||
borrow_span: Span,
|
borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
loan_cause: euv::LoanCause)
|
loan_cause: euv::LoanCause)
|
||||||
{
|
{
|
||||||
@ -299,7 +299,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
|||||||
borrow_span: Span,
|
borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
req_kind: ty::BorrowKind,
|
req_kind: ty::BorrowKind,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
cause: euv::LoanCause) {
|
cause: euv::LoanCause) {
|
||||||
debug!("guarantee_valid(borrow_id={}, cmt={:?}, \
|
debug!("guarantee_valid(borrow_id={}, cmt={:?}, \
|
||||||
req_mutbl={:?}, loan_region={:?})",
|
req_mutbl={:?}, loan_region={:?})",
|
||||||
@ -371,7 +371,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
debug!("loan_scope = {:?}", loan_scope);
|
debug!("loan_scope = {:?}", loan_scope);
|
||||||
|
|
||||||
let borrow_scope = self.tcx().region_maps().node_extent(borrow_id);
|
let borrow_scope = self.tcx().node_extent(borrow_id);
|
||||||
let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope);
|
let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope);
|
||||||
debug!("gen_scope = {:?}", gen_scope);
|
debug!("gen_scope = {:?}", gen_scope);
|
||||||
|
|
||||||
@ -450,9 +450,9 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_gen_scope(&self,
|
pub fn compute_gen_scope(&self,
|
||||||
borrow_scope: region::CodeExtent,
|
borrow_scope: region::CodeExtent<'tcx>,
|
||||||
loan_scope: region::CodeExtent)
|
loan_scope: region::CodeExtent<'tcx>)
|
||||||
-> region::CodeExtent {
|
-> region::CodeExtent<'tcx> {
|
||||||
//! Determine when to introduce the loan. Typically the loan
|
//! Determine when to introduce the loan. Typically the loan
|
||||||
//! is introduced at the point of the borrow, but in some cases,
|
//! is introduced at the point of the borrow, but in some cases,
|
||||||
//! notably method arguments, the loan may be introduced only
|
//! notably method arguments, the loan may be introduced only
|
||||||
@ -465,8 +465,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent, lp: &LoanPath<'tcx>)
|
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent<'tcx>, lp: &LoanPath<'tcx>)
|
||||||
-> region::CodeExtent {
|
-> region::CodeExtent<'tcx> {
|
||||||
//! Determine when the loan restrictions go out of scope.
|
//! Determine when the loan restrictions go out of scope.
|
||||||
//! This is either when the lifetime expires or when the
|
//! This is either when the lifetime expires or when the
|
||||||
//! local variable which roots the loan-path goes out of scope,
|
//! local variable which roots the loan-path goes out of scope,
|
||||||
|
@ -31,7 +31,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
|||||||
span: Span,
|
span: Span,
|
||||||
cause: euv::LoanCause,
|
cause: euv::LoanCause,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
loan_region: &'tcx ty::Region)
|
loan_region: ty::Region<'tcx>)
|
||||||
-> RestrictionResult<'tcx> {
|
-> RestrictionResult<'tcx> {
|
||||||
let ctxt = RestrictionsContext {
|
let ctxt = RestrictionsContext {
|
||||||
bccx: bccx,
|
bccx: bccx,
|
||||||
@ -49,7 +49,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
|||||||
struct RestrictionsContext<'a, 'tcx: 'a> {
|
struct RestrictionsContext<'a, 'tcx: 'a> {
|
||||||
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
loan_region: &'tcx ty::Region,
|
loan_region: ty::Region<'tcx>,
|
||||||
cause: euv::LoanCause,
|
cause: euv::LoanCause,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,9 +141,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
|||||||
id_range,
|
id_range,
|
||||||
all_loans.len());
|
all_loans.len());
|
||||||
for (loan_idx, loan) in all_loans.iter().enumerate() {
|
for (loan_idx, loan) in all_loans.iter().enumerate() {
|
||||||
loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps()), loan_idx);
|
loan_dfcx.add_gen(loan.gen_scope.node_id(), loan_idx);
|
||||||
loan_dfcx.add_kill(KillFrom::ScopeEnd,
|
loan_dfcx.add_kill(KillFrom::ScopeEnd,
|
||||||
loan.kill_scope.node_id(&tcx.region_maps()), loan_idx);
|
loan.kill_scope.node_id(), loan_idx);
|
||||||
}
|
}
|
||||||
loan_dfcx.add_kills_from_flow_exits(cfg);
|
loan_dfcx.add_kills_from_flow_exits(cfg);
|
||||||
loan_dfcx.propagate(cfg, body);
|
loan_dfcx.propagate(cfg, body);
|
||||||
@ -206,13 +206,13 @@ pub struct Loan<'tcx> {
|
|||||||
/// cases, notably method arguments, the loan may be introduced
|
/// cases, notably method arguments, the loan may be introduced
|
||||||
/// only later, once it comes into scope. See also
|
/// only later, once it comes into scope. See also
|
||||||
/// `GatherLoanCtxt::compute_gen_scope`.
|
/// `GatherLoanCtxt::compute_gen_scope`.
|
||||||
gen_scope: region::CodeExtent,
|
gen_scope: region::CodeExtent<'tcx>,
|
||||||
|
|
||||||
/// kill_scope indicates when the loan goes out of scope. This is
|
/// kill_scope indicates when the loan goes out of scope. This is
|
||||||
/// either when the lifetime expires or when the local variable
|
/// either when the lifetime expires or when the local variable
|
||||||
/// which roots the loan-path goes out of scope, whichever happens
|
/// which roots the loan-path goes out of scope, whichever happens
|
||||||
/// faster. See also `GatherLoanCtxt::compute_kill_scope`.
|
/// faster. See also `GatherLoanCtxt::compute_kill_scope`.
|
||||||
kill_scope: region::CodeExtent,
|
kill_scope: region::CodeExtent<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
cause: euv::LoanCause,
|
cause: euv::LoanCause,
|
||||||
}
|
}
|
||||||
@ -312,12 +312,12 @@ pub fn closure_to_block(closure_id: ast::NodeId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LoanPath<'tcx> {
|
impl<'a, 'tcx> LoanPath<'tcx> {
|
||||||
pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent {
|
pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent<'tcx> {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
LpVar(local_id) => tcx.region_maps().var_scope(local_id),
|
LpVar(local_id) => tcx.region_maps().var_scope(local_id),
|
||||||
LpUpvar(upvar_id) => {
|
LpUpvar(upvar_id) => {
|
||||||
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
|
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
|
||||||
tcx.region_maps().node_extent(block_id)
|
tcx.node_extent(block_id)
|
||||||
}
|
}
|
||||||
LpDowncast(ref base, _) |
|
LpDowncast(ref base, _) |
|
||||||
LpExtend(ref base, ..) => base.kill_scope(tcx),
|
LpExtend(ref base, ..) => base.kill_scope(tcx),
|
||||||
@ -444,8 +444,8 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
|
|||||||
pub enum bckerr_code<'tcx> {
|
pub enum bckerr_code<'tcx> {
|
||||||
err_mutbl,
|
err_mutbl,
|
||||||
/// superscope, subscope, loan cause
|
/// superscope, subscope, loan cause
|
||||||
err_out_of_scope(&'tcx ty::Region, &'tcx ty::Region, euv::LoanCause),
|
err_out_of_scope(ty::Region<'tcx>, ty::Region<'tcx>, euv::LoanCause),
|
||||||
err_borrowed_pointer_too_short(&'tcx ty::Region, &'tcx ty::Region), // loan, ptr
|
err_borrowed_pointer_too_short(ty::Region<'tcx>, ty::Region<'tcx>), // loan, ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combination of an error code and the categorization of the expression
|
// Combination of an error code and the categorization of the expression
|
||||||
@ -475,8 +475,8 @@ pub enum MovedValueUseKind {
|
|||||||
|
|
||||||
impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||||
pub fn is_subregion_of(&self,
|
pub fn is_subregion_of(&self,
|
||||||
r_sub: &'tcx ty::Region,
|
r_sub: ty::Region<'tcx>,
|
||||||
r_sup: &'tcx ty::Region)
|
r_sup: ty::Region<'tcx>)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
self.tables.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup)
|
self.tables.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup)
|
||||||
@ -963,10 +963,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
|||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn region_end_span(&self, region: &'tcx ty::Region) -> Option<Span> {
|
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReScope(scope) => {
|
ty::ReScope(scope) => {
|
||||||
match scope.span(&self.tcx.region_maps(), &self.tcx.hir) {
|
match scope.span(&self.tcx.hir) {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
Some(s.end_point())
|
Some(s.end_point())
|
||||||
}
|
}
|
||||||
@ -1244,10 +1244,10 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option<Span> {
|
fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option<Span> {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReScope(scope) => {
|
ty::ReScope(scope) => {
|
||||||
match tcx.hir.find(scope.node_id(&tcx.region_maps())) {
|
match tcx.hir.find(scope.node_id()) {
|
||||||
Some(hir_map::NodeStmt(stmt)) => Some(stmt.span),
|
Some(hir_map::NodeStmt(stmt)) => Some(stmt.span),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ impl<'a, 'tcx> MoveData<'tcx> {
|
|||||||
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
||||||
let kill_scope = path.loan_path.kill_scope(tcx);
|
let kill_scope = path.loan_path.kill_scope(tcx);
|
||||||
let path = *self.path_map.borrow().get(&path.loan_path).unwrap();
|
let path = *self.path_map.borrow().get(&path.loan_path).unwrap();
|
||||||
self.kill_moves(path, kill_scope.node_id(&tcx.region_maps()),
|
self.kill_moves(path, kill_scope.node_id(),
|
||||||
KillFrom::ScopeEnd, dfcx_moves);
|
KillFrom::ScopeEnd, dfcx_moves);
|
||||||
}
|
}
|
||||||
LpExtend(..) => {}
|
LpExtend(..) => {}
|
||||||
@ -563,7 +563,7 @@ impl<'a, 'tcx> MoveData<'tcx> {
|
|||||||
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
||||||
let kill_scope = lp.kill_scope(tcx);
|
let kill_scope = lp.kill_scope(tcx);
|
||||||
dfcx_assign.add_kill(KillFrom::ScopeEnd,
|
dfcx_assign.add_kill(KillFrom::ScopeEnd,
|
||||||
kill_scope.node_id(&tcx.region_maps()),
|
kill_scope.node_id(),
|
||||||
assignment_index);
|
assignment_index);
|
||||||
}
|
}
|
||||||
LpExtend(..) => {
|
LpExtend(..) => {
|
||||||
|
@ -533,7 +533,7 @@ impl<'a, 'gcx, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'gcx> {
|
|||||||
_: ast::NodeId,
|
_: ast::NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
_: cmt,
|
_: cmt,
|
||||||
_: &'tcx ty::Region,
|
_: ty::Region<'tcx>,
|
||||||
kind:ty:: BorrowKind,
|
kind:ty:: BorrowKind,
|
||||||
_: LoanCause) {
|
_: LoanCause) {
|
||||||
match kind {
|
match kind {
|
||||||
|
@ -35,7 +35,7 @@ pub enum PatternError<'tcx> {
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum BindingMode<'tcx> {
|
pub enum BindingMode<'tcx> {
|
||||||
ByValue,
|
ByValue,
|
||||||
ByRef(&'tcx Region, BorrowKind),
|
ByRef(Region<'tcx>, BorrowKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -811,7 +811,7 @@ macro_rules! CloneImpls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CloneImpls!{ <'tcx>
|
CloneImpls!{ <'tcx>
|
||||||
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region,
|
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region<'tcx>,
|
||||||
Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
|
Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
|
||||||
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>
|
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,27 @@ impl<T: Debug + PartialEq> TransitiveRelation<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Applies the (partial) function to each edge and returns a new
|
||||||
|
/// relation. If `f` returns `None` for any end-point, returns
|
||||||
|
/// `None`.
|
||||||
|
pub fn maybe_map<F, U>(&self, mut f: F) -> Option<TransitiveRelation<U>>
|
||||||
|
where F: FnMut(&T) -> Option<U>,
|
||||||
|
U: Debug + PartialEq,
|
||||||
|
{
|
||||||
|
let mut result = TransitiveRelation::new();
|
||||||
|
for edge in &self.edges {
|
||||||
|
let r = f(&self.elements[edge.source.0]).and_then(|source| {
|
||||||
|
f(&self.elements[edge.target.0]).and_then(|target| {
|
||||||
|
Some(result.add(source, target))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
if r.is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicate that `a < b` (where `<` is this relation)
|
/// Indicate that `a < b` (where `<` is this relation)
|
||||||
pub fn add(&mut self, a: T, b: T) {
|
pub fn add(&mut self, a: T, b: T) {
|
||||||
let a = self.add_index(a);
|
let a = self.add_index(a);
|
||||||
|
@ -293,7 +293,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
|||||||
self.infcx.tcx.mk_param(index, Symbol::intern(&name))
|
self.infcx.tcx.mk_param(index, Symbol::intern(&name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn re_early_bound(&self, index: u32, name: &'static str) -> &'tcx ty::Region {
|
pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> {
|
||||||
let name = Symbol::intern(name);
|
let name = Symbol::intern(name);
|
||||||
self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
|
self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
|
||||||
index: index,
|
index: index,
|
||||||
@ -304,11 +304,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
|||||||
pub fn re_late_bound_with_debruijn(&self,
|
pub fn re_late_bound_with_debruijn(&self,
|
||||||
id: u32,
|
id: u32,
|
||||||
debruijn: ty::DebruijnIndex)
|
debruijn: ty::DebruijnIndex)
|
||||||
-> &'tcx ty::Region {
|
-> ty::Region<'tcx> {
|
||||||
self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
|
self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn t_rptr(&self, r: &'tcx ty::Region) -> Ty<'tcx> {
|
pub fn t_rptr(&self, r: ty::Region<'tcx>) -> Ty<'tcx> {
|
||||||
self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
|
self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
|
|||||||
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
|
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> &'tcx ty::Region {
|
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> {
|
||||||
self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||||
scope: self.tcx().region_maps.item_extent(nid),
|
scope: self.tcx().region_maps.item_extent(nid),
|
||||||
bound_region: ty::BrAnon(id),
|
bound_region: ty::BrAnon(id),
|
||||||
|
@ -20,6 +20,7 @@ use rustc::middle::cstore::LinkagePreference;
|
|||||||
use rustc::hir::def::{self, Def, CtorKind};
|
use rustc::hir::def::{self, Def, CtorKind};
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
|
use rustc::middle::region;
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
@ -352,12 +353,18 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx> SpecializedDecoder<ty::Region<'tcx>> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<&'tcx ty::Region, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
Ok(self.tcx().mk_region(Decodable::decode(self)?))
|
Ok(self.tcx().mk_region(Decodable::decode(self)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> SpecializedDecoder<region::CodeExtent<'tcx>> for DecodeContext<'a, 'tcx> {
|
||||||
|
fn specialized_decode(&mut self) -> Result<region::CodeExtent<'tcx>, Self::Error> {
|
||||||
|
Ok(self.tcx().intern_code_extent(Decodable::decode(self)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
|
||||||
Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
|
Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
|
||||||
|
@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
let_extent_stack.push(remainder_scope);
|
let_extent_stack.push(remainder_scope);
|
||||||
|
|
||||||
// Declare the bindings, which may create a visibility scope.
|
// Declare the bindings, which may create a visibility scope.
|
||||||
let remainder_span = remainder_scope.span(&tcx.region_maps(), &tcx.hir);
|
let remainder_span = remainder_scope.span(&tcx.hir);
|
||||||
let remainder_span = remainder_span.unwrap_or(span);
|
let remainder_span = remainder_span.unwrap_or(span);
|
||||||
let scope = this.declare_bindings(None, remainder_span, &pattern);
|
let scope = this.declare_bindings(None, remainder_span, &pattern);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// The operand is known to be live until the end of `scope`.
|
/// The operand is known to be live until the end of `scope`.
|
||||||
pub fn as_operand<M>(&mut self,
|
pub fn as_operand<M>(&mut self,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
scope: Option<CodeExtent>,
|
scope: Option<CodeExtent<'tcx>>,
|
||||||
expr: M) -> BlockAnd<Operand<'tcx>>
|
expr: M) -> BlockAnd<Operand<'tcx>>
|
||||||
where M: Mirror<'tcx, Output = Expr<'tcx>>
|
where M: Mirror<'tcx, Output = Expr<'tcx>>
|
||||||
{
|
{
|
||||||
@ -49,7 +49,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn expr_as_operand(&mut self,
|
fn expr_as_operand(&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
scope: Option<CodeExtent>,
|
scope: Option<CodeExtent<'tcx>>,
|
||||||
expr: Expr<'tcx>)
|
expr: Expr<'tcx>)
|
||||||
-> BlockAnd<Operand<'tcx>> {
|
-> BlockAnd<Operand<'tcx>> {
|
||||||
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
|
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
|
||||||
|
@ -38,7 +38,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compile `expr`, yielding an rvalue.
|
/// Compile `expr`, yielding an rvalue.
|
||||||
pub fn as_rvalue<M>(&mut self, block: BasicBlock, scope: Option<CodeExtent>, expr: M)
|
pub fn as_rvalue<M>(&mut self, block: BasicBlock, scope: Option<CodeExtent<'tcx>>, expr: M)
|
||||||
-> BlockAnd<Rvalue<'tcx>>
|
-> BlockAnd<Rvalue<'tcx>>
|
||||||
where M: Mirror<'tcx, Output = Expr<'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,
|
fn expr_as_rvalue(&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
scope: Option<CodeExtent>,
|
scope: Option<CodeExtent<'tcx>>,
|
||||||
expr: Expr<'tcx>)
|
expr: Expr<'tcx>)
|
||||||
-> BlockAnd<Rvalue<'tcx>> {
|
-> BlockAnd<Rvalue<'tcx>> {
|
||||||
debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);
|
debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);
|
||||||
|
@ -21,7 +21,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// up rvalues so as to freeze the value that will be consumed.
|
/// up rvalues so as to freeze the value that will be consumed.
|
||||||
pub fn as_temp<M>(&mut self,
|
pub fn as_temp<M>(&mut self,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
temp_lifetime: Option<CodeExtent>,
|
temp_lifetime: Option<CodeExtent<'tcx>>,
|
||||||
expr: M)
|
expr: M)
|
||||||
-> BlockAnd<Lvalue<'tcx>>
|
-> BlockAnd<Lvalue<'tcx>>
|
||||||
where M: Mirror<'tcx, Output = Expr<'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,
|
fn expr_as_temp(&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
temp_lifetime: Option<CodeExtent>,
|
temp_lifetime: Option<CodeExtent<'tcx>>,
|
||||||
expr: Expr<'tcx>)
|
expr: Expr<'tcx>)
|
||||||
-> BlockAnd<Lvalue<'tcx>> {
|
-> BlockAnd<Lvalue<'tcx>> {
|
||||||
debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);
|
debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);
|
||||||
|
@ -137,10 +137,10 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||||||
let mut builder = Builder::new(hir, span, arguments.len(), return_ty);
|
let mut builder = Builder::new(hir, span, arguments.len(), return_ty);
|
||||||
|
|
||||||
let call_site_extent =
|
let call_site_extent =
|
||||||
tcx.region_maps().lookup_code_extent(
|
tcx.intern_code_extent(
|
||||||
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id });
|
CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id });
|
||||||
let arg_extent =
|
let arg_extent =
|
||||||
tcx.region_maps().lookup_code_extent(
|
tcx.intern_code_extent(
|
||||||
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id });
|
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id });
|
||||||
let mut block = START_BLOCK;
|
let mut block = START_BLOCK;
|
||||||
unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
|
unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
|
||||||
@ -205,8 +205,8 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||||||
let mut builder = Builder::new(hir, span, 0, ty);
|
let mut builder = Builder::new(hir, span, 0, ty);
|
||||||
|
|
||||||
let region_maps = tcx.region_maps();
|
let region_maps = tcx.region_maps();
|
||||||
let extent = region_maps.temporary_scope(ast_expr.id)
|
let extent = region_maps.temporary_scope(tcx, ast_expr.id)
|
||||||
.unwrap_or(region_maps.item_extent(owner_id));
|
.unwrap_or(tcx.item_extent(owner_id));
|
||||||
let mut block = START_BLOCK;
|
let mut block = START_BLOCK;
|
||||||
let _ = builder.in_scope(extent, block, |builder| {
|
let _ = builder.in_scope(extent, block, |builder| {
|
||||||
let expr = builder.hir.mirror(ast_expr);
|
let expr = builder.hir.mirror(ast_expr);
|
||||||
@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
fn args_and_body(&mut self,
|
fn args_and_body(&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
arguments: &[(Ty<'gcx>, Option<&'gcx hir::Pat>)],
|
arguments: &[(Ty<'gcx>, Option<&'gcx hir::Pat>)],
|
||||||
argument_extent: CodeExtent,
|
argument_extent: CodeExtent<'tcx>,
|
||||||
ast_body: &'gcx hir::Expr)
|
ast_body: &'gcx hir::Expr)
|
||||||
-> BlockAnd<()>
|
-> BlockAnd<()>
|
||||||
{
|
{
|
||||||
|
@ -102,7 +102,7 @@ pub struct Scope<'tcx> {
|
|||||||
visibility_scope: VisibilityScope,
|
visibility_scope: VisibilityScope,
|
||||||
|
|
||||||
/// the extent of this scope within source code.
|
/// the extent of this scope within source code.
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
|
|
||||||
/// Whether there's anything to do for the cleanup path, that is,
|
/// Whether there's anything to do for the cleanup path, that is,
|
||||||
/// when unwinding through this scope. This includes destructors,
|
/// when unwinding through this scope. This includes destructors,
|
||||||
@ -137,7 +137,7 @@ pub struct Scope<'tcx> {
|
|||||||
free: Option<FreeData<'tcx>>,
|
free: Option<FreeData<'tcx>>,
|
||||||
|
|
||||||
/// The cache for drop chain on “normal” exit into a particular BasicBlock.
|
/// The cache for drop chain on “normal” exit into a particular BasicBlock.
|
||||||
cached_exits: FxHashMap<(BasicBlock, CodeExtent), BasicBlock>,
|
cached_exits: FxHashMap<(BasicBlock, CodeExtent<'tcx>), BasicBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DropData<'tcx> {
|
struct DropData<'tcx> {
|
||||||
@ -180,7 +180,7 @@ struct FreeData<'tcx> {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BreakableScope<'tcx> {
|
pub struct BreakableScope<'tcx> {
|
||||||
/// Extent of the loop
|
/// Extent of the loop
|
||||||
pub extent: CodeExtent,
|
pub extent: CodeExtent<'tcx>,
|
||||||
/// Where the body of the loop begins. `None` if block
|
/// Where the body of the loop begins. `None` if block
|
||||||
pub continue_block: Option<BasicBlock>,
|
pub continue_block: Option<BasicBlock>,
|
||||||
/// Block to branch into when the loop or block terminates (either by being `break`-en out
|
/// Block to branch into when the loop or block terminates (either by being `break`-en out
|
||||||
@ -248,10 +248,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
///
|
///
|
||||||
/// Returns the might_break attribute of the BreakableScope used.
|
/// Returns the might_break attribute of the BreakableScope used.
|
||||||
pub fn in_breakable_scope<F, R>(&mut self,
|
pub fn in_breakable_scope<F, R>(&mut self,
|
||||||
loop_block: Option<BasicBlock>,
|
loop_block: Option<BasicBlock>,
|
||||||
break_block: BasicBlock,
|
break_block: BasicBlock,
|
||||||
break_destination: Lvalue<'tcx>,
|
break_destination: Lvalue<'tcx>,
|
||||||
f: F) -> R
|
f: F) -> R
|
||||||
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R
|
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R
|
||||||
{
|
{
|
||||||
let extent = self.topmost_scope();
|
let extent = self.topmost_scope();
|
||||||
@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
/// Convenience wrapper that pushes a scope and then executes `f`
|
/// Convenience wrapper that pushes a scope and then executes `f`
|
||||||
/// to build its contents, popping the scope afterwards.
|
/// to build its contents, popping the scope afterwards.
|
||||||
pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F) -> BlockAnd<R>
|
pub fn in_scope<F, R>(&mut self, extent: CodeExtent<'tcx>, mut block: BasicBlock, f: F) -> BlockAnd<R>
|
||||||
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
|
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd<R>
|
||||||
{
|
{
|
||||||
debug!("in_scope(extent={:?}, block={:?})", extent, block);
|
debug!("in_scope(extent={:?}, block={:?})", extent, block);
|
||||||
@ -285,7 +285,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// scope and call `pop_scope` afterwards. Note that these two
|
/// scope and call `pop_scope` afterwards. Note that these two
|
||||||
/// calls must be paired; using `in_scope` as a convenience
|
/// calls must be paired; using `in_scope` as a convenience
|
||||||
/// wrapper maybe preferable.
|
/// wrapper maybe preferable.
|
||||||
pub fn push_scope(&mut self, extent: CodeExtent) {
|
pub fn push_scope(&mut self, extent: CodeExtent<'tcx>) {
|
||||||
debug!("push_scope({:?})", extent);
|
debug!("push_scope({:?})", extent);
|
||||||
let vis_scope = self.visibility_scope;
|
let vis_scope = self.visibility_scope;
|
||||||
self.scopes.push(Scope {
|
self.scopes.push(Scope {
|
||||||
@ -302,7 +302,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// drops onto the end of `block` that are needed. This must
|
/// drops onto the end of `block` that are needed. This must
|
||||||
/// match 1-to-1 with `push_scope`.
|
/// match 1-to-1 with `push_scope`.
|
||||||
pub fn pop_scope(&mut self,
|
pub fn pop_scope(&mut self,
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
mut block: BasicBlock)
|
mut block: BasicBlock)
|
||||||
-> BlockAnd<()> {
|
-> BlockAnd<()> {
|
||||||
debug!("pop_scope({:?}, {:?})", extent, block);
|
debug!("pop_scope({:?}, {:?})", extent, block);
|
||||||
@ -326,7 +326,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// module comment for details.
|
/// module comment for details.
|
||||||
pub fn exit_scope(&mut self,
|
pub fn exit_scope(&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
target: BasicBlock) {
|
target: BasicBlock) {
|
||||||
debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target);
|
debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target);
|
||||||
@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// resolving `break` and `continue`.
|
/// resolving `break` and `continue`.
|
||||||
pub fn find_breakable_scope(&mut self,
|
pub fn find_breakable_scope(&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
label: CodeExtent)
|
label: CodeExtent<'tcx>)
|
||||||
-> &mut BreakableScope<'tcx> {
|
-> &mut BreakableScope<'tcx> {
|
||||||
// find the loop-scope with the correct id
|
// find the loop-scope with the correct id
|
||||||
self.breakable_scopes.iter_mut()
|
self.breakable_scopes.iter_mut()
|
||||||
@ -407,11 +407,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
/// Returns the extent of the scope which should be exited by a
|
/// Returns the extent of the scope which should be exited by a
|
||||||
/// return.
|
/// return.
|
||||||
pub fn extent_of_return_scope(&self) -> CodeExtent {
|
pub fn extent_of_return_scope(&self) -> CodeExtent<'tcx> {
|
||||||
// The outermost scope (`scopes[0]`) will be the `CallSiteScope`.
|
// The outermost scope (`scopes[0]`) will be the `CallSiteScope`.
|
||||||
// We want `scopes[1]`, which is the `ParameterScope`.
|
// We want `scopes[1]`, which is the `ParameterScope`.
|
||||||
assert!(self.scopes.len() >= 2);
|
assert!(self.scopes.len() >= 2);
|
||||||
assert!(match self.hir.tcx().region_maps().code_extent_data(self.scopes[1].extent) {
|
assert!(match *self.scopes[1].extent {
|
||||||
CodeExtentData::ParameterScope { .. } => true,
|
CodeExtentData::ParameterScope { .. } => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
@ -420,7 +420,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
/// Returns the topmost active scope, which is known to be alive until
|
/// Returns the topmost active scope, which is known to be alive until
|
||||||
/// the next scope expression.
|
/// the next scope expression.
|
||||||
pub fn topmost_scope(&self) -> CodeExtent {
|
pub fn topmost_scope(&self) -> CodeExtent<'tcx> {
|
||||||
self.scopes.last().expect("topmost_scope: no scopes present").extent
|
self.scopes.last().expect("topmost_scope: no scopes present").extent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +430,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// `extent`.
|
/// `extent`.
|
||||||
pub fn schedule_drop(&mut self,
|
pub fn schedule_drop(&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
lvalue: &Lvalue<'tcx>,
|
lvalue: &Lvalue<'tcx>,
|
||||||
lvalue_ty: Ty<'tcx>) {
|
lvalue_ty: Ty<'tcx>) {
|
||||||
let needs_drop = self.hir.needs_drop(lvalue_ty);
|
let needs_drop = self.hir.needs_drop(lvalue_ty);
|
||||||
@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
scope.needs_cleanup = true;
|
scope.needs_cleanup = true;
|
||||||
}
|
}
|
||||||
let tcx = self.hir.tcx();
|
let tcx = self.hir.tcx();
|
||||||
let extent_span = extent.span(&tcx.region_maps(), &tcx.hir).unwrap();
|
let extent_span = extent.span(&tcx.hir).unwrap();
|
||||||
// Attribute scope exit drops to scope's closing brace
|
// Attribute scope exit drops to scope's closing brace
|
||||||
let scope_end = Span { lo: extent_span.hi, .. extent_span};
|
let scope_end = Span { lo: extent_span.hi, .. extent_span};
|
||||||
scope.drops.push(DropData {
|
scope.drops.push(DropData {
|
||||||
@ -520,7 +520,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
/// There may only be one “free” scheduled in any given scope.
|
/// There may only be one “free” scheduled in any given scope.
|
||||||
pub fn schedule_box_free(&mut self,
|
pub fn schedule_box_free(&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
value: &Lvalue<'tcx>,
|
value: &Lvalue<'tcx>,
|
||||||
item_ty: Ty<'tcx>) {
|
item_ty: Ty<'tcx>) {
|
||||||
for scope in self.scopes.iter_mut().rev() {
|
for scope in self.scopes.iter_mut().rev() {
|
||||||
|
@ -24,7 +24,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
|
|||||||
let stmts = mirror_stmts(cx, self.id, &*self.stmts);
|
let stmts = mirror_stmts(cx, self.id, &*self.stmts);
|
||||||
Block {
|
Block {
|
||||||
targeted_by_break: self.targeted_by_break,
|
targeted_by_break: self.targeted_by_break,
|
||||||
extent: cx.tcx.region_maps().node_extent(self.id),
|
extent: cx.tcx.node_extent(self.id),
|
||||||
span: self.span,
|
span: self.span,
|
||||||
stmts: stmts,
|
stmts: stmts,
|
||||||
expr: self.expr.to_ref(),
|
expr: self.expr.to_ref(),
|
||||||
@ -44,7 +44,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
result.push(StmtRef::Mirror(Box::new(Stmt {
|
result.push(StmtRef::Mirror(Box::new(Stmt {
|
||||||
span: stmt.span,
|
span: stmt.span,
|
||||||
kind: StmtKind::Expr {
|
kind: StmtKind::Expr {
|
||||||
scope: cx.tcx.region_maps().node_extent(id),
|
scope: cx.tcx.node_extent(id),
|
||||||
expr: expr.to_ref(),
|
expr: expr.to_ref(),
|
||||||
},
|
},
|
||||||
})))
|
})))
|
||||||
@ -60,14 +60,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
first_statement_index: index as u32,
|
first_statement_index: index as u32,
|
||||||
});
|
});
|
||||||
let remainder_extent =
|
let remainder_extent =
|
||||||
cx.tcx.region_maps().lookup_code_extent(remainder_extent);
|
cx.tcx.intern_code_extent(remainder_extent);
|
||||||
|
|
||||||
let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat);
|
let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat);
|
||||||
result.push(StmtRef::Mirror(Box::new(Stmt {
|
result.push(StmtRef::Mirror(Box::new(Stmt {
|
||||||
span: stmt.span,
|
span: stmt.span,
|
||||||
kind: StmtKind::Let {
|
kind: StmtKind::Let {
|
||||||
remainder_scope: remainder_extent,
|
remainder_scope: remainder_extent,
|
||||||
init_scope: cx.tcx.region_maps().node_extent(id),
|
init_scope: cx.tcx.node_extent(id),
|
||||||
pattern: pattern,
|
pattern: pattern,
|
||||||
initializer: local.init.to_ref(),
|
initializer: local.init.to_ref(),
|
||||||
},
|
},
|
||||||
@ -84,7 +84,7 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
block: &'tcx hir::Block)
|
block: &'tcx hir::Block)
|
||||||
-> ExprRef<'tcx> {
|
-> ExprRef<'tcx> {
|
||||||
let block_ty = cx.tables().node_id_to_type(block.id);
|
let block_ty = cx.tables().node_id_to_type(block.id);
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(block.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, block.id);
|
||||||
let expr = Expr {
|
let expr = Expr {
|
||||||
ty: block_ty,
|
ty: block_ty,
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
|
@ -26,8 +26,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
|||||||
type Output = Expr<'tcx>;
|
type Output = Expr<'tcx>;
|
||||||
|
|
||||||
fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
|
fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(self.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, self.id);
|
||||||
let expr_extent = cx.tcx.region_maps().node_extent(self.id);
|
let expr_extent = cx.tcx.node_extent(self.id);
|
||||||
|
|
||||||
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
|
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Finally, create a destruction scope, if any.
|
// Finally, create a destruction scope, if any.
|
||||||
if let Some(extent) = cx.tcx.region_maps().opt_destruction_extent(self.id) {
|
if let Some(extent) = cx.tcx.opt_destruction_extent(self.id) {
|
||||||
expr = Expr {
|
expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
temp_lifetime_was_shrunk: was_shrunk,
|
temp_lifetime_was_shrunk: was_shrunk,
|
||||||
@ -238,7 +238,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
expr: &'tcx hir::Expr)
|
expr: &'tcx hir::Expr)
|
||||||
-> Expr<'tcx> {
|
-> Expr<'tcx> {
|
||||||
let expr_ty = cx.tables().expr_ty(expr);
|
let expr_ty = cx.tables().expr_ty(expr);
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id);
|
||||||
|
|
||||||
let kind = match expr.node {
|
let kind = match expr.node {
|
||||||
// Here comes the interesting stuff:
|
// Here comes the interesting stuff:
|
||||||
@ -610,7 +610,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
match dest.target_id {
|
match dest.target_id {
|
||||||
hir::ScopeTarget::Block(target_id) |
|
hir::ScopeTarget::Block(target_id) |
|
||||||
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break {
|
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break {
|
||||||
label: cx.tcx.region_maps().node_extent(target_id),
|
label: cx.tcx.node_extent(target_id),
|
||||||
value: value.to_ref(),
|
value: value.to_ref(),
|
||||||
},
|
},
|
||||||
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
|
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
|
||||||
@ -621,7 +621,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
match dest.target_id {
|
match dest.target_id {
|
||||||
hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"),
|
hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"),
|
||||||
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue {
|
hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue {
|
||||||
label: cx.tcx.region_maps().node_extent(loop_id),
|
label: cx.tcx.node_extent(loop_id),
|
||||||
},
|
},
|
||||||
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
|
hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) =>
|
||||||
bug!("invalid loop id for continue: {}", err)
|
bug!("invalid loop id for continue: {}", err)
|
||||||
@ -686,7 +686,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
hir::ExprBox(ref value) => {
|
hir::ExprBox(ref value) => {
|
||||||
ExprKind::Box {
|
ExprKind::Box {
|
||||||
value: value.to_ref(),
|
value: value.to_ref(),
|
||||||
value_extents: cx.tcx.region_maps().node_extent(value.id),
|
value_extents: cx.tcx.node_extent(value.id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() },
|
hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() },
|
||||||
@ -707,7 +707,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
method_call: ty::MethodCall)
|
method_call: ty::MethodCall)
|
||||||
-> Expr<'tcx> {
|
-> Expr<'tcx> {
|
||||||
let callee = cx.tables().method_map[&method_call];
|
let callee = cx.tables().method_map[&method_call];
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id);
|
||||||
Expr {
|
Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
temp_lifetime_was_shrunk: was_shrunk,
|
temp_lifetime_was_shrunk: was_shrunk,
|
||||||
@ -791,7 +791,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
expr: &'tcx hir::Expr,
|
expr: &'tcx hir::Expr,
|
||||||
def: Def)
|
def: Def)
|
||||||
-> ExprKind<'tcx> {
|
-> ExprKind<'tcx> {
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id);
|
||||||
|
|
||||||
match def {
|
match def {
|
||||||
Def::Local(def_id) => {
|
Def::Local(def_id) => {
|
||||||
@ -827,8 +827,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
// FIXME we're just hard-coding the idea that the
|
// FIXME we're just hard-coding the idea that the
|
||||||
// signature will be &self or &mut self and hence will
|
// signature will be &self or &mut self and hence will
|
||||||
// have a bound region with number 0
|
// have a bound region with number 0
|
||||||
let region = ty::Region::ReFree(ty::FreeRegion {
|
let region = ty::ReFree(ty::FreeRegion {
|
||||||
scope: Some(cx.tcx.region_maps().node_extent(body_id)),
|
scope: Some(cx.tcx.node_extent(body_id)),
|
||||||
bound_region: ty::BoundRegion::BrAnon(0),
|
bound_region: ty::BoundRegion::BrAnon(0),
|
||||||
});
|
});
|
||||||
let region = cx.tcx.mk_region(region);
|
let region = cx.tcx.mk_region(region);
|
||||||
@ -979,7 +979,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
PassArgs::ByRef => {
|
PassArgs::ByRef => {
|
||||||
let region = cx.tcx.node_scope_region(expr.id);
|
let region = cx.tcx.node_scope_region(expr.id);
|
||||||
let (temp_lifetime, was_shrunk) =
|
let (temp_lifetime, was_shrunk) =
|
||||||
cx.tcx.region_maps().temporary_scope2(expr.id);
|
cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id);
|
||||||
argrefs.extend(args.iter()
|
argrefs.extend(args.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
let arg_ty = cx.tables().expr_ty_adjusted(arg);
|
let arg_ty = cx.tables().expr_ty_adjusted(arg);
|
||||||
@ -1031,7 +1031,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
|
|
||||||
// construct the complete expression `foo()` for the overloaded call,
|
// construct the complete expression `foo()` for the overloaded call,
|
||||||
// which will yield the &T type
|
// which will yield the &T type
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id);
|
||||||
let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args);
|
let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args);
|
||||||
let ref_expr = Expr {
|
let ref_expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
@ -1056,7 +1056,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
closure_expr_id: closure_expr.id,
|
closure_expr_id: closure_expr.id,
|
||||||
};
|
};
|
||||||
let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap();
|
let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap();
|
||||||
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(closure_expr.id);
|
let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, closure_expr.id);
|
||||||
let var_ty = cx.tables().node_id_to_type(id_var);
|
let var_ty = cx.tables().node_id_to_type(id_var);
|
||||||
let captured_var = Expr {
|
let captured_var = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
|
@ -32,7 +32,7 @@ pub use rustc_const_eval::pattern::{BindingMode, Pattern, PatternKind, FieldPatt
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Block<'tcx> {
|
pub struct Block<'tcx> {
|
||||||
pub targeted_by_break: bool,
|
pub targeted_by_break: bool,
|
||||||
pub extent: CodeExtent,
|
pub extent: CodeExtent<'tcx>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub stmts: Vec<StmtRef<'tcx>>,
|
pub stmts: Vec<StmtRef<'tcx>>,
|
||||||
pub expr: Option<ExprRef<'tcx>>,
|
pub expr: Option<ExprRef<'tcx>>,
|
||||||
@ -53,7 +53,7 @@ pub struct Stmt<'tcx> {
|
|||||||
pub enum StmtKind<'tcx> {
|
pub enum StmtKind<'tcx> {
|
||||||
Expr {
|
Expr {
|
||||||
/// scope for this statement; may be used as lifetime of temporaries
|
/// scope for this statement; may be used as lifetime of temporaries
|
||||||
scope: CodeExtent,
|
scope: CodeExtent<'tcx>,
|
||||||
|
|
||||||
/// expression being evaluated in this statement
|
/// expression being evaluated in this statement
|
||||||
expr: ExprRef<'tcx>,
|
expr: ExprRef<'tcx>,
|
||||||
@ -62,11 +62,11 @@ pub enum StmtKind<'tcx> {
|
|||||||
Let {
|
Let {
|
||||||
/// scope for variables bound in this let; covers this and
|
/// scope for variables bound in this let; covers this and
|
||||||
/// remaining statements in block
|
/// remaining statements in block
|
||||||
remainder_scope: CodeExtent,
|
remainder_scope: CodeExtent<'tcx>,
|
||||||
|
|
||||||
/// scope for the initialization itself; might be used as
|
/// scope for the initialization itself; might be used as
|
||||||
/// lifetime of temporaries
|
/// lifetime of temporaries
|
||||||
init_scope: CodeExtent,
|
init_scope: CodeExtent<'tcx>,
|
||||||
|
|
||||||
/// let <PAT> = ...
|
/// let <PAT> = ...
|
||||||
pattern: Pattern<'tcx>,
|
pattern: Pattern<'tcx>,
|
||||||
@ -97,7 +97,7 @@ pub struct Expr<'tcx> {
|
|||||||
|
|
||||||
/// lifetime of this expression if it should be spilled into a
|
/// lifetime of this expression if it should be spilled into a
|
||||||
/// temporary; should be None only if in a constant context
|
/// temporary; should be None only if in a constant context
|
||||||
pub temp_lifetime: Option<CodeExtent>,
|
pub temp_lifetime: Option<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
/// whether this temp lifetime was shrunk by #36082.
|
/// whether this temp lifetime was shrunk by #36082.
|
||||||
pub temp_lifetime_was_shrunk: bool,
|
pub temp_lifetime_was_shrunk: bool,
|
||||||
@ -112,12 +112,12 @@ pub struct Expr<'tcx> {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ExprKind<'tcx> {
|
pub enum ExprKind<'tcx> {
|
||||||
Scope {
|
Scope {
|
||||||
extent: CodeExtent,
|
extent: CodeExtent<'tcx>,
|
||||||
value: ExprRef<'tcx>,
|
value: ExprRef<'tcx>,
|
||||||
},
|
},
|
||||||
Box {
|
Box {
|
||||||
value: ExprRef<'tcx>,
|
value: ExprRef<'tcx>,
|
||||||
value_extents: CodeExtent,
|
value_extents: CodeExtent<'tcx>,
|
||||||
},
|
},
|
||||||
Call {
|
Call {
|
||||||
ty: ty::Ty<'tcx>,
|
ty: ty::Ty<'tcx>,
|
||||||
@ -205,16 +205,16 @@ pub enum ExprKind<'tcx> {
|
|||||||
id: DefId,
|
id: DefId,
|
||||||
},
|
},
|
||||||
Borrow {
|
Borrow {
|
||||||
region: &'tcx Region,
|
region: Region<'tcx>,
|
||||||
borrow_kind: BorrowKind,
|
borrow_kind: BorrowKind,
|
||||||
arg: ExprRef<'tcx>,
|
arg: ExprRef<'tcx>,
|
||||||
},
|
},
|
||||||
Break {
|
Break {
|
||||||
label: CodeExtent,
|
label: CodeExtent<'tcx>,
|
||||||
value: Option<ExprRef<'tcx>>,
|
value: Option<ExprRef<'tcx>>,
|
||||||
},
|
},
|
||||||
Continue {
|
Continue {
|
||||||
label: CodeExtent,
|
label: CodeExtent<'tcx>,
|
||||||
},
|
},
|
||||||
Return {
|
Return {
|
||||||
value: Option<ExprRef<'tcx>>,
|
value: Option<ExprRef<'tcx>>,
|
||||||
|
@ -252,8 +252,8 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
-> Ty<'tcx> {
|
-> Ty<'tcx> {
|
||||||
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
|
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
|
||||||
|
|
||||||
let region = ty::Region::ReFree(ty::FreeRegion {
|
let region = ty::ReFree(ty::FreeRegion {
|
||||||
scope: Some(tcx.region_maps().item_extent(body_id.node_id)),
|
scope: Some(tcx.item_extent(body_id.node_id)),
|
||||||
bound_region: ty::BoundRegion::BrEnv,
|
bound_region: ty::BoundRegion::BrEnv,
|
||||||
});
|
});
|
||||||
let region = tcx.mk_region(region);
|
let region = tcx.mk_region(region);
|
||||||
|
@ -480,7 +480,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> {
|
|||||||
borrow_id: ast::NodeId,
|
borrow_id: ast::NodeId,
|
||||||
_borrow_span: Span,
|
_borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
_loan_region: &'tcx ty::Region,
|
_loan_region: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
loan_cause: euv::LoanCause) {
|
loan_cause: euv::LoanCause) {
|
||||||
// Kind of hacky, but we allow Unsafe coercions in constants.
|
// Kind of hacky, but we allow Unsafe coercions in constants.
|
||||||
|
@ -53,7 +53,7 @@ pub trait AstConv<'gcx, 'tcx> {
|
|||||||
|
|
||||||
/// What lifetime should we use when a lifetime is omitted (and not elided)?
|
/// What lifetime should we use when a lifetime is omitted (and not elided)?
|
||||||
fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
|
fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>)
|
||||||
-> Option<&'tcx ty::Region>;
|
-> Option<ty::Region<'tcx>>;
|
||||||
|
|
||||||
/// What type should we use when a type is omitted?
|
/// What type should we use when a type is omitted?
|
||||||
fn ty_infer(&self, span: Span) -> Ty<'tcx>;
|
fn ty_infer(&self, span: Span) -> Ty<'tcx>;
|
||||||
@ -104,7 +104,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
pub fn ast_region_to_region(&self,
|
pub fn ast_region_to_region(&self,
|
||||||
lifetime: &hir::Lifetime,
|
lifetime: &hir::Lifetime,
|
||||||
def: Option<&ty::RegionParameterDef>)
|
def: Option<&ty::RegionParameterDef>)
|
||||||
-> &'tcx ty::Region
|
-> ty::Region<'tcx>
|
||||||
{
|
{
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let r = match tcx.named_region_map.defs.get(&lifetime.id) {
|
let r = match tcx.named_region_map.defs.get(&lifetime.id) {
|
||||||
@ -133,7 +133,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
Some(&rl::Region::Free(scope, id)) => {
|
Some(&rl::Region::Free(scope, id)) => {
|
||||||
let name = tcx.hir.name(id);
|
let name = tcx.hir.name(id);
|
||||||
tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
tcx.mk_region(ty::ReFree(ty::FreeRegion {
|
||||||
scope: Some(scope.to_code_extent(&tcx.region_maps())),
|
scope: Some(scope.to_code_extent(tcx)),
|
||||||
bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name)
|
bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -1342,7 +1342,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
fn compute_object_lifetime_bound(&self,
|
fn compute_object_lifetime_bound(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
|
existential_predicates: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>)
|
||||||
-> Option<&'tcx ty::Region> // if None, use the default
|
-> Option<ty::Region<'tcx>> // if None, use the default
|
||||||
{
|
{
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
@ -1489,7 +1489,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
|
|||||||
// and return from functions in multiple places.
|
// and return from functions in multiple places.
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct Bounds<'tcx> {
|
pub struct Bounds<'tcx> {
|
||||||
pub region_bounds: Vec<&'tcx ty::Region>,
|
pub region_bounds: Vec<ty::Region<'tcx>>,
|
||||||
pub implicitly_sized: bool,
|
pub implicitly_sized: bool,
|
||||||
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
||||||
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
|
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
|
||||||
@ -1533,7 +1533,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
|||||||
|
|
||||||
pub enum ExplicitSelf<'tcx> {
|
pub enum ExplicitSelf<'tcx> {
|
||||||
ByValue,
|
ByValue,
|
||||||
ByReference(&'tcx ty::Region, hir::Mutability),
|
ByReference(ty::Region<'tcx>, hir::Mutability),
|
||||||
ByBox
|
ByBox
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
|
||||||
|
|
||||||
let extent = self.tcx.region_maps().call_site_extent(expr.id, body.value.id);
|
let extent = self.tcx.call_site_extent(expr.id, body.value.id);
|
||||||
let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig);
|
let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig);
|
||||||
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
|
let fn_sig = self.inh.normalize_associated_types_in(body.value.span,
|
||||||
body.value.id, &fn_sig);
|
body.value.id, &fn_sig);
|
||||||
|
@ -250,7 +250,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||||||
exprs: &[E],
|
exprs: &[E],
|
||||||
a: Ty<'tcx>,
|
a: Ty<'tcx>,
|
||||||
b: Ty<'tcx>,
|
b: Ty<'tcx>,
|
||||||
r_b: &'tcx ty::Region,
|
r_b: ty::Region<'tcx>,
|
||||||
mt_b: TypeAndMut<'tcx>)
|
mt_b: TypeAndMut<'tcx>)
|
||||||
-> CoerceResult<'tcx>
|
-> CoerceResult<'tcx>
|
||||||
where E: AsCoercionSite
|
where E: AsCoercionSite
|
||||||
|
@ -271,7 +271,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>(
|
|||||||
rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>,
|
rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>,
|
||||||
ty: ty::Ty<'tcx>,
|
ty: ty::Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
scope: region::CodeExtent)
|
scope: region::CodeExtent<'tcx>)
|
||||||
-> Result<(), ErrorReported>
|
-> Result<(), ErrorReported>
|
||||||
{
|
{
|
||||||
debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
|
debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}",
|
||||||
|
@ -781,7 +781,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
check_abi(tcx, span, fn_sig.abi());
|
check_abi(tcx, span, fn_sig.abi());
|
||||||
|
|
||||||
// Compute the fty from point of view of inside fn.
|
// Compute the fty from point of view of inside fn.
|
||||||
let fn_scope = inh.tcx.region_maps().call_site_extent(id, body_id.node_id);
|
let fn_scope = inh.tcx.call_site_extent(id, body_id.node_id);
|
||||||
let fn_sig =
|
let fn_sig =
|
||||||
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs);
|
||||||
let fn_sig =
|
let fn_sig =
|
||||||
@ -1549,7 +1549,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
|
fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
|
||||||
-> Option<&'tcx ty::Region> {
|
-> Option<ty::Region<'tcx>> {
|
||||||
let v = match def {
|
let v = match def {
|
||||||
Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
|
Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
|
||||||
None => infer::MiscVariable(span)
|
None => infer::MiscVariable(span)
|
||||||
@ -1963,7 +1963,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// outlive the region `r`.
|
/// outlive the region `r`.
|
||||||
pub fn register_region_obligation(&self,
|
pub fn register_region_obligation(&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
cause: traits::ObligationCause<'tcx>)
|
cause: traits::ObligationCause<'tcx>)
|
||||||
{
|
{
|
||||||
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
|
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
|
||||||
|
@ -171,15 +171,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
region_bound_pairs: Vec<(&'tcx ty::Region, GenericKind<'tcx>)>,
|
region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
|
||||||
|
|
||||||
free_region_map: FreeRegionMap,
|
free_region_map: FreeRegionMap<'tcx>,
|
||||||
|
|
||||||
// id of innermost fn body id
|
// id of innermost fn body id
|
||||||
body_id: ast::NodeId,
|
body_id: ast::NodeId,
|
||||||
|
|
||||||
// call_site scope of innermost fn
|
// call_site scope of innermost fn
|
||||||
call_site_scope: Option<CodeExtent>,
|
call_site_scope: Option<CodeExtent<'tcx>>,
|
||||||
|
|
||||||
// id of innermost fn or loop
|
// id of innermost fn or loop
|
||||||
repeating_scope: ast::NodeId,
|
repeating_scope: ast::NodeId,
|
||||||
@ -215,7 +215,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<CodeExtent<'tcx>>)
|
||||||
|
-> Option<CodeExtent<'tcx>> {
|
||||||
mem::replace(&mut self.call_site_scope, call_site_scope)
|
mem::replace(&mut self.call_site_scope, call_site_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +277,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let body_id = body.id();
|
let body_id = body.id();
|
||||||
|
|
||||||
let call_site = self.tcx.region_maps().lookup_code_extent(
|
let call_site = self.tcx.intern_code_extent(
|
||||||
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
|
region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id });
|
||||||
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
|
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
|
||||||
|
|
||||||
@ -302,7 +303,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let old_body_id = self.set_body_id(body_id.node_id);
|
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.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span);
|
||||||
self.link_fn_args(self.tcx.region_maps().node_extent(body_id.node_id), &body.arguments);
|
self.link_fn_args(self.tcx.node_extent(body_id.node_id), &body.arguments);
|
||||||
self.visit_body(body);
|
self.visit_body(body);
|
||||||
self.visit_region_obligations(body_id.node_id);
|
self.visit_region_obligations(body_id.node_id);
|
||||||
|
|
||||||
@ -868,7 +869,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// call occurs.
|
// call occurs.
|
||||||
//
|
//
|
||||||
// FIXME(#6268) to support nested method calls, should be callee_id
|
// FIXME(#6268) to support nested method calls, should be callee_id
|
||||||
let callee_scope = self.tcx.region_maps().node_extent(call_expr.id);
|
let callee_scope = self.tcx.node_extent(call_expr.id);
|
||||||
let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
|
let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
|
||||||
|
|
||||||
debug!("callee_region={:?}", callee_region);
|
debug!("callee_region={:?}", callee_region);
|
||||||
@ -982,8 +983,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
pub fn mk_subregion_due_to_dereference(&mut self,
|
pub fn mk_subregion_due_to_dereference(&mut self,
|
||||||
deref_span: Span,
|
deref_span: Span,
|
||||||
minimum_lifetime: &'tcx ty::Region,
|
minimum_lifetime: ty::Region<'tcx>,
|
||||||
maximum_lifetime: &'tcx ty::Region) {
|
maximum_lifetime: ty::Region<'tcx>) {
|
||||||
self.sub_regions(infer::DerefPointer(deref_span),
|
self.sub_regions(infer::DerefPointer(deref_span),
|
||||||
minimum_lifetime, maximum_lifetime)
|
minimum_lifetime, maximum_lifetime)
|
||||||
}
|
}
|
||||||
@ -1021,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
debug!("constrain_index(index_expr=?, indexed_ty={}",
|
debug!("constrain_index(index_expr=?, indexed_ty={}",
|
||||||
self.ty_to_string(indexed_ty));
|
self.ty_to_string(indexed_ty));
|
||||||
|
|
||||||
let r_index_expr = ty::ReScope(self.tcx.region_maps().node_extent(index_expr.id));
|
let r_index_expr = ty::ReScope(self.tcx.node_extent(index_expr.id));
|
||||||
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
|
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
|
||||||
match mt.ty.sty {
|
match mt.ty.sty {
|
||||||
ty::TySlice(_) | ty::TyStr => {
|
ty::TySlice(_) | ty::TyStr => {
|
||||||
@ -1038,7 +1039,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn type_of_node_must_outlive(&mut self,
|
fn type_of_node_must_outlive(&mut self,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
minimum_lifetime: &'tcx ty::Region)
|
minimum_lifetime: ty::Region<'tcx>)
|
||||||
{
|
{
|
||||||
// Try to resolve the type. If we encounter an error, then typeck
|
// Try to resolve the type. If we encounter an error, then typeck
|
||||||
// is going to fail anyway, so just stop here and let typeck
|
// is going to fail anyway, so just stop here and let typeck
|
||||||
@ -1101,7 +1102,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// Computes the guarantors for any ref bindings in a match and
|
/// Computes the guarantors for any ref bindings in a match and
|
||||||
/// then ensures that the lifetime of the resulting pointer is
|
/// then ensures that the lifetime of the resulting pointer is
|
||||||
/// linked to the lifetime of its guarantor (if any).
|
/// linked to the lifetime of its guarantor (if any).
|
||||||
fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) {
|
fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) {
|
||||||
debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
|
debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
|
||||||
let mc = mc::MemCategorizationContext::new(self);
|
let mc = mc::MemCategorizationContext::new(self);
|
||||||
for arg in args {
|
for arg in args {
|
||||||
@ -1167,7 +1168,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// must outlive `callee_scope`.
|
/// must outlive `callee_scope`.
|
||||||
fn link_by_ref(&self,
|
fn link_by_ref(&self,
|
||||||
expr: &hir::Expr,
|
expr: &hir::Expr,
|
||||||
callee_scope: CodeExtent) {
|
callee_scope: CodeExtent<'tcx>) {
|
||||||
debug!("link_by_ref(expr={:?}, callee_scope={:?})",
|
debug!("link_by_ref(expr={:?}, callee_scope={:?})",
|
||||||
expr, callee_scope);
|
expr, callee_scope);
|
||||||
let mc = mc::MemCategorizationContext::new(self);
|
let mc = mc::MemCategorizationContext::new(self);
|
||||||
@ -1200,7 +1201,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// between regions, as explained in `link_reborrowed_region()`.
|
/// between regions, as explained in `link_reborrowed_region()`.
|
||||||
fn link_region(&self,
|
fn link_region(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
borrow_region: &'tcx ty::Region,
|
borrow_region: ty::Region<'tcx>,
|
||||||
borrow_kind: ty::BorrowKind,
|
borrow_kind: ty::BorrowKind,
|
||||||
borrow_cmt: mc::cmt<'tcx>) {
|
borrow_cmt: mc::cmt<'tcx>) {
|
||||||
let mut borrow_cmt = borrow_cmt;
|
let mut borrow_cmt = borrow_cmt;
|
||||||
@ -1297,10 +1298,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
/// recurse and process `ref_cmt` (see case 2 above).
|
/// recurse and process `ref_cmt` (see case 2 above).
|
||||||
fn link_reborrowed_region(&self,
|
fn link_reborrowed_region(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
borrow_region: &'tcx ty::Region,
|
borrow_region: ty::Region<'tcx>,
|
||||||
borrow_kind: ty::BorrowKind,
|
borrow_kind: ty::BorrowKind,
|
||||||
ref_cmt: mc::cmt<'tcx>,
|
ref_cmt: mc::cmt<'tcx>,
|
||||||
ref_region: &'tcx ty::Region,
|
ref_region: ty::Region<'tcx>,
|
||||||
mut ref_kind: ty::BorrowKind,
|
mut ref_kind: ty::BorrowKind,
|
||||||
note: mc::Note)
|
note: mc::Note)
|
||||||
-> Option<(mc::cmt<'tcx>, ty::BorrowKind)>
|
-> Option<(mc::cmt<'tcx>, ty::BorrowKind)>
|
||||||
@ -1411,7 +1412,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
origin: infer::ParameterOrigin,
|
origin: infer::ParameterOrigin,
|
||||||
substs: &Substs<'tcx>,
|
substs: &Substs<'tcx>,
|
||||||
expr_span: Span,
|
expr_span: Span,
|
||||||
expr_region: &'tcx ty::Region) {
|
expr_region: ty::Region<'tcx>) {
|
||||||
debug!("substs_wf_in_scope(substs={:?}, \
|
debug!("substs_wf_in_scope(substs={:?}, \
|
||||||
expr_region={:?}, \
|
expr_region={:?}, \
|
||||||
origin={:?}, \
|
origin={:?}, \
|
||||||
@ -1436,7 +1437,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
pub fn type_must_outlive(&self,
|
pub fn type_must_outlive(&self,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
region: &'tcx ty::Region)
|
region: ty::Region<'tcx>)
|
||||||
{
|
{
|
||||||
let ty = self.resolve_type(ty);
|
let ty = self.resolve_type(ty);
|
||||||
|
|
||||||
@ -1454,7 +1455,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn components_must_outlive(&self,
|
fn components_must_outlive(&self,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
components: Vec<ty::outlives::Component<'tcx>>,
|
components: Vec<ty::outlives::Component<'tcx>>,
|
||||||
region: &'tcx ty::Region)
|
region: ty::Region<'tcx>)
|
||||||
{
|
{
|
||||||
for component in components {
|
for component in components {
|
||||||
let origin = origin.clone();
|
let origin = origin.clone();
|
||||||
@ -1485,7 +1486,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn param_ty_must_outlive(&self,
|
fn param_ty_must_outlive(&self,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
param_ty: ty::ParamTy) {
|
param_ty: ty::ParamTy) {
|
||||||
debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})",
|
debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})",
|
||||||
region, param_ty, origin);
|
region, param_ty, origin);
|
||||||
@ -1497,7 +1498,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn projection_must_outlive(&self,
|
fn projection_must_outlive(&self,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
projection_ty: ty::ProjectionTy<'tcx>)
|
projection_ty: ty::ProjectionTy<'tcx>)
|
||||||
{
|
{
|
||||||
debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
|
debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})",
|
||||||
@ -1622,7 +1623,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn projection_declared_bounds(&self,
|
fn projection_declared_bounds(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
projection_ty: ty::ProjectionTy<'tcx>)
|
projection_ty: ty::ProjectionTy<'tcx>)
|
||||||
-> Vec<&'tcx ty::Region>
|
-> Vec<ty::Region<'tcx>>
|
||||||
{
|
{
|
||||||
// First assemble bounds from where clauses and traits.
|
// First assemble bounds from where clauses and traits.
|
||||||
|
|
||||||
@ -1637,7 +1638,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn projection_bound(&self,
|
fn projection_bound(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
declared_bounds: Vec<&'tcx ty::Region>,
|
declared_bounds: Vec<ty::Region<'tcx>>,
|
||||||
projection_ty: ty::ProjectionTy<'tcx>)
|
projection_ty: ty::ProjectionTy<'tcx>)
|
||||||
-> VerifyBound<'tcx> {
|
-> VerifyBound<'tcx> {
|
||||||
debug!("projection_bound(declared_bounds={:?}, projection_ty={:?})",
|
debug!("projection_bound(declared_bounds={:?}, projection_ty={:?})",
|
||||||
@ -1673,7 +1674,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
|
fn declared_generic_bounds_from_env(&self, generic: GenericKind<'tcx>)
|
||||||
-> Vec<&'tcx ty::Region>
|
-> Vec<ty::Region<'tcx>>
|
||||||
{
|
{
|
||||||
let param_env = &self.parameter_environment;
|
let param_env = &self.parameter_environment;
|
||||||
|
|
||||||
@ -1707,7 +1708,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn declared_projection_bounds_from_trait(&self,
|
fn declared_projection_bounds_from_trait(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
projection_ty: ty::ProjectionTy<'tcx>)
|
projection_ty: ty::ProjectionTy<'tcx>)
|
||||||
-> Vec<&'tcx ty::Region>
|
-> Vec<ty::Region<'tcx>>
|
||||||
{
|
{
|
||||||
debug!("projection_bounds(projection_ty={:?})",
|
debug!("projection_bounds(projection_ty={:?})",
|
||||||
projection_ty);
|
projection_ty);
|
||||||
|
@ -536,7 +536,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> {
|
|||||||
borrow_id: ast::NodeId,
|
borrow_id: ast::NodeId,
|
||||||
_borrow_span: Span,
|
_borrow_span: Span,
|
||||||
cmt: mc::cmt<'tcx>,
|
cmt: mc::cmt<'tcx>,
|
||||||
_loan_region: &'tcx ty::Region,
|
_loan_region: ty::Region<'tcx>,
|
||||||
bk: ty::BorrowKind,
|
bk: ty::BorrowKind,
|
||||||
_loan_cause: euv::LoanCause)
|
_loan_cause: euv::LoanCause)
|
||||||
{
|
{
|
||||||
|
@ -341,7 +341,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
|
let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs);
|
||||||
|
|
||||||
let mut implied_bounds = vec![];
|
let mut implied_bounds = vec![];
|
||||||
let free_id_outlive = fcx.tcx.region_maps().call_site_extent(item.id, body_id.node_id);
|
let free_id_outlive = fcx.tcx.call_site_extent(item.id, body_id.node_id);
|
||||||
this.check_fn_or_method(fcx, item.span, sig, &predicates,
|
this.check_fn_or_method(fcx, item.span, sig, &predicates,
|
||||||
Some(free_id_outlive), &mut implied_bounds);
|
Some(free_id_outlive), &mut implied_bounds);
|
||||||
implied_bounds
|
implied_bounds
|
||||||
@ -429,7 +429,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
predicates: &ty::InstantiatedPredicates<'tcx>,
|
predicates: &ty::InstantiatedPredicates<'tcx>,
|
||||||
free_id_outlive: Option<CodeExtent>,
|
free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||||
implied_bounds: &mut Vec<Ty<'tcx>>)
|
implied_bounds: &mut Vec<Ty<'tcx>>)
|
||||||
{
|
{
|
||||||
let free_substs = &fcx.parameter_environment.free_substs;
|
let free_substs = &fcx.parameter_environment.free_substs;
|
||||||
@ -453,7 +453,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
|
|||||||
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
|
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
|
||||||
method_sig: &hir::MethodSig,
|
method_sig: &hir::MethodSig,
|
||||||
method: &ty::AssociatedItem,
|
method: &ty::AssociatedItem,
|
||||||
free_id_outlive: Option<CodeExtent>,
|
free_id_outlive: Option<CodeExtent<'tcx>>,
|
||||||
self_ty: ty::Ty<'tcx>)
|
self_ty: ty::Ty<'tcx>)
|
||||||
{
|
{
|
||||||
// check that the type of the method's receiver matches the
|
// check that the type of the method's receiver matches the
|
||||||
|
@ -76,7 +76,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
|
|||||||
// early-bound versions of them, visible from the
|
// early-bound versions of them, visible from the
|
||||||
// outside of the function. This is needed by, and
|
// outside of the function. This is needed by, and
|
||||||
// only populated if there are any `impl Trait`.
|
// only populated if there are any `impl Trait`.
|
||||||
free_to_bound_regions: DefIdMap<&'gcx ty::Region>,
|
free_to_bound_regions: DefIdMap<ty::Region<'gcx>>,
|
||||||
|
|
||||||
body: &'gcx hir::Body,
|
body: &'gcx hir::Body,
|
||||||
}
|
}
|
||||||
@ -275,7 +275,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_free_region_map(&mut self) {
|
fn visit_free_region_map(&mut self) {
|
||||||
self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
|
let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map);
|
||||||
|
let free_region_map = free_region_map.expect("all regions in free-region-map are global");
|
||||||
|
self.tables.free_region_map = free_region_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_anon_types(&mut self) {
|
fn visit_anon_types(&mut self) {
|
||||||
@ -522,7 +524,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// FIXME This should be carefully checked
|
// FIXME This should be carefully checked
|
||||||
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
|
// We could use `self.report_error` but it doesn't accept a ty::Region, right now.
|
||||||
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match self.infcx.fully_resolve(&r) {
|
match self.infcx.fully_resolve(&r) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -215,7 +215,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
|
fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>)
|
||||||
-> Option<&'tcx ty::Region> {
|
-> Option<ty::Region<'tcx>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
|
|||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_region(&mut self, r: &'tcx ty::Region) -> bool {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReEarlyBound(data) => {
|
ty::ReEarlyBound(data) => {
|
||||||
self.parameters.push(Parameter::from(data));
|
self.parameters.push(Parameter::from(data));
|
||||||
|
@ -479,7 +479,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
/// context with ambient variance `variance`
|
/// context with ambient variance `variance`
|
||||||
fn add_constraints_from_region(&mut self,
|
fn add_constraints_from_region(&mut self,
|
||||||
generics: &ty::Generics,
|
generics: &ty::Generics,
|
||||||
region: &'tcx ty::Region,
|
region: ty::Region<'tcx>,
|
||||||
variance: VarianceTermPtr<'a>) {
|
variance: VarianceTermPtr<'a>) {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
|
@ -726,7 +726,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
|||||||
if let ty::TyTuple(ts, _) = ty_s.sty {
|
if let ty::TyTuple(ts, _) = ty_s.sty {
|
||||||
for &ty_s in ts {
|
for &ty_s in ts {
|
||||||
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
||||||
if let &ty::Region::ReLateBound(..) = *reg {
|
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
||||||
debug!(" hit an ReLateBound {:?}", reg);
|
debug!(" hit an ReLateBound {:?}", reg);
|
||||||
if let Some(lt) = reg.clean(cx) {
|
if let Some(lt) = reg.clean(cx) {
|
||||||
late_bounds.push(lt);
|
late_bounds.push(lt);
|
||||||
@ -819,7 +819,7 @@ impl Clean<Lifetime> for ty::RegionParameterDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clean<Option<Lifetime>> for ty::Region {
|
impl<'tcx> Clean<Option<Lifetime>> for ty::RegionKind<'tcx> {
|
||||||
fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
|
fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
|
||||||
match *self {
|
match *self {
|
||||||
ty::ReStatic => Some(Lifetime::statik()),
|
ty::ReStatic => Some(Lifetime::statik()),
|
||||||
@ -915,7 +915,7 @@ impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> {
|
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>> {
|
||||||
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
||||||
let ty::OutlivesPredicate(ref a, ref b) = *self;
|
let ty::OutlivesPredicate(ref a, ref b) = *self;
|
||||||
WherePredicate::RegionPredicate {
|
WherePredicate::RegionPredicate {
|
||||||
@ -925,7 +925,7 @@ impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, &'tcx ty::Region> {
|
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, ty::Region<'tcx>> {
|
||||||
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
||||||
let ty::OutlivesPredicate(ref ty, ref lt) = *self;
|
let ty::OutlivesPredicate(ref ty, ref lt) = *self;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
s// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user