From 04e4d426a169a26d498bf22d2c2d01bc7b14fbcd Mon Sep 17 00:00:00 2001 From: Titus Barik Date: Sun, 30 Apr 2017 16:10:31 -0400 Subject: [PATCH 01/17] Rename os variable in bootstrap.py to avoid shadowing os module. --- src/bootstrap/bootstrap.py | 4 ++-- x.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 2bccdef9b0ac4..ad3cf31c1b921 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -414,8 +414,8 @@ def build_triple(self): # The goal here is to come up with the same triple as LLVM would, # at least for the subset of platforms we're willing to target. if ostype == 'Linux': - os = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding) - if os == 'Android': + os_from_sp = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding) + if os_from_sp == 'Android': ostype = 'linux-android' else: ostype = 'unknown-linux-gnu' diff --git a/x.py b/x.py index 8f528889d6020..e277ab98be10f 100755 --- a/x.py +++ b/x.py @@ -9,7 +9,7 @@ # option. This file may not be copied, modified, or distributed # except according to those terms. -# This file is only a "symlink" to boostrap.py, all logic should go there. +# This file is only a "symlink" to bootstrap.py, all logic should go there. import os import sys From eff39b73d1c50edf58a6b30ad02285ba64528cfe Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 27 Mar 2017 23:54:41 -0700 Subject: [PATCH 02/17] On-demandify region mapping --- src/librustc/cfg/construct.rs | 8 ++-- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/infer/error_reporting/mod.rs | 8 ++-- .../infer/region_inference/graphviz.rs | 4 +- src/librustc/infer/region_inference/mod.rs | 4 +- src/librustc/middle/free_region.rs | 4 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/mem_categorization.rs | 4 +- src/librustc/middle/region.rs | 41 +++++++++++++++---- src/librustc/traits/object_safety.rs | 2 +- src/librustc/ty/context.rs | 9 ++-- src/librustc/ty/maps.rs | 15 ++++++- src/librustc/ty/mod.rs | 25 +++++------ src/librustc_borrowck/borrowck/check_loans.rs | 12 +++--- .../borrowck/gather_loans/lifetime.rs | 2 +- .../borrowck/gather_loans/mod.rs | 10 ++--- src/librustc_borrowck/borrowck/mod.rs | 12 +++--- src/librustc_borrowck/borrowck/move_data.rs | 4 +- src/librustc_driver/driver.rs | 11 ++--- src/librustc_mir/build/block.rs | 2 +- src/librustc_mir/build/matches/mod.rs | 2 +- src/librustc_mir/build/mod.rs | 6 +-- src/librustc_mir/build/scope.rs | 4 +- src/librustc_mir/hair/cx/block.rs | 10 ++--- src/librustc_mir/hair/cx/expr.rs | 26 ++++++------ src/librustc_mir/mir_map.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/regionck.rs | 10 ++--- src/librustc_typeck/check/wfcheck.rs | 2 +- 32 files changed, 146 insertions(+), 105 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index d234e408a22dc..8471d2ae4e32b 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -583,11 +583,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { scope_id: ast::NodeId, to_index: CFGIndex) { let mut data = CFGEdgeData { exiting_scopes: vec![] }; - let mut scope = self.tcx.region_maps.node_extent(from_expr.id); - let target_scope = self.tcx.region_maps.node_extent(scope_id); + let mut scope = self.tcx.region_maps().node_extent(from_expr.id); + let target_scope = self.tcx.region_maps().node_extent(scope_id); while scope != target_scope { - data.exiting_scopes.push(scope.node_id(&self.tcx.region_maps)); - scope = self.tcx.region_maps.encl_scope(scope); + data.exiting_scopes.push(scope.node_id(&self.tcx.region_maps())); + scope = self.tcx.region_maps().encl_scope(scope); } self.graph.add_edge(from_index, to_index, data); } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 16af98c203548..d68a62e503031 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -438,7 +438,7 @@ impl<'a, 'tcx> HashStable> for ::middle::region:: hcx: &mut StableHashingContext<'a, 'tcx>, hasher: &mut StableHasher) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - hcx.tcx().region_maps.code_extent_data(*self).hash_stable(hcx, hasher); + hcx.tcx().region_maps().code_extent_data(*self).hash_stable(hcx, hasher); }); } } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index dcbe50de2e9b2..febf6af8763b2 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -123,14 +123,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix) }; - let span = match scope.span(&self.region_maps, &self.hir) { + let span = match scope.span(&self.region_maps(), &self.hir) { Some(s) => s, None => { err.note(&unknown_scope()); return; } }; - let tag = match self.hir.find(scope.node_id(&self.region_maps)) { + let tag = match self.hir.find(scope.node_id(&self.region_maps())) { Some(hir_map::NodeBlock(_)) => "block", Some(hir_map::NodeExpr(expr)) => match expr.node { hir::ExprCall(..) => "call", @@ -150,7 +150,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return; } }; - let scope_decorated_tag = match self.region_maps.code_extent_data(scope) { + let scope_decorated_tag = match self.region_maps().code_extent_data(scope) { region::CodeExtentData::Misc(_) => tag, region::CodeExtentData::CallSiteScope { .. } => { "scope of call-site for function" @@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } }; - let node = fr.scope.node_id(&self.region_maps); + let node = fr.scope.node_id(&self.region_maps()); let unknown; let tag = match self.hir.find(node) { Some(hir_map::NodeBlock(_)) | diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index a67049f72852b..f8d188fcaed38 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -159,7 +159,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { add_node(n2); } - 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(*sup))); }); @@ -245,7 +245,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { fn edges(&self) -> dot::Edges> { debug!("constraint graph has {} edges", self.map.len()); let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); - self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup))); + self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup))); debug!("region graph has {} edges", v.len()); Cow::Owned(v) } diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index fa6775737b57d..19752f3363ad7 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -938,7 +938,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // A "free" region can be interpreted as "some region // at least as big as the block fr.scope_id". So, we can // reasonably compare free regions and scopes: - let r_id = self.tcx.region_maps.nearest_common_ancestor(fr.scope, s_id); + let r_id = self.tcx.region_maps().nearest_common_ancestor(fr.scope, s_id); if r_id == fr.scope { // if the free region's scope `fr.scope_id` is bigger than @@ -957,7 +957,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // subtype of the region corresponding to an inner // block. self.tcx.mk_region(ReScope( - self.tcx.region_maps.nearest_common_ancestor(a_id, b_id))) + self.tcx.region_maps().nearest_common_ancestor(a_id, b_id))) } (&ReFree(a_fr), &ReFree(b_fr)) => { diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 2bfa8dec0bfc7..f622dfc683b60 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -136,10 +136,10 @@ impl FreeRegionMap { true, (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => - tcx.region_maps.is_subscope_of(sub_scope, super_scope), + tcx.region_maps().is_subscope_of(sub_scope, super_scope), (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => - tcx.region_maps.is_subscope_of(sub_scope, fr.scope) || + tcx.region_maps().is_subscope_of(sub_scope, fr.scope) || self.is_static(fr), (&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) => diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 631046788629d..73c8d1db312bb 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1441,7 +1441,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // and must outlive the *call-site* of the function. let fn_ret = self.ir.tcx.liberate_late_bound_regions( - self.ir.tcx.region_maps.call_site_extent(id, body.value.id), + self.ir.tcx.region_maps().call_site_extent(id, body.value.id), &fn_ret); if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 9db6dffb0e8cc..b398255aedeb1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -796,7 +796,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: self.tcx().region_maps.item_extent(fn_body_id), + scope: self.tcx().region_maps().item_extent(fn_body_id), bound_region: ty::BrEnv })); @@ -845,7 +845,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn temporary_scope(&self, id: ast::NodeId) -> (&'tcx ty::Region, &'tcx ty::Region) { let (scope, old_scope) = - self.tcx().region_maps.old_and_new_temporary_scope(id); + self.tcx().region_maps().old_and_new_temporary_scope(id); (self.tcx().mk_region(match scope { Some(scope) => ty::ReScope(scope), None => ty::ReStatic diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0676075930dc3..18e76ff501182 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -16,7 +16,6 @@ //! Most of the documentation on regions can be found in //! `middle/infer/region_inference/README.md` -use dep_graph::DepNode; use hir::map as hir_map; use session::Session; use util::nodemap::{FxHashMap, NodeMap, NodeSet}; @@ -26,11 +25,15 @@ use std::cell::RefCell; use std::collections::hash_map::Entry; use std::fmt; use std::mem; +use std::rc::Rc; use syntax::codemap; use syntax::ast::{self, NodeId}; use syntax_pos::Span; +use ty::TyCtxt; +use ty::maps::Providers; use hir; +use hir::def_id::{CrateNum, LOCAL_CRATE}; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; @@ -44,8 +47,13 @@ impl fmt::Debug for CodeExtent { ty::tls::with_opt(|opt_tcx| { if let Some(tcx) = opt_tcx { - if let Some(data) = tcx.region_maps.code_extents.borrow().get(self.0 as usize) { - write!(f, "/{:?}", data)?; + let region_maps = tcx.region_maps(); + { + let code_extents = ®ion_maps.code_extents; + if let Some(data) = code_extents.borrow().get(self.0 as usize) { + write!(f, "/{:?}", data)?; + } + mem::drop(code_extents); // FIXME why is this necessary? } } Ok(()) @@ -1256,9 +1264,19 @@ impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> { } } -pub fn resolve_crate(sess: &Session, map: &hir_map::Map) -> RegionMaps { - let _task = map.dep_graph.in_task(DepNode::RegionResolveCrate); - let krate = map.krate(); +pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc { + tcx.region_resolve_crate(LOCAL_CRATE) +} + +fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) + -> Rc +{ + debug_assert!(crate_num == LOCAL_CRATE); + + let sess = &tcx.sess; + let hir_map = &tcx.hir; + + let krate = hir_map.krate(); let maps = RegionMaps { code_extents: RefCell::new(vec![]), @@ -1279,7 +1297,7 @@ pub fn resolve_crate(sess: &Session, map: &hir_map::Map) -> RegionMaps { let mut visitor = RegionResolutionVisitor { sess: sess, region_maps: &maps, - map: map, + map: hir_map, cx: Context { root_id: None, parent: ROOT_CODE_EXTENT, @@ -1289,5 +1307,12 @@ pub fn resolve_crate(sess: &Session, map: &hir_map::Map) -> RegionMaps { }; krate.visit_all_item_likes(&mut visitor.as_deep_visitor()); } - return maps; + Rc::new(maps) +} + +pub fn provide(providers: &mut Providers) { + *providers = Providers { + region_resolve_crate, + ..*providers + }; } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 351bde2177cb6..98b502f5608e7 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -207,7 +207,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Search for a predicate like `Self : Sized` amongst the trait bounds. let free_substs = self.construct_free_substs(def_id, - self.region_maps.node_extent(ast::DUMMY_NODE_ID)); + self.region_maps().node_extent(ast::DUMMY_NODE_ID)); let predicates = self.predicates_of(def_id); let predicates = predicates.instantiate(self, free_substs).predicates; elaborate_predicates(self, predicates) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ac7a72e66655f..c6e9822da894e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -51,6 +51,7 @@ use std::mem; use std::ops::Deref; use std::iter; use std::cmp::Ordering; +use std::rc::Rc; use syntax::abi; use syntax::ast::{self, Name, NodeId}; use syntax::attr; @@ -439,8 +440,6 @@ pub struct GlobalCtxt<'tcx> { pub named_region_map: resolve_lifetime::NamedRegionMap, - pub region_maps: RegionMaps, - pub hir: hir_map::Map<'tcx>, pub maps: maps::Maps<'tcx>, @@ -678,6 +677,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { local as usize == global as usize } + pub fn region_maps(self) -> Rc { + self.region_resolve_crate(LOCAL_CRATE) + } + /// Create a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid @@ -690,7 +693,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, hir: hir_map::Map<'tcx>, - region_maps: RegionMaps, lang_items: middle::lang_items::LanguageItems, stability: stability::Index<'tcx>, crate_name: &str, @@ -714,7 +716,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { dep_graph: dep_graph.clone(), types: common_types, named_region_map: named_region_map, - region_maps: region_maps, variance_computed: Cell::new(false), trait_map: resolutions.trait_map, export_map: resolutions.export_map, diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 76398294aca36..abee0ae4ad63f 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -14,6 +14,7 @@ use hir::def::Def; use hir; use middle::const_val; use middle::privacy::AccessLevels; +use middle::region::RegionMaps; use mir; use session::CompileResult; use ty::{self, CrateInherentImpls, Ty, TyCtxt}; @@ -291,6 +292,12 @@ impl<'tcx> QueryDescription for queries::def_span<'tcx> { } } +impl<'tcx> QueryDescription for queries::region_resolve_crate<'tcx> { + fn describe(_: TyCtxt, _: CrateNum) -> String { + format!("resolve crate") + } +} + macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -571,6 +578,8 @@ define_maps! { <'tcx> [] reachable_set: reachability_dep_node(CrateNum) -> Rc, + [] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc, + [] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell>, [] def_symbol_name: SymbolName(DefId) -> ty::SymbolName, @@ -592,6 +601,10 @@ fn reachability_dep_node(_: CrateNum) -> DepNode { DepNode::Reachability } +fn region_resolve_crate_dep_node(_: CrateNum) -> DepNode { + DepNode::RegionResolveCrate +} + fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode { instance.dep_node() } @@ -608,4 +621,4 @@ fn typeck_item_bodies_dep_node(_: CrateNum) -> DepNode { fn const_eval_dep_node((def_id, _): (DefId, &Substs)) -> DepNode { DepNode::ConstEval(def_id) -} \ No newline at end of file +} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8be3e4be7c8b7..c0b340ad54455 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1220,13 +1220,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let impl_def_id = tcx.hir.local_def_id(impl_id); tcx.construct_parameter_environment(impl_item.span, impl_def_id, - tcx.region_maps.item_extent(id)) + tcx.region_maps().item_extent(id)) } hir::ImplItemKind::Method(_, ref body) => { tcx.construct_parameter_environment( impl_item.span, tcx.hir.local_def_id(id), - tcx.region_maps.call_site_extent(id, body.node_id)) + tcx.region_maps().call_site_extent(id, body.node_id)) } } } @@ -1239,7 +1239,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let trait_def_id = tcx.hir.local_def_id(trait_id); tcx.construct_parameter_environment(trait_item.span, trait_def_id, - tcx.region_maps.item_extent(id)) + tcx.region_maps().item_extent(id)) } hir::TraitItemKind::Method(_, ref body) => { // Use call-site for extent (unless this is a @@ -1247,10 +1247,10 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { // to the method id). let extent = if let hir::TraitMethod::Provided(body_id) = *body { // default impl: use call_site extent as free_id_outlive bound. - tcx.region_maps.call_site_extent(id, body_id.node_id) + tcx.region_maps().call_site_extent(id, body_id.node_id) } else { // no default impl: use item extent as free_id_outlive bound. - tcx.region_maps.item_extent(id) + tcx.region_maps().item_extent(id) }; tcx.construct_parameter_environment( trait_item.span, @@ -1268,7 +1268,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( item.span, fn_def_id, - tcx.region_maps.call_site_extent(id, body_id.node_id)) + tcx.region_maps().call_site_extent(id, body_id.node_id)) } hir::ItemEnum(..) | hir::ItemStruct(..) | @@ -1280,13 +1280,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - tcx.region_maps.item_extent(id)) + tcx.region_maps().item_extent(id)) } hir::ItemTrait(..) => { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - tcx.region_maps.item_extent(id)) + tcx.region_maps().item_extent(id)) } _ => { span_bug!(item.span, @@ -1304,7 +1304,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( expr.span, base_def_id, - tcx.region_maps.call_site_extent(id, body.node_id)) + tcx.region_maps().call_site_extent(id, body.node_id)) } else { tcx.empty_parameter_environment() } @@ -2474,7 +2474,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// See `ParameterEnvironment` struct def'n for details. - /// If you were using `free_id: NodeId`, you might try `self.region_maps.item_extent(free_id)` + /// If you were using `free_id: NodeId`, you might try `self.region_maps().item_extent(free_id)` /// for the `free_id_outlive` parameter. (But note that this is not always quite right.) pub fn construct_parameter_environment(self, span: Span, @@ -2521,12 +2521,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { is_freeze_cache: RefCell::new(FxHashMap()), }; - let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps)); + let cause = traits::ObligationCause::misc(span, + free_id_outlive.node_id(&self.region_maps())); traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) } pub fn node_scope_region(self, id: NodeId) -> &'tcx Region { - self.mk_region(ty::ReScope(self.region_maps.node_extent(id))) + self.mk_region(ty::ReScope(self.region_maps().node_extent(id))) } pub fn visit_all_item_likes_in_krate(self, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 3ce31882b86c4..97cf9253038e7 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -239,8 +239,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { //! currently in scope. let tcx = self.tcx(); - self.each_issued_loan(scope.node_id(&tcx.region_maps), |loan| { - if tcx.region_maps.is_subscope_of(scope, loan.kill_scope) { + self.each_issued_loan(scope.node_id(&tcx.region_maps()), |loan| { + if tcx.region_maps().is_subscope_of(scope, loan.kill_scope) { op(loan) } else { true @@ -379,7 +379,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { new_loan); // Should only be called for loans that are in scope at the same time. - assert!(self.tcx().region_maps.scopes_intersect(old_loan.kill_scope, + assert!(self.tcx().region_maps().scopes_intersect(old_loan.kill_scope, new_loan.kill_scope)); self.report_error_if_loan_conflicts_with_restriction( @@ -460,7 +460,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // 3. Where does old loan expire. let previous_end_span = - self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps)) + self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps())) .end_point(); let mut err = match (new_loan.kind, old_loan.kind) { @@ -710,7 +710,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let mut ret = UseOk; self.each_in_scope_loan_affecting_path( - self.tcx().region_maps.node_extent(expr_id), use_path, |loan| { + self.tcx().region_maps().node_extent(expr_id), use_path, |loan| { if !compatible_borrow_kinds(loan.kind, borrow_kind) { ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); false @@ -824,7 +824,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // Check that we don't invalidate any outstanding loans if let Some(loan_path) = opt_loan_path(&assignee_cmt) { - let scope = self.tcx().region_maps.node_extent(assignment_id); + let scope = self.tcx().region_maps().node_extent(assignment_id); self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| { self.report_illegal_mutation(assignment_span, &loan_path, loan); false diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index b921678b495c2..2dfb4f1dd82d3 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } Categorization::Local(local_id) => { self.bccx.tcx.mk_region(ty::ReScope( - self.bccx.tcx.region_maps.var_scope(local_id))) + self.bccx.tcx.region_maps().var_scope(local_id))) } Categorization::StaticItem | Categorization::Deref(.., mc::UnsafePtr(..)) => { diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index cedb9e1cd1cff..41fab1f3a4fc0 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -45,7 +45,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx: bccx, infcx: &infcx, all_loans: Vec::new(), - item_ub: bccx.tcx.region_maps.node_extent(body.node_id), + item_ub: bccx.tcx.region_maps().node_extent(body.node_id), move_data: MoveData::new(), move_error_collector: move_error::MoveErrorCollector::new(), }; @@ -371,7 +371,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { }; debug!("loan_scope = {:?}", loan_scope); - let borrow_scope = self.tcx().region_maps.node_extent(borrow_id); + let borrow_scope = self.tcx().region_maps().node_extent(borrow_id); let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope); debug!("gen_scope = {:?}", gen_scope); @@ -458,7 +458,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { //! notably method arguments, the loan may be introduced only //! later, once it comes into scope. - if self.bccx.tcx.region_maps.is_subscope_of(borrow_scope, loan_scope) { + if self.bccx.tcx.region_maps().is_subscope_of(borrow_scope, loan_scope) { borrow_scope } else { loan_scope @@ -489,11 +489,11 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { //! do not require restrictions and hence do not cause a loan. let lexical_scope = lp.kill_scope(self.bccx.tcx); - let rm = &self.bccx.tcx.region_maps; + let rm = &self.bccx.tcx.region_maps(); if rm.is_subscope_of(lexical_scope, loan_scope) { lexical_scope } else { - assert!(self.bccx.tcx.region_maps.is_subscope_of(loan_scope, lexical_scope)); + assert!(self.bccx.tcx.region_maps().is_subscope_of(loan_scope, lexical_scope)); loan_scope } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 401c878cd4010..2baec7418eb27 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -141,9 +141,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, id_range, all_loans.len()); for (loan_idx, loan) in all_loans.iter().enumerate() { - loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps), loan_idx); + loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps()), loan_idx); loan_dfcx.add_kill(KillFrom::ScopeEnd, - loan.kill_scope.node_id(&tcx.region_maps), loan_idx); + loan.kill_scope.node_id(&tcx.region_maps()), loan_idx); } loan_dfcx.add_kills_from_flow_exits(cfg); loan_dfcx.propagate(cfg, body); @@ -314,10 +314,10 @@ pub fn closure_to_block(closure_id: ast::NodeId, impl<'a, 'tcx> LoanPath<'tcx> { pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent { 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) => { let block_id = closure_to_block(upvar_id.closure_expr_id, tcx); - tcx.region_maps.node_extent(block_id) + tcx.region_maps().node_extent(block_id) } LpDowncast(ref base, _) | LpExtend(ref base, ..) => base.kill_scope(tcx), @@ -966,7 +966,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { fn region_end_span(&self, region: &'tcx ty::Region) -> Option { match *region { ty::ReScope(scope) => { - match scope.span(&self.tcx.region_maps, &self.tcx.hir) { + match scope.span(&self.tcx.region_maps(), &self.tcx.hir) { Some(s) => { Some(s.end_point()) } @@ -1247,7 +1247,7 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \ fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option { match *region { ty::ReScope(scope) => { - match tcx.hir.find(scope.node_id(&tcx.region_maps)) { + match tcx.hir.find(scope.node_id(&tcx.region_maps())) { Some(hir_map::NodeStmt(stmt)) => Some(stmt.span), _ => None } diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 5012969eef905..60d0ab5ff823a 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -548,7 +548,7 @@ impl<'a, 'tcx> MoveData<'tcx> { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { let kill_scope = path.loan_path.kill_scope(tcx); 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(&tcx.region_maps()), KillFrom::ScopeEnd, dfcx_moves); } LpExtend(..) => {} @@ -563,7 +563,7 @@ impl<'a, 'tcx> MoveData<'tcx> { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { let kill_scope = lp.kill_scope(tcx); dfcx_assign.add_kill(KillFrom::ScopeEnd, - kill_scope.node_id(&tcx.region_maps), + kill_scope.node_id(&tcx.region_maps()), assignment_index); } LpExtend(..) => { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index dab2a0758a217..bb3bda6827798 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -874,10 +874,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, })); sess.derive_registrar_fn.set(derive_registrar::find(&hir_map)); - let region_map = time(time_passes, - "region resolution", - || middle::region::resolve_crate(sess, &hir_map)); - time(time_passes, "loop checking", || loops::check_crate(sess, &hir_map)); @@ -898,6 +894,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, ty::provide(&mut local_providers); reachable::provide(&mut local_providers); rustc_const_eval::provide(&mut local_providers); + middle::region::provide(&mut local_providers); let mut extern_providers = ty::maps::Providers::default(); cstore::provide(&mut extern_providers); @@ -914,7 +911,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, resolutions, named_region_map, hir_map, - region_map, lang_items, index, name, @@ -923,10 +919,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, time(time_passes, "compute_incremental_hashes_map", || rustc_incremental::compute_incremental_hashes_map(tcx)); + time(time_passes, "load_dep_graph", || rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map)); + time(time_passes, + "region resolution", + || middle::region::resolve_crate(tcx)); + time(time_passes, "stability index", || { tcx.stability.borrow_mut().build(tcx) }); diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 7739766182cfa..f99f41c633e9f 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let_extent_stack.push(remainder_scope); // Declare the bindings, which may create a visibility scope. - let remainder_span = remainder_scope.span(&tcx.region_maps, &tcx.hir); + let remainder_span = remainder_scope.span(&tcx.region_maps(), &tcx.hir); let remainder_span = remainder_span.unwrap_or(span); let scope = this.declare_bindings(None, remainder_span, &pattern); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index ddeec1fe6d0ba..7c12c9ef5fadd 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span) { let local_id = self.var_indices[&var]; let var_ty = self.local_decls[local_id].ty; - let extent = self.hir.tcx().region_maps.var_scope(var); + let extent = self.hir.tcx().region_maps().var_scope(var); self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty); } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index ef3fa23500b34..2afaaaf087854 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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 call_site_extent = - tcx.region_maps.lookup_code_extent( + tcx.region_maps().lookup_code_extent( CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id }); let arg_extent = - tcx.region_maps.lookup_code_extent( + tcx.region_maps().lookup_code_extent( CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id }); let mut block = START_BLOCK; unpack!(block = builder.in_scope(call_site_extent, block, |builder| { @@ -203,7 +203,7 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, let span = tcx.hir.span(tcx.hir.body_owner(body_id)); let mut builder = Builder::new(hir, span, 0, ty); - let extent = tcx.region_maps.temporary_scope(ast_expr.id) + let extent = tcx.region_maps().temporary_scope(ast_expr.id) .unwrap_or(ROOT_CODE_EXTENT); let mut block = START_BLOCK; let _ = builder.in_scope(extent, block, |builder| { diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 95b20560c62a1..2a024454ecb4a 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -411,7 +411,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // The outermost scope (`scopes[0]`) will be the `CallSiteScope`. // We want `scopes[1]`, which is the `ParameterScope`. assert!(self.scopes.len() >= 2); - assert!(match self.hir.tcx().region_maps.code_extent_data(self.scopes[1].extent) { + assert!(match self.hir.tcx().region_maps().code_extent_data(self.scopes[1].extent) { CodeExtentData::ParameterScope { .. } => true, _ => false, }); @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { scope.needs_cleanup = true; } let tcx = self.hir.tcx(); - let extent_span = extent.span(&tcx.region_maps, &tcx.hir).unwrap(); + let extent_span = extent.span(&tcx.region_maps(), &tcx.hir).unwrap(); // Attribute scope exit drops to scope's closing brace let scope_end = Span { lo: extent_span.hi, .. extent_span}; scope.drops.push(DropData { diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index d2465331df353..1be07fba2b0cd 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -24,7 +24,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { let stmts = mirror_stmts(cx, self.id, &*self.stmts); Block { targeted_by_break: self.targeted_by_break, - extent: cx.tcx.region_maps.node_extent(self.id), + extent: cx.tcx.region_maps().node_extent(self.id), span: self.span, stmts: stmts, expr: self.expr.to_ref(), @@ -44,7 +44,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, result.push(StmtRef::Mirror(Box::new(Stmt { span: stmt.span, kind: StmtKind::Expr { - scope: cx.tcx.region_maps.node_extent(id), + scope: cx.tcx.region_maps().node_extent(id), expr: expr.to_ref(), }, }))) @@ -60,14 +60,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, first_statement_index: index as u32, }); let remainder_extent = - cx.tcx.region_maps.lookup_code_extent(remainder_extent); + cx.tcx.region_maps().lookup_code_extent(remainder_extent); let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat); result.push(StmtRef::Mirror(Box::new(Stmt { span: stmt.span, kind: StmtKind::Let { remainder_scope: remainder_extent, - init_scope: cx.tcx.region_maps.node_extent(id), + init_scope: cx.tcx.region_maps().node_extent(id), pattern: pattern, initializer: local.init.to_ref(), }, @@ -84,7 +84,7 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { let block_ty = cx.tables().node_id_to_type(block.id); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(block.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(block.id); let expr = Expr { ty: block_ty, temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 7b267fa276b18..ae63828f0ac76 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -26,8 +26,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(self.id); - let expr_extent = cx.tcx.region_maps.node_extent(self.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(self.id); + let expr_extent = cx.tcx.region_maps().node_extent(self.id); debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span); @@ -216,7 +216,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; // Finally, create a destruction scope, if any. - if let Some(extent) = cx.tcx.region_maps.opt_destruction_extent(self.id) { + if let Some(extent) = cx.tcx.region_maps().opt_destruction_extent(self.id) { expr = Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -238,7 +238,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { let expr_ty = cx.tables().expr_ty(expr); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); let kind = match expr.node { // Here comes the interesting stuff: @@ -610,7 +610,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, match dest.target_id { hir::ScopeTarget::Block(target_id) | hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break { - label: cx.tcx.region_maps.node_extent(target_id), + label: cx.tcx.region_maps().node_extent(target_id), value: value.to_ref(), }, hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) => @@ -621,7 +621,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, match dest.target_id { hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"), hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue { - label: cx.tcx.region_maps.node_extent(loop_id), + label: cx.tcx.region_maps().node_extent(loop_id), }, hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) => bug!("invalid loop id for continue: {}", err) @@ -686,7 +686,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprBox(ref value) => { ExprKind::Box { value: value.to_ref(), - value_extents: cx.tcx.region_maps.node_extent(value.id), + value_extents: cx.tcx.region_maps().node_extent(value.id), } } hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() }, @@ -707,7 +707,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, method_call: ty::MethodCall) -> Expr<'tcx> { let callee = cx.tables().method_map[&method_call]; - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -791,7 +791,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); match def { Def::Local(def_id) => { @@ -828,7 +828,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // signature will be &self or &mut self and hence will // have a bound region with number 0 let region = ty::Region::ReFree(ty::FreeRegion { - scope: cx.tcx.region_maps.node_extent(body_id), + scope: cx.tcx.region_maps().node_extent(body_id), bound_region: ty::BoundRegion::BrAnon(0), }); let region = cx.tcx.mk_region(region); @@ -979,7 +979,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, PassArgs::ByRef => { let region = cx.tcx.node_scope_region(expr.id); let (temp_lifetime, was_shrunk) = - cx.tcx.region_maps.temporary_scope2(expr.id); + cx.tcx.region_maps().temporary_scope2(expr.id); argrefs.extend(args.iter() .map(|arg| { let arg_ty = cx.tables().expr_ty_adjusted(arg); @@ -1031,7 +1031,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args); let ref_expr = Expr { temp_lifetime: temp_lifetime, @@ -1056,7 +1056,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_expr_id: closure_expr.id, }; let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap(); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(closure_expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(closure_expr.id); let var_ty = cx.tables().node_id_to_type(id_var); let captured_var = Expr { temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 77f5c8ff124df..d8604f65dff92 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -253,7 +253,7 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id); let region = ty::Region::ReFree(ty::FreeRegion { - scope: tcx.region_maps.item_extent(body_id.node_id), + scope: tcx.region_maps().item_extent(body_id.node_id), bound_region: ty::BoundRegion::BrEnv, }); let region = tcx.mk_region(region); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 92f80a3607b6e..eb897d10d2589 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -133,7 +133,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Some(&rl::Region::Free(scope, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: scope.to_code_extent(&tcx.region_maps), + scope: scope.to_code_extent(&tcx.region_maps()), bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name) })) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 78176b155691c..c74d71babc2df 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type); - let extent = self.tcx.region_maps.call_site_extent(expr.id, body.value.id); + let extent = self.tcx.region_maps().call_site_extent(expr.id, body.value.id); let fn_sig = self.tcx.liberate_late_bound_regions(extent, &sig); let fn_sig = self.inh.normalize_associated_types_in(body.value.span, body.value.id, &fn_sig); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 8d26f00742975..4c9874cfa5a07 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -278,7 +278,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( ty, scope); - let parent_scope = match rcx.tcx.region_maps.opt_encl_scope(scope) { + let parent_scope = match rcx.tcx.region_maps().opt_encl_scope(scope) { Some(parent_scope) => parent_scope, // If no enclosing scope, then it must be the root scope // which cannot be outlived. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8752f82f7abf2..e40d8f6cafca3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -781,7 +781,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_abi(tcx, span, fn_sig.abi()); // Compute the fty from point of view of inside fn. - let fn_scope = inh.tcx.region_maps.call_site_extent(id, body_id.node_id); + let fn_scope = inh.tcx.region_maps().call_site_extent(id, body_id.node_id); let fn_sig = fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs); let fn_sig = diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 3508ddbe5f489..16297709b194a 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let body_id = body.id(); - let call_site = self.tcx.region_maps.lookup_code_extent( + let call_site = self.tcx.region_maps().lookup_code_extent( region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }); let old_call_site_scope = self.set_call_site_scope(Some(call_site)); @@ -302,7 +302,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let old_body_id = self.set_body_id(body_id.node_id); self.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span); - self.link_fn_args(self.tcx.region_maps.node_extent(body_id.node_id), &body.arguments); + self.link_fn_args(self.tcx.region_maps().node_extent(body_id.node_id), &body.arguments); self.visit_body(body); self.visit_region_obligations(body_id.node_id); @@ -450,7 +450,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // that the lifetime of any regions that appear in a // variable's type enclose at least the variable's scope. - let var_scope = tcx.region_maps.var_scope(id); + let var_scope = tcx.region_maps().var_scope(id); let var_region = self.tcx.mk_region(ty::ReScope(var_scope)); let origin = infer::BindingTypeIsNotValidAtDecl(span); @@ -868,7 +868,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // call occurs. // // FIXME(#6268) to support nested method calls, should be callee_id - let callee_scope = self.tcx.region_maps.node_extent(call_expr.id); + let callee_scope = self.tcx.region_maps().node_extent(call_expr.id); let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope)); debug!("callee_region={:?}", callee_region); @@ -1021,7 +1021,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("constrain_index(index_expr=?, indexed_ty={}", self.ty_to_string(indexed_ty)); - let r_index_expr = ty::ReScope(self.tcx.region_maps.node_extent(index_expr.id)); + let r_index_expr = ty::ReScope(self.tcx.region_maps().node_extent(index_expr.id)); if let ty::TyRef(r_ptr, mt) = indexed_ty.sty { match mt.ty.sty { ty::TySlice(_) | ty::TyStr => { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 503212f2c970e..08024c9e9e691 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -341,7 +341,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs); let mut implied_bounds = vec![]; - let free_id_outlive = fcx.tcx.region_maps.call_site_extent(item.id, body_id.node_id); + let free_id_outlive = fcx.tcx.region_maps().call_site_extent(item.id, body_id.node_id); this.check_fn_or_method(fcx, item.span, sig, &predicates, free_id_outlive, &mut implied_bounds); implied_bounds From 119c38ea91ffe421a3331a600a2d18618f82bf4f Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Tue, 4 Apr 2017 23:46:59 -0700 Subject: [PATCH 03/17] Remove RefCells from RegionMaps --- src/librustc/middle/region.rs | 104 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 18e76ff501182..0c35d38d68498 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -21,7 +21,6 @@ use session::Session; use util::nodemap::{FxHashMap, NodeMap, NodeSet}; use ty; -use std::cell::RefCell; use std::collections::hash_map::Entry; use std::fmt; use std::mem; @@ -50,7 +49,7 @@ impl fmt::Debug for CodeExtent { let region_maps = tcx.region_maps(); { let code_extents = ®ion_maps.code_extents; - if let Some(data) = code_extents.borrow().get(self.0 as usize) { + if let Some(data) = code_extents.get(self.0 as usize) { write!(f, "/{:?}", data)?; } mem::drop(code_extents); // FIXME why is this necessary? @@ -258,19 +257,19 @@ impl CodeExtent { /// The region maps encode information about region relationships. pub struct RegionMaps { - code_extents: RefCell>, - code_extent_interner: RefCell>, + code_extents: Vec, + code_extent_interner: FxHashMap, /// `scope_map` maps from a scope id to the enclosing scope id; /// this is usually corresponding to the lexical nesting, though /// in the case of closures the parent scope is the innermost /// conditional expression or repeating block. (Note that the /// enclosing scope id for the block associated with a closure is /// the closure itself.) - scope_map: RefCell>, + scope_map: Vec, /// `var_map` maps from a variable or binding id to the block in /// which that variable is declared. - var_map: RefCell>, + var_map: NodeMap, /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is /// larger than the default. The map goes from the expression id @@ -278,14 +277,14 @@ pub struct RegionMaps { /// table, the appropriate cleanup scope is the innermost /// enclosing statement, conditional expression, or repeating /// block (see `terminating_scopes`). - rvalue_scopes: RefCell>, + rvalue_scopes: NodeMap, /// Records the value of rvalue scopes before they were shrunk by /// #36082, for error reporting. /// /// FIXME: this should be temporary. Remove this by 1.18.0 or /// so. - shrunk_rvalue_scopes: RefCell>, + shrunk_rvalue_scopes: NodeMap, /// Encodes the hierarchy of fn bodies. Every fn body (including /// closures) forms its own distinct region hierarchy, rooted in @@ -297,7 +296,7 @@ pub struct RegionMaps { /// closure defined by that fn. See the "Modeling closures" /// section of the README in infer::region_inference for /// more details. - fn_tree: RefCell>, + fn_tree: NodeMap, } #[derive(Debug, Copy, Clone)] @@ -321,7 +320,7 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> { sess: &'a Session, // Generated maps: - region_maps: &'a RegionMaps, + region_maps: &'a mut RegionMaps, cx: Context, @@ -354,11 +353,11 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> { impl RegionMaps { /// create a bogus code extent for the regions in astencode types. Nobody /// really cares about the contents of these. - pub fn bogus_code_extent(&self, e: CodeExtentData) -> CodeExtent { + pub fn bogus_code_extent(&mut self, e: CodeExtentData) -> CodeExtent { self.intern_code_extent(e, DUMMY_CODE_EXTENT) } pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent { - match self.code_extent_interner.borrow().get(&e) { + match self.code_extent_interner.get(&e) { Some(&d) => d, None => bug!("unknown code extent {:?}", e) } @@ -375,12 +374,12 @@ impl RegionMaps { self.lookup_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id }) } pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option { - self.code_extent_interner.borrow().get(&CodeExtentData::DestructionScope(n)).cloned() + self.code_extent_interner.get(&CodeExtentData::DestructionScope(n)).cloned() } - pub fn intern_code_extent(&self, + pub fn intern_code_extent(&mut self, e: CodeExtentData, parent: CodeExtent) -> CodeExtent { - match self.code_extent_interner.borrow_mut().entry(e) { + match self.code_extent_interner.entry(e) { Entry::Occupied(o) => { // this can happen when the bogus code extents from tydecode // have (bogus) NodeId-s that overlap items created during @@ -392,37 +391,37 @@ impl RegionMaps { info!("CodeExtent({}) = {:?} [parent={}] BOGUS!", idx.0, e, parent.0); } else { - assert_eq!(self.scope_map.borrow()[idx.0 as usize], + assert_eq!(self.scope_map[idx.0 as usize], DUMMY_CODE_EXTENT); info!("CodeExtent({}) = {:?} [parent={}] RECLAIMED!", idx.0, e, parent.0); - self.scope_map.borrow_mut()[idx.0 as usize] = parent; + self.scope_map[idx.0 as usize] = parent; } idx } Entry::Vacant(v) => { - if self.code_extents.borrow().len() > 0xffffffffusize { + if self.code_extents.len() > 0xffffffffusize { bug!() // should pass a sess, // but this isn't the only place } - let idx = CodeExtent(self.code_extents.borrow().len() as u32); + let idx = CodeExtent(self.code_extents.len() as u32); debug!("CodeExtent({}) = {:?} [parent={}]", idx.0, e, parent.0); - self.code_extents.borrow_mut().push(e); - self.scope_map.borrow_mut().push(parent); + self.code_extents.push(e); + self.scope_map.push(parent); *v.insert(idx) } } } - pub fn intern_node(&self, + pub fn intern_node(&mut self, n: ast::NodeId, parent: CodeExtent) -> CodeExtent { self.intern_code_extent(CodeExtentData::Misc(n), parent) } pub fn code_extent_data(&self, e: CodeExtent) -> CodeExtentData { - self.code_extents.borrow()[e.0 as usize] + self.code_extents[e.0 as usize] } pub fn each_encl_scope(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) { - for child_id in 1..self.code_extents.borrow().len() { + 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) @@ -430,7 +429,7 @@ impl RegionMaps { } } pub fn each_var_scope(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) { - for (child, parent) in self.var_map.borrow().iter() { + for (child, parent) in self.var_map.iter() { e(child, parent) } } @@ -438,45 +437,44 @@ impl RegionMaps { /// Records that `sub_fn` is defined within `sup_fn`. These ids /// should be the id of the block that is the fn body, which is /// also the root of the region hierarchy for that fn. - fn record_fn_parent(&self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) { + fn record_fn_parent(&mut self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) { debug!("record_fn_parent(sub_fn={:?}, sup_fn={:?})", sub_fn, sup_fn); assert!(sub_fn != sup_fn); - let previous = self.fn_tree.borrow_mut().insert(sub_fn, sup_fn); + let previous = self.fn_tree.insert(sub_fn, sup_fn); assert!(previous.is_none()); } fn fn_is_enclosed_by(&self, mut sub_fn: ast::NodeId, sup_fn: ast::NodeId) -> bool { - let fn_tree = self.fn_tree.borrow(); loop { if sub_fn == sup_fn { return true; } - match fn_tree.get(&sub_fn) { + match self.fn_tree.get(&sub_fn) { Some(&s) => { sub_fn = s; } None => { return false; } } } } - fn record_var_scope(&self, var: ast::NodeId, lifetime: CodeExtent) { + fn record_var_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) { debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime); assert!(var != lifetime.node_id(self)); - self.var_map.borrow_mut().insert(var, lifetime); + self.var_map.insert(var, lifetime); } - fn record_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) { + fn record_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) { debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime); assert!(var != lifetime.node_id(self)); - self.rvalue_scopes.borrow_mut().insert(var, lifetime); + self.rvalue_scopes.insert(var, lifetime); } - fn record_shrunk_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) { + fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) { debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime); assert!(var != lifetime.node_id(self)); - self.shrunk_rvalue_scopes.borrow_mut().insert(var, lifetime); + self.shrunk_rvalue_scopes.insert(var, lifetime); } pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map.borrow()[id.0 as usize].into_option() + self.scope_map[id.0 as usize].into_option() } #[allow(dead_code)] // used in cfg @@ -487,7 +485,7 @@ impl RegionMaps { /// Returns the lifetime of the local variable `var_id` pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent { - match self.var_map.borrow().get(&var_id) { + match self.var_map.get(&var_id) { Some(&r) => r, None => { bug!("no enclosing scope for id {:?}", var_id); } } @@ -495,7 +493,7 @@ impl RegionMaps { pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option, bool) { let temporary_scope = self.temporary_scope(expr_id); - let was_shrunk = match self.shrunk_rvalue_scopes.borrow().get(&expr_id) { + let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) { Some(&s) => { info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})", expr_id, temporary_scope, s); @@ -513,7 +511,7 @@ impl RegionMaps { let temporary_scope = self.temporary_scope(expr_id); (temporary_scope, self.shrunk_rvalue_scopes - .borrow().get(&expr_id).cloned() + .get(&expr_id).cloned() .or(temporary_scope)) } @@ -521,13 +519,13 @@ impl RegionMaps { //! Returns the scope when temp created by expr_id will be cleaned up // check for a designated rvalue scope - if let Some(&s) = self.rvalue_scopes.borrow().get(&expr_id) { + if let Some(&s) = self.rvalue_scopes.get(&expr_id) { debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s); return Some(s); } - let scope_map : &[CodeExtent] = &self.scope_map.borrow(); - let code_extents: &[CodeExtentData] = &self.code_extents.borrow(); + let scope_map : &[CodeExtent] = &self.scope_map; + let code_extents: &[CodeExtentData] = &self.code_extents; // else, locate the innermost terminating scope // if there's one. Static items, for instance, won't @@ -601,7 +599,7 @@ impl RegionMaps { let mut a_vec: Vec = vec![]; let mut b_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32]; let mut b_vec: Vec = vec![]; - let scope_map : &[CodeExtent] = &self.scope_map.borrow(); + let scope_map : &[CodeExtent] = &self.scope_map; let a_ancestors = ancestors_of(scope_map, scope_a, &mut a_buf, &mut a_vec); let b_ancestors = ancestors_of(scope_map, @@ -1216,7 +1214,7 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { // functions put their destruction scopes *inside* their parameter // scopes. let scope = CodeExtentData::DestructionScope(id); - if !self.region_maps.code_extent_interner.borrow().contains_key(&scope) { + if !self.region_maps.code_extent_interner.contains_key(&scope) { self.region_maps.intern_code_extent(scope, ROOT_CODE_EXTENT); } } @@ -1278,14 +1276,14 @@ fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateN let krate = hir_map.krate(); - let maps = RegionMaps { - code_extents: RefCell::new(vec![]), - code_extent_interner: RefCell::new(FxHashMap()), - scope_map: RefCell::new(vec![]), - var_map: RefCell::new(NodeMap()), - rvalue_scopes: RefCell::new(NodeMap()), - shrunk_rvalue_scopes: RefCell::new(NodeMap()), - fn_tree: RefCell::new(NodeMap()), + let mut maps = RegionMaps { + code_extents: vec![], + code_extent_interner: FxHashMap(), + scope_map: vec![], + var_map: NodeMap(), + rvalue_scopes: NodeMap(), + shrunk_rvalue_scopes: NodeMap(), + fn_tree: NodeMap(), }; let root_extent = maps.bogus_code_extent( CodeExtentData::DestructionScope(ast::DUMMY_NODE_ID)); @@ -1296,7 +1294,7 @@ fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateN { let mut visitor = RegionResolutionVisitor { sess: sess, - region_maps: &maps, + region_maps: &mut maps, map: hir_map, cx: Context { root_id: None, From 55d6066c05fea0e0787ac5add67e26283468116c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 19 Apr 2017 16:45:07 -0400 Subject: [PATCH 04/17] remove ROOT_CODE_EXTENT and DUMMY_CODE_EXTENT Instead, thread around `Option` where applicable. --- src/librustc/infer/error_reporting/mod.rs | 4 +- src/librustc/infer/region_inference/mod.rs | 23 +-- src/librustc/middle/free_region.rs | 15 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/region.rs | 143 +++++++----------- src/librustc/traits/object_safety.rs | 3 +- src/librustc/traits/specialize/mod.rs | 3 +- src/librustc/ty/fold.rs | 2 +- src/librustc/ty/layout.rs | 3 +- src/librustc/ty/mod.rs | 55 +++---- src/librustc/ty/sty.rs | 6 +- .../borrowck/gather_loans/mod.rs | 2 +- src/librustc_mir/build/mod.rs | 10 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/mir_map.rs | 2 +- src/librustc_mir/shim.rs | 4 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 6 +- 22 files changed, 137 insertions(+), 158 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index febf6af8763b2..10712f5ec7047 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -69,6 +69,7 @@ use traits::{ObligationCause, ObligationCauseCode}; use ty::{self, TyCtxt, TypeFoldable}; use ty::{Region, Issue32330}; use ty::error::TypeError; +use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; use errors::{DiagnosticBuilder, DiagnosticStyledString}; @@ -183,7 +184,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } }; - let node = fr.scope.node_id(&self.region_maps()); + let node = fr.scope.map(|s| s.node_id(&self.region_maps())) + .unwrap_or(DUMMY_NODE_ID); let unknown; let tag = match self.hir.find(node) { Some(hir_map::NodeBlock(_)) | diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 19752f3363ad7..f9aab59acaf6c 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -938,18 +938,19 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // A "free" region can be interpreted as "some region // at least as big as the block fr.scope_id". So, we can // reasonably compare free regions and scopes: - let r_id = self.tcx.region_maps().nearest_common_ancestor(fr.scope, s_id); - - if r_id == fr.scope { - // if the free region's scope `fr.scope_id` is bigger than - // the scope region `s_id`, then the LUB is the free - // region itself: - self.tcx.mk_region(ReFree(fr)) - } else { - // otherwise, we don't know what the free region is, - // so we must conservatively say the LUB is static: - self.tcx.types.re_static + if let Some(fr_scope) = fr.scope { + let r_id = self.tcx.region_maps().nearest_common_ancestor(fr_scope, s_id); + if r_id == fr_scope { + // if the free region's scope `fr.scope_id` is bigger than + // the scope region `s_id`, then the LUB is the free + // region itself: + return self.tcx.mk_region(ReFree(fr)); + } } + + // otherwise, we don't know what the free region is, + // so we must conservatively say the LUB is static: + self.tcx.types.re_static } (&ReScope(a_id), &ReScope(b_id)) => { diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index f622dfc683b60..9701595a9d872 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -138,9 +138,14 @@ impl FreeRegionMap { (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => tcx.region_maps().is_subscope_of(sub_scope, super_scope), - (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => - tcx.region_maps().is_subscope_of(sub_scope, fr.scope) || - self.is_static(fr), + (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { + // 1. It is safe to unwrap `fr.scope` because we + // should only ever wind up comparing against + // `ReScope` in the context of a method or fn + // body, where `fr.scope` should be `Some`. + tcx.region_maps().is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || + self.is_static(fr) + } (&ty::ReFree(sub_fr), &ty::ReFree(super_fr)) => self.sub_free_region(sub_fr, super_fr), @@ -166,9 +171,7 @@ impl FreeRegionMap { #[cfg(test)] fn free_region(index: u32) -> FreeRegion { - use middle::region::DUMMY_CODE_EXTENT; - FreeRegion { scope: DUMMY_CODE_EXTENT, - bound_region: ty::BoundRegion::BrAnon(index) } + FreeRegion { scope: None, bound_region: ty::BoundRegion::BrAnon(index) } } #[test] diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 73c8d1db312bb..508dfe9cfcd8b 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1441,7 +1441,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // and must outlive the *call-site* of the function. let fn_ret = self.ir.tcx.liberate_late_bound_regions( - self.ir.tcx.region_maps().call_site_extent(id, body.value.id), + Some(self.ir.tcx.region_maps().call_site_extent(id, body.value.id)), &fn_ret); if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index b398255aedeb1..92777bb160463 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -796,7 +796,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: self.tcx().region_maps().item_extent(fn_body_id), + scope: Some(self.tcx().region_maps().item_extent(fn_body_id)), bound_region: ty::BrEnv })); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0c35d38d68498..e381a904478b7 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -34,7 +34,7 @@ use ty::maps::Providers; use hir; use hir::def_id::{CrateNum, LOCAL_CRATE}; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; -use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; +use hir::{Body, Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)] @@ -62,12 +62,6 @@ impl fmt::Debug for CodeExtent { } } -/// The root of everything. I should be using NonZero or profiling -/// instead of this (probably). -pub const ROOT_CODE_EXTENT : CodeExtent = CodeExtent(0); -/// A placeholder used in trans to stand for real code extents -pub const DUMMY_CODE_EXTENT : CodeExtent = CodeExtent(1); - /// CodeExtent represents a statically-describable extent that can be /// used to bound the lifetime/region for values. /// @@ -209,14 +203,6 @@ impl CodeExtentData { } impl CodeExtent { - #[inline] - fn into_option(self) -> Option { - if self == ROOT_CODE_EXTENT { - None - } else { - Some(self) - } - } pub fn node_id(&self, region_maps: &RegionMaps) -> ast::NodeId { region_maps.code_extent_data(*self).node_id() } @@ -265,7 +251,7 @@ pub struct RegionMaps { /// conditional expression or repeating block. (Note that the /// enclosing scope id for the block associated with a closure is /// the closure itself.) - scope_map: Vec, + scope_map: Vec>, /// `var_map` maps from a variable or binding id to the block in /// which that variable is declared. @@ -310,10 +296,10 @@ pub struct Context { root_id: Option, /// the scope that contains any new variables declared - var_parent: CodeExtent, + var_parent: Option, /// region parent of expressions etc - parent: CodeExtent + parent: Option, } struct RegionResolutionVisitor<'hir: 'a, 'a> { @@ -351,11 +337,6 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> { impl RegionMaps { - /// create a bogus code extent for the regions in astencode types. Nobody - /// really cares about the contents of these. - pub fn bogus_code_extent(&mut self, e: CodeExtentData) -> CodeExtent { - self.intern_code_extent(e, DUMMY_CODE_EXTENT) - } pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent { match self.code_extent_interner.get(&e) { Some(&d) => d, @@ -378,26 +359,10 @@ impl RegionMaps { } pub fn intern_code_extent(&mut self, e: CodeExtentData, - parent: CodeExtent) -> CodeExtent { + parent: Option) -> CodeExtent { match self.code_extent_interner.entry(e) { - Entry::Occupied(o) => { - // this can happen when the bogus code extents from tydecode - // have (bogus) NodeId-s that overlap items created during - // inlining. - // We probably shouldn't be creating bogus code extents - // though. - let idx = *o.get(); - if parent == DUMMY_CODE_EXTENT { - info!("CodeExtent({}) = {:?} [parent={}] BOGUS!", - idx.0, e, parent.0); - } else { - assert_eq!(self.scope_map[idx.0 as usize], - DUMMY_CODE_EXTENT); - info!("CodeExtent({}) = {:?} [parent={}] RECLAIMED!", - idx.0, e, parent.0); - self.scope_map[idx.0 as usize] = parent; - } - idx + Entry::Occupied(_) => { + bug!("intern_code_extent: already exists") } Entry::Vacant(v) => { if self.code_extents.len() > 0xffffffffusize { @@ -405,7 +370,7 @@ impl RegionMaps { // but this isn't the only place } let idx = CodeExtent(self.code_extents.len() as u32); - debug!("CodeExtent({}) = {:?} [parent={}]", idx.0, e, parent.0); + debug!("CodeExtent({:?}) = {:?} [parent={:?}]", idx, e, parent); self.code_extents.push(e); self.scope_map.push(parent); *v.insert(idx) @@ -414,7 +379,7 @@ impl RegionMaps { } pub fn intern_node(&mut self, n: ast::NodeId, - parent: CodeExtent) -> CodeExtent { + parent: Option) -> CodeExtent { self.intern_code_extent(CodeExtentData::Misc(n), parent) } pub fn code_extent_data(&self, e: CodeExtent) -> CodeExtentData { @@ -474,7 +439,7 @@ impl RegionMaps { pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map[id.0 as usize].into_option() + self.scope_map[id.0 as usize] } #[allow(dead_code)] // used in cfg @@ -524,7 +489,7 @@ impl RegionMaps { return Some(s); } - let scope_map : &[CodeExtent] = &self.scope_map; + let scope_map : &[Option] = &self.scope_map; let code_extents: &[CodeExtentData] = &self.code_extents; // else, locate the innermost terminating scope @@ -533,7 +498,7 @@ impl RegionMaps { // returned. let mut id = self.node_extent(expr_id); - while let Some(p) = scope_map[id.0 as usize].into_option() { + while let Some(p) = scope_map[id.0 as usize] { match code_extents[p.0 as usize] { CodeExtentData::DestructionScope(..) => { debug!("temporary_scope({:?}) = {:?} [enclosing]", @@ -595,15 +560,17 @@ impl RegionMaps { -> CodeExtent { if scope_a == scope_b { return scope_a; } - let mut a_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32]; + /// [1] The initial values for `a_buf` and `b_buf` are not used. + /// The `ancestors_of` function will return some prefix that + /// is re-initialized with new values (or else fallback to a + /// heap-allocated vector). + let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32]; let mut a_vec: Vec = vec![]; - let mut b_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32]; + let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32]; let mut b_vec: Vec = vec![]; - let scope_map : &[CodeExtent] = &self.scope_map; - let a_ancestors = ancestors_of(scope_map, - scope_a, &mut a_buf, &mut a_vec); - let b_ancestors = ancestors_of(scope_map, - scope_b, &mut b_buf, &mut b_vec); + let scope_map : &[Option] = &self.scope_map; + let a_ancestors = ancestors_of(scope_map, scope_a, &mut a_buf, &mut a_vec); + let b_ancestors = ancestors_of(scope_map, scope_b, &mut b_buf, &mut b_vec); let mut a_index = a_ancestors.len() - 1; let mut b_index = b_ancestors.len() - 1; @@ -656,17 +623,18 @@ impl RegionMaps { } } - fn ancestors_of<'a>(scope_map: &[CodeExtent], + fn ancestors_of<'a>(scope_map: &[Option], scope: CodeExtent, buf: &'a mut [CodeExtent; 32], - vec: &'a mut Vec) -> &'a [CodeExtent] { + vec: &'a mut Vec) + -> &'a [CodeExtent] { // debug!("ancestors_of(scope={:?})", scope); let mut scope = scope; let mut i = 0; while i < 32 { buf[i] = scope; - match scope_map[scope.0 as usize].into_option() { + match scope_map[scope.0 as usize] { Some(superscope) => scope = superscope, _ => return &buf[..i+1] } @@ -677,7 +645,7 @@ impl RegionMaps { vec.extend_from_slice(buf); loop { vec.push(scope); - match scope_map[scope.0 as usize].into_option() { + match scope_map[scope.0 as usize] { Some(superscope) => scope = superscope, _ => return &*vec } @@ -691,12 +659,12 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor, var_id: ast::NodeId, _sp: Span) { match visitor.cx.var_parent { - ROOT_CODE_EXTENT => { + None => { // this can happen in extern fn declarations like // // extern fn isalnum(c: c_int) -> c_int } - parent_scope => + Some(parent_scope) => visitor.region_maps.record_var_scope(var_id, parent_scope), } } @@ -734,8 +702,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: visitor.cx = Context { root_id: prev_cx.root_id, - var_parent: block_extent, - parent: block_extent, + var_parent: Some(block_extent), + parent: Some(block_extent), }; { @@ -760,8 +728,8 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: ); visitor.cx = Context { root_id: prev_cx.root_id, - var_parent: stmt_extent, - parent: stmt_extent, + var_parent: Some(stmt_extent), + parent: Some(stmt_extent), }; } visitor.visit_stmt(statement) @@ -806,7 +774,7 @@ fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: let stmt_extent = visitor.new_node_extent_with_dtor(stmt_id); let prev_parent = visitor.cx.parent; - visitor.cx.parent = stmt_extent; + visitor.cx.parent = Some(stmt_extent); intravisit::walk_stmt(visitor, stmt); visitor.cx.parent = prev_parent; } @@ -816,7 +784,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: let expr_extent = visitor.new_node_extent_with_dtor(expr.id); let prev_cx = visitor.cx; - visitor.cx.parent = expr_extent; + visitor.cx.parent = Some(expr_extent); { let terminating_scopes = &mut visitor.terminating_scopes; @@ -856,7 +824,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: } hir::ExprMatch(..) => { - visitor.cx.var_parent = expr_extent; + visitor.cx.var_parent = Some(expr_extent); } hir::ExprAssignOp(..) | hir::ExprIndex(..) | @@ -898,7 +866,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, // scope that will be used for any bindings declared in this // pattern. let blk_scope = visitor.cx.var_parent; - assert!(blk_scope != ROOT_CODE_EXTENT); // locals must be within a block + let blk_scope = blk_scope.expect("locals must be within a block"); visitor.region_maps.record_var_scope(local.id, blk_scope); // As an exception to the normal rules governing temporary @@ -1123,8 +1091,8 @@ fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet()); visitor.cx = Context { root_id: None, - var_parent: ROOT_CODE_EXTENT, - parent: ROOT_CODE_EXTENT + var_parent: None, + parent: None, }; walk(visitor); visitor.create_item_scope_if_needed(id); @@ -1147,8 +1115,8 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, body_id, visitor.cx.parent); - visitor.cx.parent = visitor.new_code_extent( - CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }); + visitor.cx.parent = Some(visitor.new_code_extent( + CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id })); let fn_decl_scope = visitor.new_code_extent( CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id }); @@ -1164,8 +1132,8 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, // The arguments and `self` are parented to the fn. visitor.cx = Context { root_id: Some(body_id.node_id), - parent: ROOT_CODE_EXTENT, - var_parent: fn_decl_scope, + parent: None, + var_parent: Some(fn_decl_scope), }; intravisit::walk_fn_decl(visitor, decl); @@ -1174,8 +1142,8 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, // The body of the every fn is a root scope. visitor.cx = Context { root_id: Some(body_id.node_id), - parent: fn_decl_scope, - var_parent: fn_decl_scope + parent: Some(fn_decl_scope), + var_parent: Some(fn_decl_scope), }; visitor.visit_nested_body(body_id); @@ -1202,7 +1170,7 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { if self.terminating_scopes.contains(&id) { let ds = self.new_code_extent( CodeExtentData::DestructionScope(id)); - self.region_maps.intern_node(id, ds) + self.region_maps.intern_node(id, Some(ds)) } else { self.new_node_extent(id) } @@ -1215,7 +1183,7 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { // scopes. let scope = CodeExtentData::DestructionScope(id); if !self.region_maps.code_extent_interner.contains_key(&scope) { - self.region_maps.intern_code_extent(scope, ROOT_CODE_EXTENT); + self.region_maps.intern_code_extent(scope, None); } } } @@ -1225,6 +1193,15 @@ impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> { NestedVisitorMap::OnlyBodies(&self.map) } + fn visit_body(&mut self, b: &'hir Body) { + // 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); } @@ -1285,12 +1262,6 @@ fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateN shrunk_rvalue_scopes: NodeMap(), fn_tree: NodeMap(), }; - let root_extent = maps.bogus_code_extent( - CodeExtentData::DestructionScope(ast::DUMMY_NODE_ID)); - assert_eq!(root_extent, ROOT_CODE_EXTENT); - let bogus_extent = maps.bogus_code_extent( - CodeExtentData::Misc(ast::DUMMY_NODE_ID)); - assert_eq!(bogus_extent, DUMMY_CODE_EXTENT); { let mut visitor = RegionResolutionVisitor { sess: sess, @@ -1298,8 +1269,8 @@ fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateN map: hir_map, cx: Context { root_id: None, - parent: ROOT_CODE_EXTENT, - var_parent: ROOT_CODE_EXTENT + parent: None, + var_parent: None, }, terminating_scopes: NodeSet() }; diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 98b502f5608e7..ea1a2f9a982c9 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -206,8 +206,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }; // Search for a predicate like `Self : Sized` amongst the trait bounds. - let free_substs = self.construct_free_substs(def_id, - self.region_maps().node_extent(ast::DUMMY_NODE_ID)); + let free_substs = self.construct_free_substs(def_id, None); let predicates = self.predicates_of(def_id); let predicates = predicates.instantiate(self, free_substs).predicates; elaborate_predicates(self, predicates) diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 6c685851e2593..d5d17e3c81214 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -23,7 +23,6 @@ use super::util::impl_trait_ref_and_oblig; use rustc_data_structures::fx::FxHashMap; use hir::def_id::DefId; use infer::{InferCtxt, InferOk}; -use middle::region; use ty::subst::{Subst, Substs}; use traits::{self, Reveal, ObligationCause}; use ty::{self, TyCtxt, TypeFoldable}; @@ -182,7 +181,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // create a parameter environment corresponding to a (skolemized) instantiation of impl1 let penv = tcx.construct_parameter_environment(DUMMY_SP, impl1_def_id, - region::DUMMY_CODE_EXTENT); + None); let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id) .unwrap() .subst(tcx, &penv.free_substs); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 969d040e7a6e8..1cf6c3f334f6a 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Replace any late-bound regions bound in `value` with free variants attached to scope-id /// `scope_id`. pub fn liberate_late_bound_regions(self, - all_outlive_scope: region::CodeExtent, + all_outlive_scope: Option, value: &Binder) -> T where T : TypeFoldable<'tcx> diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 49cc4e7c993a5..480b8967a79e9 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1268,9 +1268,8 @@ impl<'a, 'gcx, 'tcx> Layout { let kind = if def.is_enum() || def.variants[0].fields.len() == 0{ StructKind::AlwaysSizedUnivariant } else { - use middle::region::ROOT_CODE_EXTENT; let param_env = tcx.construct_parameter_environment(DUMMY_SP, - def.did, ROOT_CODE_EXTENT); + def.did, None); let fields = &def.variants[0].fields; let last_field = &fields[fields.len()-1]; let always_sized = last_field.ty(tcx, param_env.free_substs) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c0b340ad54455..fd0b1308c9572 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -23,7 +23,7 @@ use ich::StableHashingContext; use middle::const_val::ConstVal; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::privacy::AccessLevels; -use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; +use middle::region::CodeExtent; use middle::resolve_lifetime::ObjectLifetimeDefault; use mir::Mir; use traits; @@ -46,7 +46,7 @@ use std::rc::Rc; use std::slice; use std::vec::IntoIter; use std::mem; -use syntax::ast::{self, Name, NodeId}; +use syntax::ast::{self, DUMMY_NODE_ID, Name, NodeId}; use syntax::attr; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{DUMMY_SP, Span}; @@ -1164,22 +1164,24 @@ pub struct ParameterEnvironment<'tcx> { /// Each type parameter has an implicit region bound that /// indicates it must outlive at least the function body (the user /// may specify stronger requirements). This field indicates the - /// region of the callee. - pub implicit_region_bound: &'tcx ty::Region, + /// region of the callee. If it is `None`, then the parameter + /// environment is for an item or something where the "callee" is + /// not clear. + pub implicit_region_bound: Option<&'tcx ty::Region>, /// Obligations that the caller must satisfy. This is basically /// the set of bounds on the in-scope type parameters, translated /// into Obligations, and elaborated and normalized. pub caller_bounds: Vec>, - /// Scope that is attached to free regions for this scope. This - /// is usually the id of the fn body, but for more abstract scopes - /// like structs we often use the node-id of the struct. + /// Scope that is attached to free regions for this scope. This is + /// usually the id of the fn body, but for more abstract scopes + /// like structs we use None or the item extent. /// /// FIXME(#3696). It would be nice to refactor so that free /// regions don't have this implicit scope and instead introduce /// relationships in the environment. - pub free_id_outlive: CodeExtent, + pub free_id_outlive: Option, /// A cache for `moves_by_default`. pub is_copy_cache: RefCell, bool>>, @@ -1220,13 +1222,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let impl_def_id = tcx.hir.local_def_id(impl_id); tcx.construct_parameter_environment(impl_item.span, impl_def_id, - tcx.region_maps().item_extent(id)) + Some(tcx.region_maps().item_extent(id))) } hir::ImplItemKind::Method(_, ref body) => { tcx.construct_parameter_environment( impl_item.span, tcx.hir.local_def_id(id), - tcx.region_maps().call_site_extent(id, body.node_id)) + Some(tcx.region_maps().call_site_extent(id, body.node_id))) } } } @@ -1239,7 +1241,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let trait_def_id = tcx.hir.local_def_id(trait_id); tcx.construct_parameter_environment(trait_item.span, trait_def_id, - tcx.region_maps().item_extent(id)) + Some(tcx.region_maps().item_extent(id))) } hir::TraitItemKind::Method(_, ref body) => { // Use call-site for extent (unless this is a @@ -1255,7 +1257,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( trait_item.span, tcx.hir.local_def_id(id), - extent) + Some(extent)) } } } @@ -1268,7 +1270,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( item.span, fn_def_id, - tcx.region_maps().call_site_extent(id, body_id.node_id)) + Some(tcx.region_maps().call_site_extent(id, body_id.node_id))) } hir::ItemEnum(..) | hir::ItemStruct(..) | @@ -1280,13 +1282,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - tcx.region_maps().item_extent(id)) + Some(tcx.region_maps().item_extent(id))) } hir::ItemTrait(..) => { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - tcx.region_maps().item_extent(id)) + Some(tcx.region_maps().item_extent(id))) } _ => { span_bug!(item.span, @@ -1304,7 +1306,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( expr.span, base_def_id, - tcx.region_maps().call_site_extent(id, body.node_id)) + Some(tcx.region_maps().call_site_extent(id, body.node_id))) } else { tcx.empty_parameter_environment() } @@ -1313,14 +1315,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - ROOT_CODE_EXTENT) + None) } Some(hir_map::NodeStructCtor(..)) | Some(hir_map::NodeVariant(..)) => { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(tcx.hir.span(id), def_id, - ROOT_CODE_EXTENT) + None) } it => { bug!("ParameterEnvironment::from_item(): \ @@ -2439,10 +2441,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::ParameterEnvironment { free_substs: self.intern_substs(&[]), caller_bounds: Vec::new(), - implicit_region_bound: self.types.re_empty, - // for an empty parameter environment, there ARE no free - // regions, so it shouldn't matter what we use for the free id - free_id_outlive: ROOT_CODE_EXTENT, + implicit_region_bound: None, + free_id_outlive: None, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), is_freeze_cache: RefCell::new(FxHashMap()), @@ -2455,7 +2455,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// free parameters. Since we currently represent bound/free type /// parameters in the same way, this only has an effect on regions. pub fn construct_free_substs(self, def_id: DefId, - free_id_outlive: CodeExtent) + free_id_outlive: Option) -> &'gcx Substs<'gcx> { let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| { @@ -2479,7 +2479,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn construct_parameter_environment(self, span: Span, def_id: DefId, - free_id_outlive: CodeExtent) + free_id_outlive: Option) -> ParameterEnvironment<'gcx> { // @@ -2513,7 +2513,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let unnormalized_env = ty::ParameterEnvironment { free_substs: free_substs, - implicit_region_bound: tcx.mk_region(ty::ReScope(free_id_outlive)), + implicit_region_bound: free_id_outlive.map(|f| tcx.mk_region(ty::ReScope(f))), caller_bounds: predicates, free_id_outlive: free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), @@ -2521,8 +2521,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { is_freeze_cache: RefCell::new(FxHashMap()), }; - let cause = traits::ObligationCause::misc(span, - free_id_outlive.node_id(&self.region_maps())); + let body_id = free_id_outlive.map(|f| f.node_id(&self.region_maps())) + .unwrap_or(DUMMY_NODE_ID); + let cause = traits::ObligationCause::misc(span, body_id); traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 7857d07ed0910..02c4bad8e4e1c 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -43,8 +43,12 @@ pub struct TypeAndMut<'tcx> { RustcEncodable, RustcDecodable, Copy)] /// A "free" region `fr` can be interpreted as "some region /// at least as big as the scope `fr.scope`". +/// +/// If `fr.scope` is None, then this is in some context (e.g., an +/// impl) where lifetimes are more abstract and the notion of the +/// caller/callee stack frames are not applicable. pub struct FreeRegion { - pub scope: region::CodeExtent, + pub scope: Option, pub bound_region: BoundRegion, } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 41fab1f3a4fc0..f5cdd40714cdb 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -353,7 +353,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { let loan_scope = match *loan_region { ty::ReScope(scope) => scope, - ty::ReFree(ref fr) => fr.scope, + ty::ReFree(ref fr) => fr.scope.unwrap_or(self.item_ub), ty::ReStatic => self.item_ub, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 2afaaaf087854..f3a258a8ca58a 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -11,7 +11,7 @@ use hair::cx::Cx; use hair::Pattern; -use rustc::middle::region::{CodeExtent, CodeExtentData, ROOT_CODE_EXTENT}; +use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::ty::{self, Ty}; use rustc::mir::*; use rustc::util::nodemap::NodeMap; @@ -200,11 +200,13 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, let tcx = hir.tcx(); let ast_expr = &tcx.hir.body(body_id).value; let ty = hir.tables().expr_ty_adjusted(ast_expr); - let span = tcx.hir.span(tcx.hir.body_owner(body_id)); + let owner_id = tcx.hir.body_owner(body_id); + let span = tcx.hir.span(owner_id); let mut builder = Builder::new(hir, span, 0, ty); - let extent = tcx.region_maps().temporary_scope(ast_expr.id) - .unwrap_or(ROOT_CODE_EXTENT); + let region_maps = tcx.region_maps(); + let extent = region_maps.temporary_scope(ast_expr.id) + .unwrap_or(region_maps.item_extent(owner_id)); let mut block = START_BLOCK; let _ = builder.in_scope(extent, block, |builder| { let expr = builder.hir.mirror(ast_expr); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index ae63828f0ac76..ad51530b19152 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -828,7 +828,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // signature will be &self or &mut self and hence will // have a bound region with number 0 let region = ty::Region::ReFree(ty::FreeRegion { - scope: cx.tcx.region_maps().node_extent(body_id), + scope: Some(cx.tcx.region_maps().node_extent(body_id)), bound_region: ty::BoundRegion::BrAnon(0), }); let region = cx.tcx.mk_region(region); diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index d8604f65dff92..cbd88733e82de 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -253,7 +253,7 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id); let region = ty::Region::ReFree(ty::FreeRegion { - scope: tcx.region_maps().item_extent(body_id.node_id), + scope: Some(tcx.region_maps().item_extent(body_id.node_id)), bound_region: ty::BoundRegion::BrEnv, }); let region = tcx.mk_region(region); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 9e57472c23657..f2a550ec23a8e 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -11,7 +11,6 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer; -use rustc::middle::region::ROOT_CODE_EXTENT; use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::transform::MirSource; @@ -45,8 +44,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, debug!("make_shim({:?})", instance); let did = instance.def_id(); let span = tcx.def_span(did); - let param_env = - tcx.construct_parameter_environment(span, did, ROOT_CODE_EXTENT); + let param_env = tcx.construct_parameter_environment(span, did, None); let mut result = match instance { ty::InstanceDef::Item(..) => diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index eb897d10d2589..d672637649e85 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -133,7 +133,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Some(&rl::Region::Free(scope, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: scope.to_code_extent(&tcx.region_maps()), + scope: Some(scope.to_code_extent(&tcx.region_maps())), bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name) })) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index c74d71babc2df..5d24df136ff19 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type); let extent = self.tcx.region_maps().call_site_extent(expr.id, body.value.id); - let fn_sig = self.tcx.liberate_late_bound_regions(extent, &sig); + let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig); let fn_sig = self.inh.normalize_associated_types_in(body.value.span, body.value.id, &fn_sig); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e40d8f6cafca3..8b366fd5a2770 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -785,7 +785,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let fn_sig = fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs); let fn_sig = - inh.tcx.liberate_late_bound_regions(fn_scope, &fn_sig); + inh.tcx.liberate_late_bound_regions(Some(fn_scope), &fn_sig); let fn_sig = inh.normalize_associated_types_in(body.value.span, body_id.node_id, &fn_sig); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 16297709b194a..a6f72898a5495 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1614,7 +1614,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // Add in the default bound of fn body that applies to all in // scope type parameters: - param_bounds.push(param_env.implicit_region_bound); + param_bounds.extend(param_env.implicit_region_bound); VerifyBound::AnyRegion(param_bounds) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 08024c9e9e691..f306d5dd70f29 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -343,7 +343,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let mut implied_bounds = vec![]; let free_id_outlive = fcx.tcx.region_maps().call_site_extent(item.id, body_id.node_id); this.check_fn_or_method(fcx, item.span, sig, &predicates, - free_id_outlive, &mut implied_bounds); + Some(free_id_outlive), &mut implied_bounds); implied_bounds }) } @@ -429,7 +429,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { span: Span, sig: ty::PolyFnSig<'tcx>, predicates: &ty::InstantiatedPredicates<'tcx>, - free_id_outlive: CodeExtent, + free_id_outlive: Option, implied_bounds: &mut Vec>) { let free_substs = &fcx.parameter_environment.free_substs; @@ -453,7 +453,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, method_sig: &hir::MethodSig, method: &ty::AssociatedItem, - free_id_outlive: CodeExtent, + free_id_outlive: Option, self_ty: ty::Ty<'tcx>) { // check that the type of the method's receiver matches the From c7dc39dbf095f04839b57a1e34afc6ab29d905d3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 20 Apr 2017 04:45:53 -0400 Subject: [PATCH 05/17] intern CodeExtents Make a `CodeExtent<'tcx>` be something allocated in an arena instead of an index into the `RegionMaps`. --- src/librustc/cfg/construct.rs | 6 +- src/librustc/ich/impls_ty.rs | 15 +- src/librustc/infer/combine.rs | 2 +- src/librustc/infer/equate.rs | 4 +- src/librustc/infer/error_reporting/mod.rs | 18 +- src/librustc/infer/error_reporting/note.rs | 4 +- src/librustc/infer/freshen.rs | 2 +- src/librustc/infer/fudge.rs | 2 +- src/librustc/infer/glb.rs | 4 +- src/librustc/infer/higher_ranked/mod.rs | 32 +- src/librustc/infer/lub.rs | 4 +- src/librustc/infer/mod.rs | 20 +- .../infer/region_inference/graphviz.rs | 28 +- src/librustc/infer/region_inference/mod.rs | 132 +++---- src/librustc/infer/resolve.rs | 4 +- src/librustc/infer/sub.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 4 +- src/librustc/middle/free_region.rs | 134 ++++--- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/mem_categorization.rs | 16 +- src/librustc/middle/region.rs | 359 +++++++----------- src/librustc/mir/mod.rs | 2 +- src/librustc/mir/visit.rs | 2 +- src/librustc/traits/fulfill.rs | 6 +- src/librustc/traits/mod.rs | 2 +- src/librustc/ty/_match.rs | 4 +- src/librustc/ty/adjustment.rs | 2 +- src/librustc/ty/context.rs | 87 ++++- src/librustc/ty/error.rs | 10 +- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/fold.rs | 45 +-- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 46 +-- src/librustc/ty/outlives.rs | 4 +- src/librustc/ty/relate.rs | 12 +- src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 24 +- src/librustc/ty/subst.rs | 30 +- src/librustc/ty/util.rs | 6 +- src/librustc/ty/wf.rs | 12 +- src/librustc/util/ppaux.rs | 16 +- src/librustc_borrowck/borrowck/check_loans.rs | 15 +- .../borrowck/gather_loans/lifetime.rs | 12 +- .../borrowck/gather_loans/mod.rs | 20 +- .../borrowck/gather_loans/restrictions.rs | 4 +- src/librustc_borrowck/borrowck/mod.rs | 28 +- src/librustc_borrowck/borrowck/move_data.rs | 4 +- src/librustc_const_eval/check_match.rs | 2 +- src/librustc_const_eval/pattern.rs | 4 +- .../transitive_relation.rs | 21 + src/librustc_driver/test.rs | 8 +- src/librustc_metadata/decoder.rs | 11 +- src/librustc_mir/build/block.rs | 2 +- src/librustc_mir/build/expr/as_operand.rs | 4 +- src/librustc_mir/build/expr/as_rvalue.rs | 4 +- src/librustc_mir/build/expr/as_temp.rs | 4 +- src/librustc_mir/build/mod.rs | 10 +- src/librustc_mir/build/scope.rs | 36 +- src/librustc_mir/hair/cx/block.rs | 10 +- src/librustc_mir/hair/cx/expr.rs | 28 +- src/librustc_mir/hair/mod.rs | 20 +- src/librustc_mir/mir_map.rs | 4 +- src/librustc_passes/consts.rs | 2 +- src/librustc_typeck/astconv.rs | 12 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 6 +- src/librustc_typeck/check/regionck.rs | 51 +-- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 6 +- src/librustc_typeck/check/writeback.rs | 8 +- src/librustc_typeck/collect.rs | 2 +- .../constrained_type_params.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 8 +- .../kindck-implicit-close-over-mut-var.rs | 2 +- 77 files changed, 729 insertions(+), 743 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 8471d2ae4e32b..7b7c204a0ee77 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -583,10 +583,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { scope_id: ast::NodeId, to_index: CFGIndex) { let mut data = CFGEdgeData { exiting_scopes: vec![] }; - let mut scope = self.tcx.region_maps().node_extent(from_expr.id); - let target_scope = self.tcx.region_maps().node_extent(scope_id); + let mut scope = self.tcx.node_extent(from_expr.id); + let target_scope = self.tcx.node_extent(scope_id); 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); } self.graph.add_edge(from_index, to_index, data); diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index d68a62e503031..52bdb5d02406e 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> HashStable> for ty::subst::Kind<'t } } -impl<'a, 'tcx> HashStable> for ty::Region { +impl<'a, 'tcx> HashStable> for ty::RegionKind<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'tcx>, hasher: &mut StableHasher) { @@ -432,17 +432,6 @@ impl_stable_hash_for!(enum ty::cast::CastKind { FnPtrAddrCast }); -impl<'a, 'tcx> HashStable> for ::middle::region::CodeExtent -{ - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a, 'tcx>, - hasher: &mut StableHasher) { - 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> for ::middle::region::CodeExtentData { fn hash_stable(&self, @@ -477,7 +466,7 @@ impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo { custom_kind }); -impl_stable_hash_for!(struct ty::FreeRegion { +impl_stable_hash_for!(struct ty::FreeRegion<'tcx> { scope, bound_region }); diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index b73079b02bdd9..1bac512e20977 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -315,7 +315,7 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx } } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index f620965ced845..f0b179fa2e420 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -78,8 +78,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } } - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> { + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 10712f5ec7047..8f2bdd4e85c77 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn note_and_explain_region(self, err: &mut DiagnosticBuilder, prefix: &str, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, suffix: &str) { fn item_scope_tag(item: &hir::Item) -> &'static str { match item.node { @@ -124,14 +124,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix) }; - let span = match scope.span(&self.region_maps(), &self.hir) { + let span = match scope.span(&self.hir) { Some(s) => s, None => { err.note(&unknown_scope()); return; } }; - let tag = match self.hir.find(scope.node_id(&self.region_maps())) { + let tag = match self.hir.find(scope.node_id()) { Some(hir_map::NodeBlock(_)) => "block", Some(hir_map::NodeExpr(expr)) => match expr.node { hir::ExprCall(..) => "call", @@ -151,7 +151,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return; } }; - let scope_decorated_tag = match self.region_maps().code_extent_data(scope) { + let scope_decorated_tag = match *scope { region::CodeExtentData::Misc(_) => tag, region::CodeExtentData::CallSiteScope { .. } => { "scope of call-site for function" @@ -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); let unknown; let tag = match self.hir.find(node) { @@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { values.1.push_normal("<"); } - fn lifetime_display(lifetime: &Region) -> String { + fn lifetime_display(lifetime: Region) -> String { let s = format!("{}", lifetime); if s.is_empty() { "'_".to_string() @@ -769,7 +769,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_generic_bound_failure(&self, origin: SubregionOrigin<'tcx>, bound_kind: GenericKind<'tcx>, - sub: &'tcx Region) + sub: Region<'tcx>) { // FIXME: it would be better to report the first error message // with the span of the parameter itself, rather than the span @@ -848,9 +848,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_sub_sup_conflict(&self, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, - sub_region: &'tcx Region, + sub_region: Region<'tcx>, sup_origin: SubregionOrigin<'tcx>, - sup_region: &'tcx Region) { + sup_region: Region<'tcx>) { let mut err = self.report_inference_failure(var_origin); self.tcx.note_and_explain_region(&mut err, diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 8b753e0d22be7..49952d81cbb0b 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -146,8 +146,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub(super) fn report_concrete_failure(&self, origin: SubregionOrigin<'tcx>, - sub: &'tcx Region, - sup: &'tcx Region) + sub: Region<'tcx>, + sup: Region<'tcx>) -> DiagnosticBuilder<'tcx> { match origin { infer::Subtype(trace) => { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 922842136dc9f..ad67ef9a127d8 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { self.infcx.tcx } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReEarlyBound(..) | ty::ReLateBound(..) => { diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 72b23a3bc181c..a8bc33f772d55 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> { } } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReVar(v) if self.region_vars.contains(&v) => { self.infcx.next_region_var(self.origin.clone()) diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index a6dd18c113f1a..d7afeba7dc96b 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> { + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index e3ffc99c0e967..09f909ef399d1 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -269,9 +269,9 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FxHashMap, - r0: &'tcx ty::Region) - -> &'tcx ty::Region { + a_map: &FxHashMap>, + r0: ty::Region<'tcx>) + -> ty::Region<'tcx> { // Regions that pre-dated the LUB computation stay as they are. if !is_var_in_set(new_vars, r0) { assert!(!r0.is_bound()); @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // Variables created during LUB computation which are // *related* to regions that pre-date the LUB computation // stay as they are. - if !tainted.iter().all(|r| is_var_in_set(new_vars, *r)) { + if !tainted.iter().all(|&r| is_var_in_set(new_vars, r)) { debug!("generalize_region(r0={:?}): \ non-new-variables found in {:?}", r0, tainted); @@ -365,11 +365,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { snapshot: &CombinedSnapshot, debruijn: ty::DebruijnIndex, new_vars: &[ty::RegionVid], - a_map: &FxHashMap, + a_map: &FxHashMap>, a_vars: &[ty::RegionVid], b_vars: &[ty::RegionVid], - r0: &'tcx ty::Region) - -> &'tcx ty::Region { + r0: ty::Region<'tcx>) + -> ty::Region<'tcx> { if !is_var_in_set(new_vars, r0) { assert!(!r0.is_bound()); return r0; @@ -434,8 +434,8 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, span: Span, - a_map: &FxHashMap, - r: &'tcx ty::Region) -> &'tcx ty::Region + a_map: &FxHashMap>, + r: ty::Region<'tcx>) -> ty::Region<'tcx> { for (a_br, a_r) in a_map { if *a_r == r { @@ -450,14 +450,14 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, debruijn: ty::DebruijnIndex) - -> &'tcx ty::Region { + -> ty::Region<'tcx> { infcx.region_vars.new_bound(debruijn) } } } fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, - map: &FxHashMap) + map: &FxHashMap>) -> Vec { map.iter() .map(|(_, &r)| match *r { @@ -472,7 +472,7 @@ fn var_ids<'a, 'gcx, 'tcx>(fields: &CombineFields<'a, 'gcx, 'tcx>, .collect() } -fn is_var_in_set(new_vars: &[ty::RegionVid], r: &ty::Region) -> bool { +fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool { match *r { ty::ReVar(ref v) => new_vars.iter().any(|x| x == v), _ => false @@ -484,7 +484,7 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, mut fldr: F) -> T where T: TypeFoldable<'tcx>, - F: FnMut(&'tcx ty::Region, ty::DebruijnIndex) -> &'tcx ty::Region, + F: FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, { tcx.fold_regions(unbound_value, &mut false, |region, current_depth| { // we should only be encountering "escaping" late-bound regions here, @@ -502,9 +502,9 @@ fn fold_regions_in<'a, 'gcx, 'tcx, T, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn tainted_regions(&self, snapshot: &CombinedSnapshot, - r: &'tcx ty::Region, + r: ty::Region<'tcx>, directions: TaintDirections) - -> FxHashSet<&'tcx ty::Region> { + -> FxHashSet> { self.region_vars.tainted(&snapshot.region_vars_snapshot, r, directions) } @@ -731,7 +731,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // region back to the `ty::BoundRegion` that it originally // represented. Because `leak_check` passed, we know that // these taint sets are mutually disjoint. - let inv_skol_map: FxHashMap<&'tcx ty::Region, ty::BoundRegion> = + let inv_skol_map: FxHashMap, ty::BoundRegion> = skol_map .iter() .flat_map(|(&skol_br, &skol)| { diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index d7e5c92b6e17b..04b470b29fc5e 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -59,8 +59,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> { + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index e75513e924eec..a0451c5fe0b4d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -205,7 +205,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized /// region that each late-bound region was replaced with. -pub type SkolemizationMap<'tcx> = FxHashMap; +pub type SkolemizationMap<'tcx> = FxHashMap>; /// See `error_reporting` module for more details #[derive(Clone, Debug)] @@ -1008,7 +1008,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn add_given(&self, - sub: ty::FreeRegion, + sub: ty::FreeRegion<'tcx>, sup: ty::RegionVid) { self.region_vars.add_given(sub, sup); @@ -1107,8 +1107,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn sub_regions(&self, origin: SubregionOrigin<'tcx>, - a: &'tcx ty::Region, - b: &'tcx ty::Region) { + a: ty::Region<'tcx>, + b: ty::Region<'tcx>) { debug!("sub_regions({:?} <: {:?})", a, b); self.region_vars.make_subregion(origin, a, b); } @@ -1210,7 +1210,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn next_region_var(&self, origin: RegionVariableOrigin) - -> &'tcx ty::Region { + -> ty::Region<'tcx> { self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin))) } @@ -1219,7 +1219,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn region_var_for_def(&self, span: Span, def: &ty::RegionParameterDef) - -> &'tcx ty::Region { + -> ty::Region<'tcx> { self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330)) } @@ -1270,7 +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) } @@ -1322,7 +1322,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn resolve_regions_and_report_errors(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, subject_node_id: ast::NodeId) { let errors = self.region_vars.resolve_regions(free_regions, subject_node_id); if !self.is_tainted_by_errors() { @@ -1531,7 +1531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span: Span, lbrct: LateBoundRegionConversionTime, value: &ty::Binder) - -> (T, FxHashMap) + -> (T, FxHashMap>) where T : TypeFoldable<'tcx> { self.tcx.replace_late_bound_regions( @@ -1577,7 +1577,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, - a: &'tcx ty::Region, + a: ty::Region<'tcx>, bound: VerifyBound<'tcx>) { debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index f8d188fcaed38..7de81e14d7754 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -123,20 +123,20 @@ struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, graph_name: String, map: &'a FxHashMap, SubregionOrigin<'tcx>>, - node_ids: FxHashMap, + node_ids: FxHashMap, usize>, } #[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)] -enum Node { +enum Node<'tcx> { RegionVid(ty::RegionVid), - Region(ty::Region), + Region(ty::RegionKind<'tcx>), } // type Edge = Constraint; #[derive(Clone, PartialEq, Eq, Debug, Copy)] enum Edge<'tcx> { Constraint(Constraint<'tcx>), - EnclScope(CodeExtent, CodeExtent), + EnclScope(CodeExtent<'tcx>, CodeExtent<'tcx>), } impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { @@ -160,8 +160,8 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { } tcx.region_maps().each_encl_scope(|sub, sup| { - add_node(Node::Region(ty::ReScope(*sub))); - add_node(Node::Region(ty::ReScope(*sup))); + add_node(Node::Region(ty::ReScope(sub))); + 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> { - type Node = Node; + type Node = Node<'tcx>; type Edge = Edge<'tcx>; fn graph_id(&self) -> dot::Id { dot::Id::new(&*self.graph_name).unwrap() @@ -208,7 +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 { Constraint::ConstrainVarSubVar(rv_1, 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 { Edge::Constraint(ref c) => constraint_to_nodes(c), 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> { - type Node = Node; + type Node = Node<'tcx>; type Edge = Edge<'tcx>; - fn nodes(&self) -> dot::Nodes { + fn nodes(&self) -> dot::Nodes> { let mut set = FxHashSet(); for node in self.node_ids.keys() { set.insert(*node); @@ -245,16 +245,16 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { fn edges(&self) -> dot::Edges> { debug!("constraint graph has {} edges", self.map.len()); let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); - self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup))); + self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup))); debug!("region graph has {} edges", v.len()); Cow::Owned(v) } - fn source(&self, edge: &Edge<'tcx>) -> Node { + fn source(&self, edge: &Edge<'tcx>) -> Node<'tcx> { let (n1, _) = edge_to_nodes(edge); debug!("edge {:?} has source {:?}", edge, n1); n1 } - fn target(&self, edge: &Edge<'tcx>) -> Node { + fn target(&self, edge: &Edge<'tcx>) -> Node<'tcx> { let (_, n2) = edge_to_nodes(edge); debug!("edge {:?} has target {:?}", edge, n2); n2 diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index f9aab59acaf6c..33754b738a091 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -44,17 +44,17 @@ pub enum Constraint<'tcx> { ConstrainVarSubVar(RegionVid, RegionVid), // Concrete region is subregion of region variable - ConstrainRegSubVar(&'tcx Region, RegionVid), + ConstrainRegSubVar(Region<'tcx>, RegionVid), // Region variable is subregion of concrete region. This does not // directly affect inference, but instead is checked after // inference is complete. - ConstrainVarSubReg(RegionVid, &'tcx Region), + ConstrainVarSubReg(RegionVid, Region<'tcx>), // A constraint where neither side is a variable. This does not // directly affect inference, but instead is checked after // inference is complete. - ConstrainRegSubReg(&'tcx Region, &'tcx Region), + ConstrainRegSubReg(Region<'tcx>, Region<'tcx>), } // VerifyGenericBound(T, _, R, RS): The parameter type `T` (or @@ -66,7 +66,7 @@ pub enum Constraint<'tcx> { pub struct Verify<'tcx> { kind: GenericKind<'tcx>, origin: SubregionOrigin<'tcx>, - region: &'tcx Region, + region: Region<'tcx>, bound: VerifyBound<'tcx>, } @@ -86,14 +86,14 @@ pub enum VerifyBound<'tcx> { // Put another way, the subject value is known to outlive all // regions in {R}, so if any of those outlives 'min, then the // bound is met. - AnyRegion(Vec<&'tcx Region>), + AnyRegion(Vec>), // B = forall {R} --> all 'r in {R} must outlive 'min // // Put another way, the subject value is known to outlive some // region in {R}, so if all of those outlives 'min, then the bound // is met. - AllRegions(Vec<&'tcx Region>), + AllRegions(Vec>), // B = exists {B} --> 'min must meet some bound b in {B} AnyBound(Vec>), @@ -104,8 +104,8 @@ pub enum VerifyBound<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct TwoRegions<'tcx> { - a: &'tcx Region, - b: &'tcx Region, + a: Region<'tcx>, + b: Region<'tcx>, } #[derive(Copy, Clone, PartialEq)] @@ -128,7 +128,7 @@ pub enum UndoLogEntry<'tcx> { AddVerify(usize), /// We added the given `given` - AddGiven(ty::FreeRegion, ty::RegionVid), + AddGiven(ty::FreeRegion<'tcx>, ty::RegionVid), /// We added a GLB/LUB "combinaton variable" AddCombination(CombineMapType, TwoRegions<'tcx>), @@ -153,13 +153,13 @@ pub enum RegionResolutionError<'tcx> { /// `ConcreteFailure(o, a, b)`: /// /// `o` requires that `a <= b`, but this does not hold - ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region), + ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>), /// `GenericBoundFailure(p, s, a) /// /// The parameter/associated-type `p` must be known to outlive the lifetime /// `a` (but none of the known bounds are sufficient). - GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, &'tcx Region), + GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region<'tcx>), /// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`: /// @@ -168,14 +168,14 @@ pub enum RegionResolutionError<'tcx> { /// `sub_r <= sup_r` does not hold. SubSupConflict(RegionVariableOrigin, SubregionOrigin<'tcx>, - &'tcx Region, + Region<'tcx>, SubregionOrigin<'tcx>, - &'tcx Region), + Region<'tcx>), } #[derive(Clone, Debug)] pub enum ProcessedErrorOrigin<'tcx> { - ConcreteFailure(SubregionOrigin<'tcx>, &'tcx Region, &'tcx Region), + ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>), VariableFailure(RegionVariableOrigin), } @@ -214,7 +214,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // record the fact that `'a <= 'b` is implied by the fn signature, // and then ignore the constraint when solving equations. This is // a bit of a hack but seems to work. - givens: RefCell>, + givens: RefCell, ty::RegionVid)>>, lubs: RefCell>, glbs: RefCell>, @@ -271,12 +271,12 @@ impl TaintDirections { struct TaintSet<'tcx> { directions: TaintDirections, - regions: FxHashSet<&'tcx ty::Region> + regions: FxHashSet> } impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { fn new(directions: TaintDirections, - initial_region: &'tcx ty::Region) + initial_region: ty::Region<'tcx>) -> Self { let mut regions = FxHashSet(); regions.insert(initial_region); @@ -328,7 +328,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { } } - fn into_set(self) -> FxHashSet<&'tcx ty::Region> { + fn into_set(self) -> FxHashSet> { self.regions } @@ -337,8 +337,8 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> { } fn add_edge(&mut self, - source: &'tcx ty::Region, - target: &'tcx ty::Region) { + source: ty::Region<'tcx>, + target: ty::Region<'tcx>) { if self.directions.incoming { if self.regions.contains(&target) { self.regions.insert(source); @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// it's just there to make it explicit which snapshot bounds the /// skolemized region that results. It should always be the top-most snapshot. pub fn push_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) - -> &'tcx Region { + -> Region<'tcx> { assert!(self.in_snapshot()); assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot); @@ -513,7 +513,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// completes to remove all trace of the skolemized regions /// created in that time. pub fn pop_skolemized(&self, - skols: &FxHashSet<&'tcx ty::Region>, + skols: &FxHashSet>, snapshot: &RegionSnapshot) { 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); return; - fn kill_constraint<'tcx>(skols: &FxHashSet<&'tcx ty::Region>, + fn kill_constraint<'tcx>(skols: &FxHashSet>, undo_entry: &UndoLogEntry<'tcx>) -> bool { 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. // See discussion of GLB computation in the large comment at // 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 assert!(self.values_are_none()); @@ -676,8 +676,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn make_eqregion(&self, origin: SubregionOrigin<'tcx>, - sub: &'tcx Region, - sup: &'tcx Region) { + sub: Region<'tcx>, + sup: Region<'tcx>) { if sub != sup { // Eventually, it would be nice to add direct support for // equating regions. @@ -692,8 +692,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>, - sub: &'tcx Region, - sup: &'tcx Region) { + sub: Region<'tcx>, + sup: Region<'tcx>) { // cannot add constraints once regions are resolved assert!(self.values_are_none()); @@ -734,7 +734,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>, kind: GenericKind<'tcx>, - sub: &'tcx Region, + sub: Region<'tcx>, bound: VerifyBound<'tcx>) { self.add_verify(Verify { kind: kind, @@ -746,9 +746,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn lub_regions(&self, origin: SubregionOrigin<'tcx>, - a: &'tcx Region, - b: &'tcx Region) - -> &'tcx Region { + a: Region<'tcx>, + b: Region<'tcx>) + -> Region<'tcx> { // cannot add constraints once regions are resolved assert!(self.values_are_none()); @@ -772,9 +772,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn glb_regions(&self, origin: SubregionOrigin<'tcx>, - a: &'tcx Region, - b: &'tcx Region) - -> &'tcx Region { + a: Region<'tcx>, + b: Region<'tcx>) + -> Region<'tcx> { // cannot add constraints once regions are resolved assert!(self.values_are_none()); @@ -796,7 +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() { None => { 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; self.tcx.mk_region(ty::ReVar(vid)) } @@ -825,12 +825,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { pub fn combine_vars(&self, t: CombineMapType, - a: &'tcx Region, - b: &'tcx Region, + a: Region<'tcx>, + b: Region<'tcx>, origin: SubregionOrigin<'tcx>, mut relate: F) - -> &'tcx Region - where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, &'tcx Region, &'tcx Region) + -> Region<'tcx> + where F: FnMut(&RegionVarBindings<'a, 'gcx, 'tcx>, Region<'tcx>, Region<'tcx>) { let vars = TwoRegions { a: a, b: b }; if let Some(&c) = self.combine_map(t).borrow().get(&vars) { @@ -869,9 +869,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// related to other regions. pub fn tainted(&self, mark: &RegionSnapshot, - r0: &'tcx Region, + r0: Region<'tcx>, directions: TaintDirections) - -> FxHashSet<&'tcx ty::Region> { + -> FxHashSet> { debug!("tainted(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, /// errors are reported. pub fn resolve_regions(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, subject_node: ast::NodeId) -> Vec> { debug!("RegionVarBindings: resolve_regions()"); @@ -903,10 +903,10 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn lub_concrete_regions(&self, - free_regions: &FreeRegionMap, - a: &'tcx Region, - b: &'tcx Region) - -> &'tcx Region { + free_regions: &FreeRegionMap<'tcx>, + a: Region<'tcx>, + b: Region<'tcx>) + -> Region<'tcx> { match (a, b) { (&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))) } - (&ReFree(a_fr), &ReFree(b_fr)) => { - self.tcx.mk_region(free_regions.lub_free_regions(a_fr, b_fr)) + (&ReFree(_), &ReFree(_)) => { + free_regions.lub_free_regions(self.tcx, a, b) } // For these types, we cannot define any additional @@ -983,12 +983,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { #[derive(Copy, Clone, Debug)] pub enum VarValue<'tcx> { - Value(&'tcx Region), + Value(Region<'tcx>), ErrorValue, } struct RegionAndOrigin<'tcx> { - region: &'tcx Region, + region: Region<'tcx>, origin: SubregionOrigin<'tcx>, } @@ -996,7 +996,7 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>; impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn infer_variable_values(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, errors: &mut Vec>, subject: ast::NodeId) -> Vec> { @@ -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| { debug!("expansion: constraint={:?} origin={:?}", constraint, origin); @@ -1085,8 +1085,8 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn expand_node(&self, - free_regions: &FreeRegionMap, - a_region: &'tcx Region, + free_regions: &FreeRegionMap<'tcx>, + a_region: Region<'tcx>, b_vid: RegionVid, b_data: &mut VarValue<'tcx>) -> bool { @@ -1132,7 +1132,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// cases where the region cannot grow larger than a fixed point) /// and check that they are satisfied. fn collect_errors(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, var_data: &mut Vec>, errors: &mut Vec>) { 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 /// and create a `RegionResolutionError` for each of them. fn collect_var_errors(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, var_data: &[VarValue<'tcx>], graph: &RegionGraph<'tcx>, errors: &mut Vec>) { @@ -1311,7 +1311,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn collect_error_for_expanding_node(&self, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, graph: &RegionGraph<'tcx>, dup_vec: &mut [u32], 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>, values: &Vec>, - r: &'tcx ty::Region) - -> &'tcx ty::Region { + r: ty::Region<'tcx>) + -> ty::Region<'tcx> { match *r { ty::ReVar(rid) => lookup(tcx, values, rid), _ => 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>, values: &Vec>, rid: ty::RegionVid) - -> &'tcx ty::Region { + -> ty::Region<'tcx> { match values[rid.index as usize] { Value(r) => r, ErrorValue => tcx.types.re_static, // Previously reported error. @@ -1539,7 +1539,7 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> { } impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { - fn for_each_region(&self, f: &mut FnMut(&'tcx ty::Region)) { + fn for_each_region(&self, f: &mut FnMut(ty::Region<'tcx>)) { match self { &VerifyBound::AnyRegion(ref rs) | &VerifyBound::AllRegions(ref rs) => for &r in rs { @@ -1592,9 +1592,9 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { } fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - free_regions: &FreeRegionMap, + free_regions: &FreeRegionMap<'tcx>, var_values: &Vec>, - min: &'tcx ty::Region) + min: ty::Region<'tcx>) -> bool { match self { &VerifyBound::AnyRegion(ref rs) => diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 357a03a2ffd7c..2e8b843d07b30 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.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 { ty::ReVar(rid) => self.infcx.region_vars.opportunistic_resolve_var(rid), _ => r, @@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> } } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid), _ => r, diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 2a7dbbc026bc0..487195fdfae9f 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -127,8 +127,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> } } - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> { + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?}) self.cause={:?}", self.tag(), a, b, self.fields.cause); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 82e7d972c579a..9be05313439fd 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -75,7 +75,7 @@ pub trait Delegate<'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: LoanCause); @@ -347,7 +347,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn borrow_expr(&mut self, expr: &hir::Expr, - r: &'tcx ty::Region, + r: ty::Region<'tcx>, bk: ty::BorrowKind, cause: LoanCause) { debug!("borrow_expr(expr={:?}, r={:?}, bk={:?})", diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 9701595a9d872..1dc633c6d0040 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -15,18 +15,21 @@ //! `TransitiveRelation` type and use that to decide when one free //! region outlives another and so forth. -use ty::{self, TyCtxt, FreeRegion, Region}; +use ty::{self, Lift, TyCtxt, Region}; use ty::wf::ImpliedBound; use rustc_data_structures::transitive_relation::TransitiveRelation; #[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct FreeRegionMap { +pub struct FreeRegionMap<'tcx> { // Stores the relation `a < b`, where `a` and `b` are regions. - relation: TransitiveRelation + // + // Invariant: only free regions like `'x` or `'static` are stored + // in this relation, not scopes. + relation: TransitiveRelation> } -impl FreeRegionMap { - pub fn new() -> FreeRegionMap { +impl<'tcx> FreeRegionMap<'tcx> { + pub fn new() -> Self { FreeRegionMap { relation: TransitiveRelation::new() } } @@ -34,15 +37,16 @@ impl FreeRegionMap { self.relation.is_empty() } - pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self, - implied_bounds: &[ImpliedBound<'tcx>]) + pub fn relate_free_regions_from_implied_bounds(&mut self, + implied_bounds: &[ImpliedBound<'tcx>]) { debug!("relate_free_regions_from_implied_bounds()"); for implied_bound in implied_bounds { debug!("implied bound: {:?}", implied_bound); match *implied_bound { - ImpliedBound::RegionSubRegion(&ty::ReFree(free_a), &ty::ReFree(free_b)) => { - self.relate_free_regions(free_a, free_b); + ImpliedBound::RegionSubRegion(a @ &ty::ReFree(_), b @ &ty::ReFree(_)) | + ImpliedBound::RegionSubRegion(a @ &ty::ReStatic, b @ &ty::ReFree(_)) => { + self.relate_regions(a, b); } ImpliedBound::RegionSubRegion(..) | ImpliedBound::RegionSubParam(..) | @@ -53,7 +57,7 @@ impl FreeRegionMap { } pub fn relate_free_regions_from_predicates(&mut self, - predicates: &[ty::Predicate]) { + predicates: &[ty::Predicate<'tcx>]) { debug!("relate_free_regions_from_predicates(predicates={:?})", predicates); for predicate in predicates { match *predicate { @@ -69,12 +73,15 @@ impl FreeRegionMap { } ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => { match (r_a, r_b) { + // `'static: 'x` is not notable (&ty::ReStatic, &ty::ReFree(_)) => {}, - (&ty::ReFree(fr_a), &ty::ReStatic) => self.relate_to_static(fr_a), - (&ty::ReFree(fr_a), &ty::ReFree(fr_b)) => { + + (&ty::ReFree(_), &ty::ReStatic) | + (&ty::ReFree(_), &ty::ReFree(_)) => { // Record that `'a:'b`. Or, put another way, `'b <= 'a`. - self.relate_free_regions(fr_b, fr_a); + self.relate_regions(r_b, r_a); } + _ => { // All named regions are instantiated with free regions. bug!("record_region_bounds: non free region: {:?} / {:?}", @@ -87,48 +94,36 @@ impl FreeRegionMap { } } - fn relate_to_static(&mut self, sup: FreeRegion) { - self.relation.add(ty::ReStatic, ty::ReFree(sup)); - } - - fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) { - self.relation.add(ty::ReFree(sub), ty::ReFree(sup)) - } - - /// Determines whether two free regions have a subregion relationship - /// by walking the graph encoded in `map`. Note that - /// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub` - /// (that is, the user can give two different names to the same lifetime). - pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool { - let result = sub == sup || { - let sub = ty::ReFree(sub); - let sup = ty::ReFree(sup); - self.relation.contains(&sub, &sup) || self.relation.contains(&ty::ReStatic, &sup) - }; - debug!("sub_free_region(sub={:?}, sup={:?}) = {:?}", sub, sup, result); - result + fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) { + assert!(match *sub { ty::ReFree(_) | ty::ReStatic => true, _ => false }); + assert!(match *sup { ty::ReFree(_) | ty::ReStatic => true, _ => false }); + self.relation.add(sub, sup) } - pub fn lub_free_regions(&self, fr_a: FreeRegion, fr_b: FreeRegion) -> Region { - let r_a = ty::ReFree(fr_a); - let r_b = ty::ReFree(fr_b); - let result = if fr_a == fr_b { r_a } else { + pub fn lub_free_regions<'a, 'gcx>(&self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + r_a: Region<'tcx>, + r_b: Region<'tcx>) + -> Region<'tcx> { + assert!(match *r_a { ty::ReFree(_) => true, _ => false }); + assert!(match *r_b { ty::ReFree(_) => true, _ => false }); + let result = if r_a == r_b { r_a } else { match self.relation.postdom_upper_bound(&r_a, &r_b) { - None => ty::ReStatic, + None => tcx.mk_region(ty::ReStatic), Some(r) => *r, } }; - debug!("lub_free_regions(fr_a={:?}, fr_b={:?}) = {:?}", fr_a, fr_b, result); + debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result); result } /// Determines whether one region is a subregion of another. This is intended to run *after /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. - pub fn is_subregion_of(&self, - tcx: TyCtxt, - sub_region: &ty::Region, - super_region: &ty::Region) - -> bool { + pub fn is_subregion_of<'a, 'gcx>(&self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + sub_region: ty::Region<'tcx>, + super_region: ty::Region<'tcx>) + -> bool { let result = sub_region == super_region || { match (sub_region, super_region) { (&ty::ReEmpty, _) | @@ -141,17 +136,18 @@ impl FreeRegionMap { (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { // 1. It is safe to unwrap `fr.scope` because we // should only ever wind up comparing against - // `ReScope` in the context of a method or fn + // `ReScope` in the context of a method or // body, where `fr.scope` should be `Some`. 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)) => - self.sub_free_region(sub_fr, super_fr), + (&ty::ReFree(_), &ty::ReFree(_)) => + self.relation.contains(&sub_region, &super_region) || + self.is_static(tcx, super_region), - (&ty::ReStatic, &ty::ReFree(sup_fr)) => - self.is_static(sup_fr), + (&ty::ReStatic, &ty::ReFree(_)) => + self.is_static(tcx, super_region), _ => false, @@ -163,28 +159,28 @@ impl FreeRegionMap { } /// 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); - 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)] -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 { +impl_stable_hash_for!(struct FreeRegionMap<'tcx> { relation }); + +impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { + type Lifted = FreeRegionMap<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { + self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx)) + .map(|relation| FreeRegionMap { relation }) + } +} diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 508dfe9cfcd8b..1ea87cc0a4568 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1441,7 +1441,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // and must outlive the *call-site* of the function. let fn_ret = self.ir.tcx.liberate_late_bound_regions( - 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); if !fn_ret.is_never() && self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 92777bb160463..3b1a9552ece26 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -89,7 +89,7 @@ use std::rc::Rc; #[derive(Clone, PartialEq)] pub enum Categorization<'tcx> { // temporary val, argument is its scope - Rvalue(&'tcx ty::Region, &'tcx ty::Region), + Rvalue(ty::Region<'tcx>, ty::Region<'tcx>), StaticItem, Upvar(Upvar), // upvar referenced by closure env Local(ast::NodeId), // local variable @@ -114,13 +114,13 @@ pub enum PointerKind<'tcx> { Unique, /// `&T` - BorrowedPtr(ty::BorrowKind, &'tcx ty::Region), + BorrowedPtr(ty::BorrowKind, ty::Region<'tcx>), /// `*T` UnsafePtr(hir::Mutability), /// Implicit deref of the `&T` that results from an overloaded index `[]`. - Implicit(ty::BorrowKind, &'tcx ty::Region), + Implicit(ty::BorrowKind, ty::Region<'tcx>), } // We use the term "interior" to mean "something reachable from the @@ -796,7 +796,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: Some(self.tcx().region_maps().item_extent(fn_body_id)), + scope: Some(self.tcx().item_extent(fn_body_id)), 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`. /// This could be `'static` if `id` is part of a constant expression. - pub fn temporary_scope(&self, id: ast::NodeId) -> (&'tcx ty::Region, &'tcx ty::Region) + pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>) { let (scope, old_scope) = - self.tcx().region_maps().old_and_new_temporary_scope(id); + self.tcx().region_maps().old_and_new_temporary_scope(self.tcx(), id); (self.tcx().mk_region(match scope { Some(scope) => ty::ReScope(scope), None => ty::ReStatic @@ -887,8 +887,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn cat_rvalue(&self, cmt_id: ast::NodeId, span: Span, - temp_scope: &'tcx ty::Region, - old_temp_scope: &'tcx ty::Region, + temp_scope: ty::Region<'tcx>, + old_temp_scope: ty::Region<'tcx>, expr_ty: Ty<'tcx>) -> cmt<'tcx> { let ret = Rc::new(cmt_ { id:cmt_id, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index e381a904478b7..062432e27e549 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,14 +17,12 @@ //! `middle/infer/region_inference/README.md` use hir::map as hir_map; -use session::Session; use util::nodemap::{FxHashMap, NodeMap, NodeSet}; use ty; -use std::collections::hash_map::Entry; -use std::fmt; use std::mem; use std::rc::Rc; +use serialize; use syntax::codemap; use syntax::ast::{self, NodeId}; use syntax_pos::Span; @@ -34,33 +32,12 @@ use ty::maps::Providers; use hir; use hir::def_id::{CrateNum, LOCAL_CRATE}; 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, - RustcDecodable, Copy)] -pub struct CodeExtent(u32); - -impl fmt::Debug for CodeExtent { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "CodeExtent({:?}", self.0)?; - - ty::tls::with_opt(|opt_tcx| { - if let Some(tcx) = opt_tcx { - 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(()) - })?; +pub type CodeExtent<'tcx> = &'tcx CodeExtentData; - write!(f, ")") - } -} +impl<'tcx> serialize::UseSpecializedEncodable for CodeExtent<'tcx> {} +impl<'tcx> serialize::UseSpecializedDecodable for CodeExtent<'tcx> {} /// CodeExtent represents a statically-describable extent that can be /// used to bound the lifetime/region for values. @@ -123,7 +100,7 @@ impl fmt::Debug for CodeExtent { /// placate the same deriving in `ty::FreeRegion`, but we may want to /// actually attach a more meaningful ordering to scopes than the one /// generated via deriving here. -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy)] +#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, RustcEncodable, RustcDecodable)] pub enum CodeExtentData { Misc(ast::NodeId), @@ -150,8 +127,8 @@ pub struct CallSiteScopeData { } impl CallSiteScopeData { - pub fn to_code_extent(&self, region_maps: &RegionMaps) -> CodeExtent { - region_maps.lookup_code_extent( + pub fn to_code_extent<'a, 'tcx, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CodeExtent<'tcx> { + tcx.intern_code_extent( match *self { CallSiteScopeData { fn_id, body_id } => CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id }, @@ -200,20 +177,14 @@ impl CodeExtentData { 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 /// returned span may not correspond to the span of any node id in /// the AST. - pub fn span(&self, region_maps: &RegionMaps, hir_map: &hir_map::Map) -> Option { - match hir_map.find(self.node_id(region_maps)) { + pub fn span(&self, hir_map: &hir_map::Map) -> Option { + match hir_map.find(self.node_id()) { Some(hir_map::NodeBlock(ref blk)) => { - match region_maps.code_extent_data(*self) { + match *self { CodeExtentData::CallSiteScope { .. } | CodeExtentData::ParameterScope { .. } | CodeExtentData::Misc(_) | @@ -242,20 +213,18 @@ impl CodeExtent { } /// The region maps encode information about region relationships. -pub struct RegionMaps { - code_extents: Vec, - code_extent_interner: FxHashMap, +pub struct RegionMaps<'tcx> { /// `scope_map` maps from a scope id to the enclosing scope id; /// this is usually corresponding to the lexical nesting, though /// in the case of closures the parent scope is the innermost /// conditional expression or repeating block. (Note that the /// enclosing scope id for the block associated with a closure is /// the closure itself.) - scope_map: Vec>, + scope_map: FxHashMap, CodeExtent<'tcx>>, /// `var_map` maps from a variable or binding id to the block in /// which that variable is declared. - var_map: NodeMap, + var_map: NodeMap>, /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is /// 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 /// enclosing statement, conditional expression, or repeating /// block (see `terminating_scopes`). - rvalue_scopes: NodeMap, + rvalue_scopes: NodeMap>, /// Records the value of rvalue scopes before they were shrunk by /// #36082, for error reporting. /// /// FIXME: this should be temporary. Remove this by 1.18.0 or /// so. - shrunk_rvalue_scopes: NodeMap, + shrunk_rvalue_scopes: NodeMap>, /// Encodes the hierarchy of fn bodies. Every fn body (including /// closures) forms its own distinct region hierarchy, rooted in @@ -286,7 +255,7 @@ pub struct RegionMaps { } #[derive(Debug, Copy, Clone)] -pub struct Context { +pub struct Context<'tcx> { /// the root of the current region tree. This is typically the id /// of the innermost fn body. Each fn forms its own disjoint tree /// in the region hierarchy. These fn bodies are themselves @@ -296,21 +265,21 @@ pub struct Context { root_id: Option, /// the scope that contains any new variables declared - var_parent: Option, + var_parent: Option>, /// region parent of expressions etc - parent: Option, + parent: Option>, } -struct RegionResolutionVisitor<'hir: 'a, 'a> { - sess: &'a Session, +struct RegionResolutionVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, // 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 /// statement, or conditional/repeating expression. These scopes @@ -336,64 +305,13 @@ struct RegionResolutionVisitor<'hir: 'a, 'a> { } -impl RegionMaps { - pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent { - match self.code_extent_interner.get(&e) { - Some(&d) => d, - None => bug!("unknown code extent {:?}", e) - } - } - pub fn node_extent(&self, n: ast::NodeId) -> CodeExtent { - self.lookup_code_extent(CodeExtentData::Misc(n)) - } - // Returns the code extent for an item - the destruction scope. - pub fn item_extent(&self, n: ast::NodeId) -> CodeExtent { - self.lookup_code_extent(CodeExtentData::DestructionScope(n)) - } - pub fn call_site_extent(&self, fn_id: ast::NodeId, body_id: ast::NodeId) -> CodeExtent { - assert!(fn_id != body_id); - self.lookup_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id }) - } - pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option { - self.code_extent_interner.get(&CodeExtentData::DestructionScope(n)).cloned() - } - pub fn intern_code_extent(&mut self, - e: CodeExtentData, - parent: Option) -> 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 { - 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(&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) - } +impl<'tcx> RegionMaps<'tcx> { + pub fn each_encl_scope(&self, mut e:E) where E: FnMut(CodeExtent<'tcx>, CodeExtent<'tcx>) { + for (&child, &parent) in &self.scope_map { + e(child, parent) } } - pub fn each_var_scope(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) { + pub fn each_var_scope(&self, mut e:E) where E: FnMut(&ast::NodeId, CodeExtent<'tcx>) { for (child, parent) in self.var_map.iter() { 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); - assert!(var != lifetime.node_id(self)); + assert!(var != lifetime.node_id()); 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); - assert!(var != lifetime.node_id(self)); + assert!(var != lifetime.node_id()); 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); - assert!(var != lifetime.node_id(self)); + assert!(var != lifetime.node_id()); self.shrunk_rvalue_scopes.insert(var, lifetime); } - pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { + pub fn opt_encl_scope(&self, id: CodeExtent<'tcx>) -> Option> { //! 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 - pub fn encl_scope(&self, id: CodeExtent) -> CodeExtent { + pub fn encl_scope(&self, id: CodeExtent<'tcx>) -> CodeExtent<'tcx> { //! Returns the narrowest scope that encloses `id`, if any. self.opt_encl_scope(id).unwrap() } /// Returns the lifetime of the local variable `var_id` - pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent { + pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent<'tcx> { match self.var_map.get(&var_id) { Some(&r) => r, None => { bug!("no enclosing scope for id {:?}", var_id); } } } - pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option, bool) { - let temporary_scope = self.temporary_scope(expr_id); + pub fn temporary_scope2<'a, 'gcx: 'tcx>(&self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + expr_id: ast::NodeId) + -> (Option>, bool) { + let temporary_scope = self.temporary_scope(tcx, expr_id); let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) { Some(&s) => { info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})", @@ -470,17 +391,23 @@ impl RegionMaps { (temporary_scope, was_shrunk) } - pub fn old_and_new_temporary_scope(&self, expr_id: ast::NodeId) -> - (Option, Option) + pub fn old_and_new_temporary_scope<'a, 'gcx: 'tcx>(&self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + expr_id: ast::NodeId) + -> (Option>, + Option>) { - let temporary_scope = self.temporary_scope(expr_id); + let temporary_scope = self.temporary_scope(tcx, expr_id); (temporary_scope, self.shrunk_rvalue_scopes .get(&expr_id).cloned() .or(temporary_scope)) } - pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option { + pub fn temporary_scope<'a, 'gcx: 'tcx>(&self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + expr_id: ast::NodeId) + -> Option> { //! Returns the scope when temp created by expr_id will be cleaned up // check for a designated rvalue scope @@ -489,17 +416,14 @@ impl RegionMaps { return Some(s); } - let scope_map : &[Option] = &self.scope_map; - let code_extents: &[CodeExtentData] = &self.code_extents; - // else, locate the innermost terminating scope // if there's one. Static items, for instance, won't // have an enclosing scope, hence no scope will be // returned. - let mut id = self.node_extent(expr_id); + let mut id = tcx.node_extent(expr_id); - while let Some(p) = scope_map[id.0 as usize] { - match code_extents[p.0 as usize] { + while let Some(&p) = self.scope_map.get(id) { + match *p { CodeExtentData::DestructionScope(..) => { debug!("temporary_scope({:?}) = {:?} [enclosing]", expr_id, id); @@ -513,7 +437,7 @@ impl RegionMaps { return None; } - pub fn var_region(&self, id: ast::NodeId) -> ty::Region { + pub fn var_region(&self, id: ast::NodeId) -> ty::RegionKind<'tcx> { //! Returns the lifetime of the variable `id`. let scope = ty::ReScope(self.var_scope(id)); @@ -555,9 +479,9 @@ impl RegionMaps { /// Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest /// scope which is greater than or equal to both `scope_a` and `scope_b`. pub fn nearest_common_ancestor(&self, - scope_a: CodeExtent, - scope_b: CodeExtent) - -> CodeExtent { + scope_a: CodeExtent<'tcx>, + scope_b: CodeExtent<'tcx>) + -> CodeExtent<'tcx> { if scope_a == scope_b { return scope_a; } /// [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 /// heap-allocated vector). let mut a_buf: [CodeExtent; 32] = [scope_a /* [1] */; 32]; - let mut a_vec: Vec = vec![]; + let mut a_vec: Vec> = vec![]; let mut b_buf: [CodeExtent; 32] = [scope_b /* [1] */; 32]; - let mut b_vec: Vec = vec![]; - let scope_map : &[Option] = &self.scope_map; + let mut b_vec: Vec> = vec![]; + let scope_map = &self.scope_map; let a_ancestors = ancestors_of(scope_map, scope_a, &mut a_buf, &mut a_vec); let b_ancestors = ancestors_of(scope_map, scope_b, &mut b_buf, &mut b_vec); let mut a_index = a_ancestors.len() - 1; @@ -588,11 +512,11 @@ impl RegionMaps { // nesting. The reasoning behind this is subtle. See the // "Modeling closures" section of the README in // infer::region_inference for more details. - let a_root_scope = self.code_extent_data(a_ancestors[a_index]); - let b_root_scope = self.code_extent_data(a_ancestors[a_index]); + let a_root_scope = a_ancestors[a_index]; + let b_root_scope = a_ancestors[a_index]; return match (a_root_scope, b_root_scope) { - (CodeExtentData::DestructionScope(a_root_id), - CodeExtentData::DestructionScope(b_root_id)) => { + (&CodeExtentData::DestructionScope(a_root_id), + &CodeExtentData::DestructionScope(b_root_id)) => { if self.fn_is_enclosed_by(a_root_id, b_root_id) { // `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a` scope_b @@ -623,18 +547,18 @@ impl RegionMaps { } } - fn ancestors_of<'a>(scope_map: &[Option], - scope: CodeExtent, - buf: &'a mut [CodeExtent; 32], - vec: &'a mut Vec) - -> &'a [CodeExtent] { + fn ancestors_of<'a, 'tcx>(scope_map: &FxHashMap, CodeExtent<'tcx>>, + scope: CodeExtent<'tcx>, + buf: &'a mut [CodeExtent<'tcx>; 32], + vec: &'a mut Vec>) + -> &'a [CodeExtent<'tcx>] { // debug!("ancestors_of(scope={:?})", scope); let mut scope = scope; let mut i = 0; while i < 32 { buf[i] = scope; - match scope_map[scope.0 as usize] { + match scope_map.get(&scope) { Some(superscope) => scope = superscope, _ => return &buf[..i+1] } @@ -645,7 +569,7 @@ impl RegionMaps { vec.extend_from_slice(buf); loop { vec.push(scope); - match scope_map[scope.0 as usize] { + match scope_map.get(&scope) { Some(superscope) => scope = superscope, _ => 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); let prev_cx = visitor.cx; @@ -740,7 +664,7 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: visitor.cx = prev_cx; } -fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) { +fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, arm: &'tcx hir::Arm) { visitor.terminating_scopes.insert(arm.body.id); if let Some(ref expr) = arm.guard { @@ -750,7 +674,7 @@ fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: & intravisit::walk_arm(visitor, arm); } -fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) { +fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: &'tcx hir::Pat) { visitor.new_node_extent(pat.id); // If this is a binding then record the lifetime of that binding. @@ -761,7 +685,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: & intravisit::walk_pat(visitor, pat); } -fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) { +fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) { let stmt_id = stmt.node.id(); debug!("resolve_stmt(stmt.id={:?})", stmt_id); @@ -779,7 +703,7 @@ fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: visitor.cx.parent = prev_parent; } -fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) { +fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr: &'tcx hir::Expr) { debug!("resolve_expr(expr.id={:?})", expr.id); let expr_extent = visitor.new_node_extent_with_dtor(expr.id); @@ -857,7 +781,7 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: visitor.cx = prev_cx; } -fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, +fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, local: &'tcx hir::Local) { debug!("resolve_local(local.id={:?},local.init={:?})", local.id,local.init.is_some()); @@ -998,9 +922,11 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, /// | box E& /// | E& as ... /// | ( E& ) - fn record_rvalue_scope_if_borrow_expr(visitor: &mut RegionResolutionVisitor, - expr: &hir::Expr, - blk_id: CodeExtent) { + fn record_rvalue_scope_if_borrow_expr<'a, 'tcx>( + visitor: &mut RegionResolutionVisitor<'a, 'tcx>, + expr: &hir::Expr, + blk_id: CodeExtent<'tcx>) + { match expr.node { hir::ExprAddrOf(_, ref subexpr) => { record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); @@ -1047,10 +973,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, /// | /// /// Note: ET is intended to match "rvalues or lvalues based on rvalues". - fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor, - expr: &'a hir::Expr, - blk_scope: CodeExtent, - is_shrunk: bool) { + fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, + expr: &hir::Expr, + blk_scope: CodeExtent<'tcx>, + is_shrunk: bool) { let mut expr = expr; loop { // Note: give all the expressions matching `ET` with the @@ -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>, - id: ast::NodeId, - walk: F) - where F: FnOnce(&mut RegionResolutionVisitor<'tcx, 'a>) +fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, walk: F) + where F: FnOnce(&mut RegionResolutionVisitor<'a, 'tcx>) { // Items create a new outer block scope as far as we're concerned. let prev_cx = visitor.cx; @@ -1095,12 +1019,11 @@ fn resolve_item_like<'a, 'tcx, F>(visitor: &mut RegionResolutionVisitor<'tcx, 'a parent: None, }; walk(visitor); - visitor.create_item_scope_if_needed(id); visitor.cx = prev_cx; visitor.terminating_scopes = prev_ts; } -fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, +fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, kind: FnKind<'tcx>, decl: &'tcx hir::FnDecl, body_id: hir::BodyId, @@ -1111,7 +1034,7 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, body.id={:?}, \ cx.parent={:?})", id, - visitor.sess.codemap().span_to_string(sp), + visitor.tcx.sess.codemap().span_to_string(sp), body_id, visitor.cx.parent); @@ -1152,17 +1075,37 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, visitor.terminating_scopes = outer_ts; } -impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { +impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> { + pub fn intern_code_extent(&mut self, + data: CodeExtentData, + parent: Option>) + -> 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 + } + + pub fn intern_node(&mut self, + n: ast::NodeId, + parent: Option>) -> 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 { - self.region_maps.intern_code_extent(child_scope, self.cx.parent) + 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 { + fn new_node_extent(&mut self, child_scope: ast::NodeId) -> CodeExtent<'tcx> { self.new_code_extent(CodeExtentData::Misc(child_scope)) } - fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent { + fn new_node_extent_with_dtor(&mut self, id: ast::NodeId) -> CodeExtent<'tcx> { // If node was previously marked as a terminating scope during the // recursive visit of its parent node in the AST, then we need to // account for the destruction scope representing the extent of @@ -1170,101 +1113,79 @@ impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { if self.terminating_scopes.contains(&id) { let ds = self.new_code_extent( CodeExtentData::DestructionScope(id)); - self.region_maps.intern_node(id, Some(ds)) + self.intern_node(id, Some(ds)) } else { self.new_node_extent(id) } } - - fn create_item_scope_if_needed(&mut self, id: ast::NodeId) { - // create a region for the destruction scope - this is needed - // for constructing parameter environments based on the item. - // functions put their destruction scopes *inside* their parameter - // scopes. - let scope = CodeExtentData::DestructionScope(id); - if !self.region_maps.code_extent_interner.contains_key(&scope) { - self.region_maps.intern_code_extent(scope, None); - } - } } -impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { +impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { NestedVisitorMap::OnlyBodies(&self.map) } - fn visit_body(&mut self, b: &'hir Body) { - // 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) { + fn visit_block(&mut self, b: &'tcx Block) { resolve_block(self, b); } - fn visit_item(&mut self, i: &'hir Item) { - resolve_item_like(self, i.id, |this| intravisit::walk_item(this, i)); + fn visit_item(&mut self, i: &'tcx Item) { + resolve_item_like(self, |this| intravisit::walk_item(this, i)); } - fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { - resolve_item_like(self, ii.id, |this| intravisit::walk_impl_item(this, ii)); + fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { + resolve_item_like(self, |this| intravisit::walk_impl_item(this, ii)); } - fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { - resolve_item_like(self, ti.id, |this| intravisit::walk_trait_item(this, ti)); + fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { + resolve_item_like(self, |this| intravisit::walk_trait_item(this, ti)); } - fn visit_fn(&mut self, fk: FnKind<'hir>, fd: &'hir FnDecl, + fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx FnDecl, b: hir::BodyId, s: Span, n: NodeId) { resolve_fn(self, fk, fd, b, s, n); } - fn visit_arm(&mut self, a: &'hir Arm) { + fn visit_arm(&mut self, a: &'tcx Arm) { resolve_arm(self, a); } - fn visit_pat(&mut self, p: &'hir Pat) { + fn visit_pat(&mut self, p: &'tcx Pat) { resolve_pat(self, p); } - fn visit_stmt(&mut self, s: &'hir Stmt) { + fn visit_stmt(&mut self, s: &'tcx Stmt) { resolve_stmt(self, s); } - fn visit_expr(&mut self, ex: &'hir Expr) { + fn visit_expr(&mut self, ex: &'tcx Expr) { resolve_expr(self, ex); } - fn visit_local(&mut self, l: &'hir Local) { + fn visit_local(&mut self, l: &'tcx Local) { resolve_local(self, l); } } -pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc { +pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc> { tcx.region_resolve_crate(LOCAL_CRATE) } fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Rc + -> Rc> { debug_assert!(crate_num == LOCAL_CRATE); - let sess = &tcx.sess; let hir_map = &tcx.hir; let krate = hir_map.krate(); let mut maps = RegionMaps { - code_extents: vec![], - code_extent_interner: FxHashMap(), - scope_map: vec![], + scope_map: FxHashMap(), var_map: NodeMap(), rvalue_scopes: NodeMap(), shrunk_rvalue_scopes: NodeMap(), fn_tree: NodeMap(), }; + { let mut visitor = RegionResolutionVisitor { - sess: sess, + tcx: tcx, region_maps: &mut maps, map: hir_map, cx: Context { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 724d4f457deae..8f8af8b10366e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1034,7 +1034,7 @@ pub enum Rvalue<'tcx> { Repeat(Operand<'tcx>, ConstUsize), /// &x or &mut x - Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>), + Ref(Region<'tcx>, BorrowKind, Lvalue<'tcx>), /// length of a [X] or [X;n] value Len(Lvalue<'tcx>), diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 83963de8b0014..31bdd99ef3221 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -747,7 +747,7 @@ pub enum LvalueContext<'tcx> { Inspect, // Being borrowed - Borrow { region: &'tcx Region, kind: BorrowKind }, + Borrow { region: Region<'tcx>, kind: BorrowKind }, // Used as base for another lvalue, e.g. `x` in `x.y`. // diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 908bb337fa18e..e8baaa7ffb26d 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -84,7 +84,7 @@ pub struct FulfillmentContext<'tcx> { #[derive(Clone)] pub struct RegionObligation<'tcx> { - pub sub_region: &'tcx ty::Region, + pub sub_region: ty::Region<'tcx>, pub sup_type: Ty<'tcx>, pub cause: ObligationCause<'tcx>, } @@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> { pub fn register_region_obligation(&mut self, t_a: Ty<'tcx>, - r_b: &'tcx ty::Region, + r_b: ty::Region<'tcx>, cause: ObligationCause<'tcx>) { register_region_obligation(t_a, r_b, cause, &mut self.region_obligations); @@ -566,7 +566,7 @@ fn coinductive_obligation<'a,'gcx,'tcx>(selcx: &SelectionContext<'a,'gcx,'tcx>, } fn register_region_obligation<'tcx>(t_a: Ty<'tcx>, - r_b: &'tcx ty::Region, + r_b: ty::Region<'tcx>, cause: ObligationCause<'tcx>, region_obligations: &mut NodeMap>>) { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index a7f9cc74c4f58..5ac79a8e72a50 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -112,7 +112,7 @@ pub enum ObligationCauseCode<'tcx> { ReferenceOutlivesReferent(Ty<'tcx>), /// A type like `Box + 'b>` is WF only if `'b: 'a`. - ObjectTypeBound(Ty<'tcx>, &'tcx ty::Region), + ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>), /// Obligation incurred due to an object cast. ObjectCastObligation(/* Object type */ Ty<'tcx>), diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs index b1846e0394148..f86c1cf0dd6ab 100644 --- a/src/librustc/ty/_match.rs +++ b/src/librustc/ty/_match.rs @@ -52,8 +52,8 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Match<'a, 'gcx, 'tcx> { self.relate(a, b) } - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> { + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("{}.regions({:?}, {:?})", self.tag(), a, diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 1d7100a7a4e44..385591e10f744 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -133,7 +133,7 @@ impl<'tcx> Adjustment<'tcx> { #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] pub enum AutoBorrow<'tcx> { /// Convert from T to &T. - Ref(&'tcx ty::Region, hir::Mutability), + Ref(ty::Region<'tcx>, hir::Mutability), /// Convert from T to *T. RawPtr(hir::Mutability), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c6e9822da894e..3c6f833c4ef45 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; use middle::lang_items; -use middle::region::RegionMaps; +use middle::region::{CodeExtent, CodeExtentData, RegionMaps}; use middle::resolve_lifetime; use middle::stability; use mir::Mir; @@ -33,6 +33,7 @@ use ty::{TyS, TypeVariants, Slice}; use ty::{AdtKind, AdtDef, ClosureSubsts, Region}; use hir::FreevarMap; use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; +use ty::RegionKind; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; use ty::TypeVariants::*; use ty::layout::{Layout, TargetDataLayout}; @@ -94,7 +95,7 @@ pub struct CtxtInterners<'tcx> { type_: RefCell>>>, type_list: RefCell>>>>, substs: RefCell>>>, - region: RefCell>>, + region: RefCell>>>, existential_predicates: RefCell>>>>, } @@ -192,9 +193,9 @@ pub struct CommonTypes<'tcx> { pub never: Ty<'tcx>, pub err: Ty<'tcx>, - pub re_empty: &'tcx Region, - pub re_static: &'tcx Region, - pub re_erased: &'tcx Region, + pub re_empty: Region<'tcx>, + pub re_static: Region<'tcx>, + pub re_erased: Region<'tcx>, } #[derive(RustcEncodable, RustcDecodable)] @@ -257,7 +258,7 @@ pub struct TypeckTables<'tcx> { /// Stores the free-region relationships that were deduced from /// its where clauses and parameter types. These are then /// read-again by borrowck. - pub free_region_map: FreeRegionMap, + pub free_region_map: FreeRegionMap<'tcx>, } impl<'tcx> TypeckTables<'tcx> { @@ -393,9 +394,9 @@ impl<'tcx> CommonTypes<'tcx> { f32: mk(TyFloat(ast::FloatTy::F32)), f64: mk(TyFloat(ast::FloatTy::F64)), - re_empty: mk_region(Region::ReEmpty), - re_static: mk_region(Region::ReStatic), - re_erased: mk_region(Region::ReErased), + re_empty: mk_region(RegionKind::ReEmpty), + re_static: mk_region(RegionKind::ReStatic), + re_erased: mk_region(RegionKind::ReErased), } } } @@ -549,6 +550,8 @@ pub struct GlobalCtxt<'tcx> { layout_interner: RefCell>, + code_extent_interner: RefCell>>, + /// A vector of every trait accessible in the whole crate /// (i.e. including those from subcrates). This is used only for /// error reporting, and so is lazily initialised and generally @@ -649,6 +652,38 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { interned } + pub fn node_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> { + self.intern_code_extent(CodeExtentData::Misc(n)) + } + + // TODO this is revealing side-effects of query, bad + pub fn opt_destruction_extent(self, n: ast::NodeId) -> Option> { + 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 { if let Some(layout) = self.layout_interner.borrow().get(&layout) { return layout; @@ -677,7 +712,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { local as usize == global as usize } - pub fn region_maps(self) -> Rc { + pub fn region_maps(self) -> Rc> { self.region_resolve_crate(LOCAL_CRATE) } @@ -741,6 +776,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data_layout: data_layout, layout_cache: RefCell::new(FxHashMap()), layout_interner: RefCell::new(FxHashSet()), + code_extent_interner: RefCell::new(FxHashSet()), layout_depth: Cell::new(0), derive_macros: RefCell::new(NodeMap()), stability_interner: RefCell::new(FxHashSet()), @@ -820,9 +856,18 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for &'a Region { - type Lifted = &'tcx Region; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Region> { +impl<'a, 'tcx> Lift<'tcx> for ty::FreeRegion<'a> { + type Lifted = ty::FreeRegion<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + 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> { if tcx.interners.arena.in_arena(*self as *const _) { 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 for Interned<'tcx, Region> { - fn borrow<'a>(&'a self) -> &'a Region { - self.0 +impl<'tcx> Borrow> for Interned<'tcx, RegionKind<'tcx>> { + fn borrow<'a>(&'a self) -> &'a RegionKind<'tcx> { + &self.0 } } @@ -1176,7 +1221,7 @@ direct_interners!('tcx, &ty::ReVar(_) | &ty::ReSkolemized(..) => true, _ => false } - }) -> Region + }) -> RegionKind<'tcx> ); macro_rules! slice_interners { @@ -1268,15 +1313,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.mk_ty(TyRawPtr(tm)) } - pub fn mk_ref(self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { + pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { self.mk_ty(TyRef(r, tm)) } - pub fn mk_mut_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { + pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable}) } - pub fn mk_imm_ref(self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { + pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable}) } @@ -1338,7 +1383,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn mk_dynamic( self, obj: ty::Binder<&'tcx Slice>>, - reg: &'tcx ty::Region + reg: ty::Region<'tcx> ) -> Ty<'tcx> { self.mk_ty(TyDynamic(obj, reg)) } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 73d9c8b00ae47..cec52b10736e4 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -36,11 +36,11 @@ pub enum TypeError<'tcx> { TupleSize(ExpectedFound), FixedArraySize(ExpectedFound), ArgCount, - RegionsDoesNotOutlive(&'tcx Region, &'tcx Region), - RegionsNotSame(&'tcx Region, &'tcx Region), - RegionsNoOverlap(&'tcx Region, &'tcx Region), - RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option>), - RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option>), + RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), + RegionsNotSame(Region<'tcx>, Region<'tcx>), + RegionsNoOverlap(Region<'tcx>, Region<'tcx>), + RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>, Option>), + RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>, Option>), Sorts(ExpectedFound>), IntMismatch(ExpectedFound), FloatMismatch(ExpectedFound), diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 384f99ceb4e83..686b99ba68094 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -186,7 +186,7 @@ impl FlagComputation { self.add_bound_computation(&computation); } - fn add_region(&mut self, r: &ty::Region) { + fn add_region(&mut self, r: ty::Region) { self.add_flags(r.type_flags()); if let ty::ReLateBound(debruijn, _) = *r { self.add_depth(debruijn.depth); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 1cf6c3f334f6a..21ccf6f987b89 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -159,7 +159,7 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized { sig.super_fold_with(self) } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { r.super_fold_with(self) } @@ -182,7 +182,7 @@ pub trait TypeVisitor<'tcx> : Sized { trait_ref.super_visit_with(self) } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { r.super_visit_with(self) } } @@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// whether any late-bound regions were skipped pub fn collect_regions(self, value: &T, - region_set: &mut FxHashSet<&'tcx ty::Region>) + region_set: &mut FxHashSet>) -> bool where T : TypeFoldable<'tcx> { @@ -236,7 +236,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { skipped_regions: &mut bool, mut f: F) -> T - where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region, + where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx>, T : TypeFoldable<'tcx>, { value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) @@ -256,14 +256,14 @@ pub struct RegionFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, skipped_regions: &'a mut bool, current_depth: u32, - fld_r: &'a mut (FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + 'a), + fld_r: &'a mut (FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> + 'a), } impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, skipped_regions: &'a mut bool, fld_r: &'a mut F) -> RegionFolder<'a, 'gcx, 'tcx> - where F : FnMut(&'tcx ty::Region, u32) -> &'tcx ty::Region + where F : FnMut(ty::Region<'tcx>, u32) -> ty::Region<'tcx> { RegionFolder { tcx: tcx, @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> { t } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => { debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})", @@ -309,16 +309,16 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> { struct RegionReplacer<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, current_depth: u32, - fld_r: &'a mut (FnMut(ty::BoundRegion) -> &'tcx ty::Region + 'a), - map: FxHashMap + fld_r: &'a mut (FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a), + map: FxHashMap> } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn replace_late_bound_regions(self, value: &Binder, mut f: F) - -> (T, FxHashMap) - where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region, + -> (T, FxHashMap>) + where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx>, T : TypeFoldable<'tcx>, { let mut replacer = RegionReplacer::new(self, &mut f); @@ -330,7 +330,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Replace any late-bound regions bound in `value` with free variants attached to scope-id /// `scope_id`. pub fn liberate_late_bound_regions(self, - all_outlive_scope: Option, + all_outlive_scope: Option>, value: &Binder) -> T where T : TypeFoldable<'tcx> @@ -435,7 +435,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> RegionReplacer<'a, 'gcx, 'tcx> { fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fld_r: &'a mut F) -> RegionReplacer<'a, 'gcx, 'tcx> - where F : FnMut(ty::BoundRegion) -> &'tcx ty::Region + where F : FnMut(ty::BoundRegion) -> ty::Region<'tcx> { RegionReplacer { tcx: tcx, @@ -464,7 +464,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> { t.super_fold_with(self) } - fn fold_region(&mut self, r:&'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => { let fld_r = &mut self.fld_r; @@ -527,7 +527,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { u.super_fold_with(self) } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // because late-bound regions affect subtyping, we can't // erase the bound/free distinction, but we can replace // all free regions with 'erased. @@ -554,7 +554,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // regions. See comment on `shift_regions_through_binders` method in // `subst.rs` for more details. -pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region { +pub fn shift_region<'tcx>(region: ty::RegionKind<'tcx>, amount: u32) -> ty::RegionKind<'tcx> { match region { ty::ReLateBound(debruijn, br) => { ty::ReLateBound(debruijn.shifted(amount), br) @@ -567,9 +567,9 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region { pub fn shift_region_ref<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, amount: u32) - -> &'tcx ty::Region + -> ty::Region<'tcx> { match region { &ty::ReLateBound(debruijn, br) if amount > 0 => { @@ -582,7 +582,8 @@ pub fn shift_region_ref<'a, 'gcx, 'tcx>( } pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - amount: u32, value: &T) -> T + amount: u32, + value: &T) -> T where T: TypeFoldable<'tcx> { debug!("shift_regions(value={:?}, amount={})", @@ -631,7 +632,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor { t.region_depth > self.depth } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { r.escapes_depth(self.depth) } } @@ -647,7 +648,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { flags.intersects(self.flags) } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { let flags = r.type_flags(); debug!("HasTypeFlagsVisitor: r={:?} r.flags={:?} self.flags={:?}", r, flags, self.flags); flags.intersects(self.flags) @@ -693,7 +694,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { t.super_visit_with(self) } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReLateBound(debruijn, br) if debruijn.depth == self.current_depth => { self.regions.insert(br); diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index abee0ae4ad63f..4a780b9178ecc 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -578,7 +578,7 @@ define_maps! { <'tcx> [] reachable_set: reachability_dep_node(CrateNum) -> Rc, - [] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc, + [] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc>, [] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fd0b1308c9572..e6a8459e00179 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -67,11 +67,12 @@ pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef}; pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; pub use self::sty::{ExistentialProjection, PolyExistentialProjection}; pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; +pub use self::sty::RegionKind; pub use self::sty::Issue32330; pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid}; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; -pub use self::sty::Region::*; +pub use self::sty::RegionKind::*; pub use self::sty::TypeVariants::*; pub use self::context::{TyCtxt, GlobalArenas, tls}; @@ -601,7 +602,7 @@ pub struct UpvarBorrow<'tcx> { pub kind: BorrowKind, /// Region of the resulting reference. - pub region: &'tcx ty::Region, + pub region: ty::Region<'tcx>, } pub type UpvarCaptureMap<'tcx> = FxHashMap>; @@ -934,9 +935,9 @@ pub type PolyEquatePredicate<'tcx> = ty::Binder>; #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct OutlivesPredicate(pub A, pub B); // `A : B` pub type PolyOutlivesPredicate = ty::Binder>; -pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate<&'tcx ty::Region, - &'tcx ty::Region>; -pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate, &'tcx ty::Region>; +pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate, + ty::Region<'tcx>>; +pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate, ty::Region<'tcx>>; #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct SubtypePredicate<'tcx> { @@ -1167,7 +1168,7 @@ pub struct ParameterEnvironment<'tcx> { /// region of the callee. If it is `None`, then the parameter /// environment is for an item or something where the "callee" is /// not clear. - pub implicit_region_bound: Option<&'tcx ty::Region>, + pub implicit_region_bound: Option>, /// Obligations that the caller must satisfy. This is basically /// 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 /// regions don't have this implicit scope and instead introduce /// relationships in the environment. - pub free_id_outlive: Option, + pub free_id_outlive: Option>, /// A cache for `moves_by_default`. pub is_copy_cache: RefCell, bool>>, @@ -1222,13 +1223,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let impl_def_id = tcx.hir.local_def_id(impl_id); tcx.construct_parameter_environment(impl_item.span, impl_def_id, - Some(tcx.region_maps().item_extent(id))) + Some(tcx.item_extent(id))) } hir::ImplItemKind::Method(_, ref body) => { tcx.construct_parameter_environment( impl_item.span, tcx.hir.local_def_id(id), - 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); tcx.construct_parameter_environment(trait_item.span, trait_def_id, - Some(tcx.region_maps().item_extent(id))) + Some(tcx.item_extent(id))) } hir::TraitItemKind::Method(_, ref body) => { // Use call-site for extent (unless this is a @@ -1249,10 +1250,10 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { // to the method id). let extent = if let hir::TraitMethod::Provided(body_id) = *body { // default impl: use call_site extent as free_id_outlive bound. - tcx.region_maps().call_site_extent(id, body_id.node_id) + tcx.call_site_extent(id, body_id.node_id) } else { // no default impl: use item extent as free_id_outlive bound. - tcx.region_maps().item_extent(id) + tcx.item_extent(id) }; tcx.construct_parameter_environment( trait_item.span, @@ -1270,7 +1271,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( item.span, 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::ItemStruct(..) | @@ -1282,13 +1283,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - Some(tcx.region_maps().item_extent(id))) + Some(tcx.item_extent(id))) } hir::ItemTrait(..) => { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, - Some(tcx.region_maps().item_extent(id))) + Some(tcx.item_extent(id))) } _ => { span_bug!(item.span, @@ -1306,7 +1307,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.construct_parameter_environment( expr.span, base_def_id, - Some(tcx.region_maps().call_site_extent(id, body.node_id))) + Some(tcx.call_site_extent(id, body.node_id))) } else { 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 /// free parameters. Since we currently represent bound/free type /// parameters in the same way, this only has an effect on regions. - pub fn construct_free_substs(self, def_id: DefId, - free_id_outlive: Option) + pub fn construct_free_substs(self, + def_id: DefId, + free_id_outlive: Option>) -> &'gcx Substs<'gcx> { 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, span: Span, def_id: DefId, - free_id_outlive: Option) + free_id_outlive: Option>) -> ParameterEnvironment<'gcx> { // @@ -2521,14 +2523,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { 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); let cause = traits::ObligationCause::misc(span, body_id); traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) } - pub fn node_scope_region(self, id: NodeId) -> &'tcx Region { - self.mk_region(ty::ReScope(self.region_maps().node_extent(id))) + pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> { + self.mk_region(ty::ReScope(self.node_extent(id))) } pub fn visit_all_item_likes_in_krate(self, diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index bc30f1fb71722..a544b2dd3991b 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -16,7 +16,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable}; #[derive(Debug)] pub enum Component<'tcx> { - Region(&'tcx ty::Region), + Region(ty::Region<'tcx>), Param(ty::ParamTy), UnresolvedInferenceVariable(ty::InferTy), @@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } -fn push_region_constraints<'tcx>(out: &mut Vec>, regions: Vec<&'tcx ty::Region>) { +fn push_region_constraints<'tcx>(out: &mut Vec>, regions: Vec>) { for r in regions { if !r.is_bound() { out.push(Component::Region(r)); diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 58ebc843da106..ac434c01c6a88 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -67,8 +67,8 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>; - fn regions(&mut self, a: &'tcx ty::Region, b: &'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region>; + fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>>; fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) -> RelateResult<'tcx, ty::Binder> @@ -529,11 +529,11 @@ impl<'tcx> Relate<'tcx> for &'tcx Substs<'tcx> { } } -impl<'tcx> Relate<'tcx> for &'tcx ty::Region { +impl<'tcx> Relate<'tcx> for ty::Region<'tcx> { fn relate<'a, 'gcx, R>(relation: &mut R, - a: &&'tcx ty::Region, - b: &&'tcx ty::Region) - -> RelateResult<'tcx, &'tcx ty::Region> + a: &ty::Region<'tcx>, + b: &ty::Region<'tcx>) + -> RelateResult<'tcx, ty::Region<'tcx>> where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a { relation.regions(*a, *b) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index a4466d7d84011..53d516e581b2a 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -624,7 +624,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region { +impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { *self } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 02c4bad8e4e1c..1ec8fd572a4ce 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -47,8 +47,8 @@ pub struct TypeAndMut<'tcx> { /// If `fr.scope` is None, then this is in some context (e.g., an /// impl) where lifetimes are more abstract and the notion of the /// caller/callee stack frames are not applicable. -pub struct FreeRegion { - pub scope: Option, +pub struct FreeRegion<'tcx> { + pub scope: Option>, pub bound_region: BoundRegion, } @@ -128,7 +128,7 @@ pub enum TypeVariants<'tcx> { /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - TyRef(&'tcx Region, TypeAndMut<'tcx>), + TyRef(Region<'tcx>, TypeAndMut<'tcx>), /// The anonymous type of a function declaration/definition. Each /// function has a unique type. @@ -140,7 +140,7 @@ pub enum TypeVariants<'tcx> { TyFnPtr(PolyFnSig<'tcx>), /// A trait, defined with `trait`. - TyDynamic(Binder<&'tcx Slice>>, &'tcx ty::Region), + TyDynamic(Binder<&'tcx Slice>>, ty::Region<'tcx>), /// The anonymous type of a closure. Used to represent the type of /// `|a| a`. @@ -679,6 +679,8 @@ pub struct DebruijnIndex { pub depth: u32, } +pub type Region<'tcx> = &'tcx RegionKind<'tcx>; + /// Representation of regions. /// /// Unlike types, most region variants are "fictitious", not concrete, @@ -736,7 +738,7 @@ pub struct DebruijnIndex { /// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)] -pub enum Region { +pub enum RegionKind<'tcx> { // Region bound in a type or fn declaration which will be // substituted 'early' -- that is, at the same time when type // parameters are substituted. @@ -749,12 +751,12 @@ pub enum Region { /// When checking a function body, the types of all arguments and so forth /// that refer to bound region parameters are modified to refer to free /// region parameters. - ReFree(FreeRegion), + ReFree(FreeRegion<'tcx>), /// A concrete region naming some statically determined extent /// (e.g. an expression or sequence of statements) within the /// current function. - ReScope(region::CodeExtent), + ReScope(region::CodeExtent<'tcx>), /// Static data that has an "infinite" lifetime. Top in the region lattice. ReStatic, @@ -779,7 +781,7 @@ pub enum Region { ReErased, } -impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Region {} +impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {} #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub struct EarlyBoundRegion { @@ -898,7 +900,7 @@ impl DebruijnIndex { } // Region utilities -impl Region { +impl<'tcx> RegionKind<'tcx> { pub fn is_bound(&self) -> bool { match *self { ty::ReEarlyBound(..) => true, @@ -922,7 +924,7 @@ impl Region { } /// Returns the depth of `self` from the (1-based) binding level `depth` - pub fn from_depth(&self, depth: u32) -> Region { + pub fn from_depth(&self, depth: u32) -> RegionKind<'tcx> { match *self { ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex { depth: debruijn.depth - (depth - 1) @@ -1334,7 +1336,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { /// Returns the regions directly referenced from this type (but /// not types reachable from this type via `walk_tys`). This /// ignores late-bound regions binders. - pub fn regions(&self) -> Vec<&'tcx ty::Region> { + pub fn regions(&self) -> Vec> { match self.sty { TyRef(region, _) => { vec![region] diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 961140d5eac60..c591845dd63b1 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -11,7 +11,7 @@ // Type substitutions. use hir::def_id::DefId; -use ty::{self, Slice, Ty, TyCtxt}; +use ty::{self, Slice, Region, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use serialize::{self, Encodable, Encoder, Decodable, Decoder}; @@ -32,7 +32,7 @@ use std::mem; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Kind<'tcx> { ptr: NonZero, - marker: PhantomData<(Ty<'tcx>, &'tcx ty::Region)> + marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)> } const TAG_MASK: usize = 0b11; @@ -54,8 +54,8 @@ impl<'tcx> From> for Kind<'tcx> { } } -impl<'tcx> From<&'tcx ty::Region> for Kind<'tcx> { - fn from(r: &'tcx ty::Region) -> Kind<'tcx> { +impl<'tcx> From> for Kind<'tcx> { + fn from(r: ty::Region<'tcx>) -> Kind<'tcx> { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(r) & TAG_MASK, 0); @@ -88,7 +88,7 @@ impl<'tcx> Kind<'tcx> { } #[inline] - pub fn as_region(self) -> Option<&'tcx ty::Region> { + pub fn as_region(self) -> Option> { unsafe { self.downcast(REGION_TAG) } @@ -153,7 +153,7 @@ impl<'tcx> Decodable for Kind<'tcx> { d.read_enum_variant(&["Ty", "Region"], |d, tag| { match tag { TYPE_TAG => Ty::decode(d).map(Kind::from), - REGION_TAG => <&ty::Region>::decode(d).map(Kind::from), + REGION_TAG => Region::decode(d).map(Kind::from), _ => Err(d.error("invalid Kind tag")) } }) @@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { mut mk_region: FR, mut mk_type: FT) -> &'tcx Substs<'tcx> - where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { let defs = tcx.generics_of(def_id); let mut substs = Vec::with_capacity(defs.count()); @@ -197,7 +197,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { mut mk_region: FR, mut mk_type: FT) -> &'tcx Substs<'tcx> - where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { let defs = tcx.generics_of(def_id); @@ -212,7 +212,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { defs: &ty::Generics, mk_region: &mut FR, mk_type: &mut FT) - where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { if let Some(def_id) = defs.parent { @@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { defs: &ty::Generics, mk_region: &mut FR, mk_type: &mut FT) - where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region, + where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { // Handle Self first, before all regions. let mut types = defs.types.iter(); @@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } #[inline] - pub fn regions(&'a self) -> impl DoubleEndedIterator + 'a { + pub fn regions(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| k.as_region()) } @@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } #[inline] - pub fn region_at(&self, i: usize) -> &'tcx ty::Region { + pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { self[i].as_region().unwrap_or_else(|| { bug!("expected region for param #{} in {:?}", i, self); }) @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } #[inline] - pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> &'tcx ty::Region { + pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region<'tcx> { self.region_at(def.index as usize) } @@ -396,7 +396,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> { t } - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those // bound in *fn types*. Region substitution of the bound @@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { result } - fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region { + fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> { if self.region_binders_passed == 0 || !region.has_escaping_regions() { return region; } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 87921c80502e0..befc4e6c5fdd1 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -316,7 +316,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn required_region_bounds(self, erased_self_ty: Ty<'tcx>, predicates: Vec>) - -> Vec<&'tcx ty::Region> { + -> Vec> { debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})", erased_self_ty, predicates); @@ -457,7 +457,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let result = item_substs.iter().zip(impl_substs.iter()) .filter(|&(_, &k)| { - if let Some(&ty::Region::ReEarlyBound(ref ebr)) = k.as_region() { + if let Some(&ty::RegionKind::ReEarlyBound(ref ebr)) = k.as_region() { !impl_generics.region_param(ebr).pure_wrt_drop } else if let Some(&ty::TyS { sty: ty::TypeVariants::TyParam(ref pt), .. @@ -673,7 +673,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> ty.super_visit_with(self) } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { self.hash_discriminant_u8(r); match *r { ty::ReErased | diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 6c7073de70bbd..d0cbbaf2c10bf 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -116,9 +116,9 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, /// For `&'a T` to be WF, `T: 'a` must hold. So we can assume `T: 'a`. #[derive(Debug)] pub enum ImpliedBound<'tcx> { - RegionSubRegion(&'tcx ty::Region, &'tcx ty::Region), - RegionSubParam(&'tcx ty::Region, ty::ParamTy), - RegionSubProjection(&'tcx ty::Region, ty::ProjectionTy<'tcx>), + RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), + RegionSubParam(ty::Region<'tcx>, ty::ParamTy), + RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), } /// Compute the implied bounds that a callee/impl can assume based on @@ -198,7 +198,7 @@ pub fn implied_bounds<'a, 'gcx, 'tcx>( /// this down to determine what relationships would have to hold for /// `T: 'a` to hold. We get to assume that the caller has validated /// those relationships. -fn implied_bounds_from_components<'tcx>(sub_region: &'tcx ty::Region, +fn implied_bounds_from_components<'tcx>(sub_region: ty::Region<'tcx>, sup_components: Vec>) -> Vec> { @@ -455,7 +455,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { fn from_object_ty(&mut self, ty: Ty<'tcx>, data: ty::Binder<&'tcx ty::Slice>>, - region: &'tcx ty::Region) { + region: ty::Region<'tcx>) { // Imagine a type like this: // // trait Foo { } @@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { pub fn object_region_bounds<'a, 'gcx, 'tcx>( tcx: TyCtxt<'a, 'gcx, 'tcx>, existential_predicates: ty::Binder<&'tcx ty::Slice>>) - -> Vec<&'tcx ty::Region> + -> Vec> { // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index df5a2731c8900..d773bb2da0898 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -177,12 +177,12 @@ pub fn parameterized(f: &mut fmt::Formatter, let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| { // Don't print any regions if they're all erased. let regions = || substs.regions().skip(skip).take(count); - if regions().all(|r: &ty::Region| *r == ty::ReErased) { + if regions().all(|r: ty::Region| *r == ty::ReErased) { return Ok(()); } for region in regions() { - let region: &ty::Region = region; + let region: ty::Region = region; start_or_continue(f, start, ", ")?; if verbose { write!(f, "{:?}", region)?; @@ -458,7 +458,7 @@ impl fmt::Debug for ty::BoundRegion { } } -impl fmt::Debug for ty::Region { +impl<'tcx> fmt::Debug for ty::RegionKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ty::ReEarlyBound(ref data) => { @@ -516,7 +516,7 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> { } } -impl fmt::Display for ty::Region { +impl<'tcx> fmt::Display for ty::RegionKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if verbose() { return write!(f, "{:?}", *self); @@ -544,7 +544,7 @@ impl fmt::Display for ty::Region { } } -impl fmt::Debug for ty::FreeRegion { +impl<'tcx> fmt::Debug for ty::FreeRegion<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region) @@ -689,14 +689,14 @@ impl<'tcx> fmt::Display for ty::Binder> { } } -impl<'tcx> fmt::Display for ty::Binder, &'tcx ty::Region>> { +impl<'tcx> fmt::Display for ty::Binder, ty::Region<'tcx>>> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) } } -impl<'tcx> fmt::Display for ty::Binder> { +impl<'tcx> fmt::Display for ty::Binder, + ty::Region<'tcx>>> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self))) } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 97cf9253038e7..96753d63af203 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { @@ -232,14 +232,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }) } - pub fn each_in_scope_loan(&self, scope: region::CodeExtent, mut op: F) -> bool where + pub fn each_in_scope_loan(&self, scope: region::CodeExtent<'tcx>, mut op: F) -> bool where F: FnMut(&Loan<'tcx>) -> bool, { //! Like `each_issued_loan()`, but only considers loans that are //! currently in scope. let tcx = self.tcx(); - self.each_issued_loan(scope.node_id(&tcx.region_maps()), |loan| { + self.each_issued_loan(scope.node_id(), |loan| { if tcx.region_maps().is_subscope_of(scope, loan.kill_scope) { op(loan) } else { @@ -249,7 +249,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } fn each_in_scope_loan_affecting_path(&self, - scope: region::CodeExtent, + scope: region::CodeExtent<'tcx>, loan_path: &LoanPath<'tcx>, mut op: F) -> bool where @@ -460,8 +460,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // 3. Where does old loan expire. let previous_end_span = - self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps())) - .end_point(); + self.tcx().hir.span(old_loan.kill_scope.node_id()).end_point(); let mut err = match (new_loan.kind, old_loan.kind) { (ty::MutBorrow, ty::MutBorrow) => { @@ -710,7 +709,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let mut ret = UseOk; self.each_in_scope_loan_affecting_path( - self.tcx().region_maps().node_extent(expr_id), use_path, |loan| { + self.tcx().node_extent(expr_id), use_path, |loan| { if !compatible_borrow_kinds(loan.kind, borrow_kind) { ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); false @@ -824,7 +823,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // Check that we don't invalidate any outstanding loans if let Some(loan_path) = opt_loan_path(&assignee_cmt) { - let scope = self.tcx().region_maps().node_extent(assignment_id); + let scope = self.tcx().node_extent(assignment_id); self.each_in_scope_loan_affecting_path(scope, &loan_path, |loan| { self.report_illegal_mutation(assignment_span, &loan_path, loan); false diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 2dfb4f1dd82d3..9f8ffd86f5414 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -24,11 +24,11 @@ use syntax_pos::Span; type R = Result<(),()>; pub fn guarantee_lifetime<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - item_scope: region::CodeExtent, + item_scope: region::CodeExtent<'tcx>, span: Span, cause: euv::LoanCause, cmt: mc::cmt<'tcx>, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, _: ty::BorrowKind) -> Result<(),()> { //! Reports error if `loan_region` is larger than S @@ -52,11 +52,11 @@ struct GuaranteeLifetimeContext<'a, 'tcx: 'a> { bccx: &'a BorrowckCtxt<'a, 'tcx>, // the scope of the function body for the enclosing item - item_scope: region::CodeExtent, + item_scope: region::CodeExtent<'tcx>, span: Span, cause: euv::LoanCause, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, cmt_original: mc::cmt<'tcx> } @@ -92,7 +92,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn check_scope(&self, max_scope: &'tcx ty::Region) -> R { + fn check_scope(&self, max_scope: ty::Region<'tcx>) -> R { //! Reports an error if `loan_region` is larger than `max_scope` if !self.bccx.is_subregion_of(self.loan_region, max_scope) { @@ -102,7 +102,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } } - fn scope(&self, cmt: &mc::cmt<'tcx>) -> &'tcx ty::Region { + fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'tcx> { //! Returns the maximal region scope for the which the //! lvalue `cmt` is guaranteed to be valid without any //! rooting etc, and presuming `cmt` is not mutated. diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index f5cdd40714cdb..09ed515939de6 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -45,7 +45,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx: bccx, infcx: &infcx, all_loans: Vec::new(), - item_ub: bccx.tcx.region_maps().node_extent(body.node_id), + item_ub: bccx.tcx.node_extent(body.node_id), move_data: MoveData::new(), move_error_collector: move_error::MoveErrorCollector::new(), }; @@ -66,7 +66,7 @@ struct GatherLoanCtxt<'a, 'tcx: 'a> { all_loans: Vec>, /// `item_ub` is used as an upper-bound on the lifetime whenever we /// ask for the scope of an expression categorized as an upvar. - item_ub: region::CodeExtent, + item_ub: region::CodeExtent<'tcx>, } impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { @@ -127,7 +127,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { borrow_id: ast::NodeId, borrow_span: Span, cmt: mc::cmt<'tcx>, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { @@ -299,7 +299,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { borrow_span: Span, cmt: mc::cmt<'tcx>, req_kind: ty::BorrowKind, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, cause: euv::LoanCause) { debug!("guarantee_valid(borrow_id={}, cmt={:?}, \ req_mutbl={:?}, loan_region={:?})", @@ -371,7 +371,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { }; debug!("loan_scope = {:?}", loan_scope); - let borrow_scope = self.tcx().region_maps().node_extent(borrow_id); + let borrow_scope = self.tcx().node_extent(borrow_id); let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope); debug!("gen_scope = {:?}", gen_scope); @@ -450,9 +450,9 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } pub fn compute_gen_scope(&self, - borrow_scope: region::CodeExtent, - loan_scope: region::CodeExtent) - -> region::CodeExtent { + borrow_scope: region::CodeExtent<'tcx>, + loan_scope: region::CodeExtent<'tcx>) + -> region::CodeExtent<'tcx> { //! Determine when to introduce the loan. Typically the loan //! is introduced at the point of the borrow, but in some cases, //! notably method arguments, the loan may be introduced only @@ -465,8 +465,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } } - pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent, lp: &LoanPath<'tcx>) - -> region::CodeExtent { + pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent<'tcx>, lp: &LoanPath<'tcx>) + -> region::CodeExtent<'tcx> { //! Determine when the loan restrictions go out of scope. //! This is either when the lifetime expires or when the //! local variable which roots the loan-path goes out of scope, diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index fdcefdc0d4307..7f90a8b19d4a1 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -31,7 +31,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, span: Span, cause: euv::LoanCause, cmt: mc::cmt<'tcx>, - loan_region: &'tcx ty::Region) + loan_region: ty::Region<'tcx>) -> RestrictionResult<'tcx> { let ctxt = RestrictionsContext { bccx: bccx, @@ -49,7 +49,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, struct RestrictionsContext<'a, 'tcx: 'a> { bccx: &'a BorrowckCtxt<'a, 'tcx>, span: Span, - loan_region: &'tcx ty::Region, + loan_region: ty::Region<'tcx>, cause: euv::LoanCause, } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 2baec7418eb27..1a7c700e23955 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -141,9 +141,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, id_range, all_loans.len()); for (loan_idx, loan) in all_loans.iter().enumerate() { - loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps()), loan_idx); + loan_dfcx.add_gen(loan.gen_scope.node_id(), loan_idx); loan_dfcx.add_kill(KillFrom::ScopeEnd, - loan.kill_scope.node_id(&tcx.region_maps()), loan_idx); + loan.kill_scope.node_id(), loan_idx); } loan_dfcx.add_kills_from_flow_exits(cfg); loan_dfcx.propagate(cfg, body); @@ -206,13 +206,13 @@ pub struct Loan<'tcx> { /// cases, notably method arguments, the loan may be introduced /// only later, once it comes into scope. See also /// `GatherLoanCtxt::compute_gen_scope`. - gen_scope: region::CodeExtent, + gen_scope: region::CodeExtent<'tcx>, /// kill_scope indicates when the loan goes out of scope. This is /// either when the lifetime expires or when the local variable /// which roots the loan-path goes out of scope, whichever happens /// faster. See also `GatherLoanCtxt::compute_kill_scope`. - kill_scope: region::CodeExtent, + kill_scope: region::CodeExtent<'tcx>, span: Span, cause: euv::LoanCause, } @@ -312,12 +312,12 @@ pub fn closure_to_block(closure_id: ast::NodeId, } impl<'a, 'tcx> LoanPath<'tcx> { - pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent { + pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent<'tcx> { match self.kind { LpVar(local_id) => tcx.region_maps().var_scope(local_id), LpUpvar(upvar_id) => { let block_id = closure_to_block(upvar_id.closure_expr_id, tcx); - tcx.region_maps().node_extent(block_id) + tcx.node_extent(block_id) } LpDowncast(ref base, _) | LpExtend(ref base, ..) => base.kill_scope(tcx), @@ -444,8 +444,8 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option>> { pub enum bckerr_code<'tcx> { err_mutbl, /// superscope, subscope, loan cause - err_out_of_scope(&'tcx ty::Region, &'tcx ty::Region, euv::LoanCause), - err_borrowed_pointer_too_short(&'tcx ty::Region, &'tcx ty::Region), // loan, ptr + err_out_of_scope(ty::Region<'tcx>, ty::Region<'tcx>, euv::LoanCause), + err_borrowed_pointer_too_short(ty::Region<'tcx>, ty::Region<'tcx>), // loan, ptr } // Combination of an error code and the categorization of the expression @@ -475,8 +475,8 @@ pub enum MovedValueUseKind { impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { pub fn is_subregion_of(&self, - r_sub: &'tcx ty::Region, - r_sup: &'tcx ty::Region) + r_sub: ty::Region<'tcx>, + r_sup: ty::Region<'tcx>) -> bool { self.tables.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup) @@ -963,10 +963,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { .emit(); } - fn region_end_span(&self, region: &'tcx ty::Region) -> Option { + fn region_end_span(&self, region: ty::Region<'tcx>) -> Option { match *region { ty::ReScope(scope) => { - match scope.span(&self.tcx.region_maps(), &self.tcx.hir) { + match scope.span(&self.tcx.hir) { Some(s) => { Some(s.end_point()) } @@ -1244,10 +1244,10 @@ before rustc 1.16, this temporary lived longer - see issue #39283 \ } } -fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option { +fn statement_scope_span(tcx: TyCtxt, region: ty::Region) -> Option { match *region { ty::ReScope(scope) => { - match tcx.hir.find(scope.node_id(&tcx.region_maps())) { + match tcx.hir.find(scope.node_id()) { Some(hir_map::NodeStmt(stmt)) => Some(stmt.span), _ => None } diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 60d0ab5ff823a..3d7df7f037213 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -548,7 +548,7 @@ impl<'a, 'tcx> MoveData<'tcx> { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { let kill_scope = path.loan_path.kill_scope(tcx); let path = *self.path_map.borrow().get(&path.loan_path).unwrap(); - self.kill_moves(path, kill_scope.node_id(&tcx.region_maps()), + self.kill_moves(path, kill_scope.node_id(), KillFrom::ScopeEnd, dfcx_moves); } LpExtend(..) => {} @@ -563,7 +563,7 @@ impl<'a, 'tcx> MoveData<'tcx> { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { let kill_scope = lp.kill_scope(tcx); dfcx_assign.add_kill(KillFrom::ScopeEnd, - kill_scope.node_id(&tcx.region_maps()), + kill_scope.node_id(), assignment_index); } LpExtend(..) => { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 2e0afe789c62d..5a2fc9adc2f02 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -533,7 +533,7 @@ impl<'a, 'gcx, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'gcx> { _: ast::NodeId, span: Span, _: cmt, - _: &'tcx ty::Region, + _: ty::Region<'tcx>, kind:ty:: BorrowKind, _: LoanCause) { match kind { diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index aea40b8553548..e15d63a63c258 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -35,7 +35,7 @@ pub enum PatternError<'tcx> { #[derive(Copy, Clone, Debug)] pub enum BindingMode<'tcx> { ByValue, - ByRef(&'tcx Region, BorrowKind), + ByRef(Region<'tcx>, BorrowKind), } #[derive(Clone, Debug)] @@ -811,7 +811,7 @@ macro_rules! CloneImpls { } CloneImpls!{ <'tcx> - Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region, + Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef, &'tcx Substs<'tcx>, &'tcx Kind<'tcx> } diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 2631108aeb5fa..b0fca5c0ff377 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -80,6 +80,27 @@ impl TransitiveRelation { } } + /// 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(&self, mut f: F) -> Option> + where F: FnMut(&T) -> Option, + U: Debug + PartialEq, + { + let mut result = TransitiveRelation::new(); + for edge in &self.edges { + let r = f(&self.elements[edge.source.0]).and_then(|source| { + f(&self.elements[edge.target.0]).and_then(|target| { + Some(result.add(source, target)) + }) + }); + if r.is_none() { + return None; + } + } + Some(result) + } + /// Indicate that `a < b` (where `<` is this relation) pub fn add(&mut self, a: T, b: T) { let a = self.add_index(a); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a19bc4aea2c9d..38f9854857115 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -293,7 +293,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { self.infcx.tcx.mk_param(index, Symbol::intern(&name)) } - pub fn re_early_bound(&self, index: u32, name: &'static str) -> &'tcx ty::Region { + pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> { let name = Symbol::intern(name); self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { index: index, @@ -304,11 +304,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn re_late_bound_with_debruijn(&self, id: u32, debruijn: ty::DebruijnIndex) - -> &'tcx ty::Region { + -> ty::Region<'tcx> { self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id))) } - pub fn t_rptr(&self, r: &'tcx ty::Region) -> Ty<'tcx> { + pub fn t_rptr(&self, r: ty::Region<'tcx>) -> Ty<'tcx> { self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } @@ -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) } - pub fn re_free(&self, nid: ast::NodeId, id: u32) -> &'tcx ty::Region { + pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> { self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: self.tcx().region_maps.item_extent(nid), bound_region: ty::BrAnon(id), diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 28fea2eec60f0..9f4625c2ce305 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -20,6 +20,7 @@ use rustc::middle::cstore::LinkagePreference; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::middle::lang_items; +use rustc::middle::region; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; @@ -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> { - fn specialized_decode(&mut self) -> Result<&'tcx ty::Region, Self::Error> { +impl<'a, 'tcx> SpecializedDecoder> for DecodeContext<'a, 'tcx> { + fn specialized_decode(&mut self) -> Result, Self::Error> { Ok(self.tcx().mk_region(Decodable::decode(self)?)) } } +impl<'a, 'tcx> SpecializedDecoder> for DecodeContext<'a, 'tcx> { + fn specialized_decode(&mut self) -> Result, Self::Error> { + Ok(self.tcx().intern_code_extent(Decodable::decode(self)?)) + } +} + impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice>> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice>, Self::Error> { Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?) diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index f99f41c633e9f..d81de954dbf15 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -83,7 +83,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let_extent_stack.push(remainder_scope); // Declare the bindings, which may create a visibility scope. - let remainder_span = remainder_scope.span(&tcx.region_maps(), &tcx.hir); + let remainder_span = remainder_scope.span(&tcx.hir); let remainder_span = remainder_span.unwrap_or(span); let scope = this.declare_bindings(None, remainder_span, &pattern); diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index 8d79e755685d0..22a36bb21d875 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// The operand is known to be live until the end of `scope`. pub fn as_operand(&mut self, block: BasicBlock, - scope: Option, + scope: Option>, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>> { @@ -49,7 +49,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn expr_as_operand(&mut self, mut block: BasicBlock, - scope: Option, + scope: Option>, expr: Expr<'tcx>) -> BlockAnd> { debug!("expr_as_operand(block={:?}, expr={:?})", block, expr); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index fb547332c5f58..8dc7745cd9eb9 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -38,7 +38,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } /// Compile `expr`, yielding an rvalue. - pub fn as_rvalue(&mut self, block: BasicBlock, scope: Option, expr: M) + pub fn as_rvalue(&mut self, block: BasicBlock, scope: Option>, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>> { @@ -48,7 +48,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn expr_as_rvalue(&mut self, mut block: BasicBlock, - scope: Option, + scope: Option>, expr: Expr<'tcx>) -> BlockAnd> { debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr); diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index a334923546fb2..db4561af734d5 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -21,7 +21,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// up rvalues so as to freeze the value that will be consumed. pub fn as_temp(&mut self, block: BasicBlock, - temp_lifetime: Option, + temp_lifetime: Option>, expr: M) -> BlockAnd> where M: Mirror<'tcx, Output = Expr<'tcx>> @@ -32,7 +32,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn expr_as_temp(&mut self, mut block: BasicBlock, - temp_lifetime: Option, + temp_lifetime: Option>, expr: Expr<'tcx>) -> BlockAnd> { debug!("expr_as_temp(block={:?}, expr={:?})", block, expr); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f3a258a8ca58a..6c01e4315f3e9 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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 call_site_extent = - tcx.region_maps().lookup_code_extent( + tcx.intern_code_extent( CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body.value.id }); let arg_extent = - tcx.region_maps().lookup_code_extent( + tcx.intern_code_extent( CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.value.id }); let mut block = START_BLOCK; unpack!(block = builder.in_scope(call_site_extent, block, |builder| { @@ -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 region_maps = tcx.region_maps(); - let extent = region_maps.temporary_scope(ast_expr.id) - .unwrap_or(region_maps.item_extent(owner_id)); + let extent = region_maps.temporary_scope(tcx, ast_expr.id) + .unwrap_or(tcx.item_extent(owner_id)); let mut block = START_BLOCK; let _ = builder.in_scope(extent, block, |builder| { let expr = builder.hir.mirror(ast_expr); @@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn args_and_body(&mut self, mut block: BasicBlock, arguments: &[(Ty<'gcx>, Option<&'gcx hir::Pat>)], - argument_extent: CodeExtent, + argument_extent: CodeExtent<'tcx>, ast_body: &'gcx hir::Expr) -> BlockAnd<()> { diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 2a024454ecb4a..fcd06835d9869 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -102,7 +102,7 @@ pub struct Scope<'tcx> { visibility_scope: VisibilityScope, /// the extent of this scope within source code. - extent: CodeExtent, + extent: CodeExtent<'tcx>, /// Whether there's anything to do for the cleanup path, that is, /// when unwinding through this scope. This includes destructors, @@ -137,7 +137,7 @@ pub struct Scope<'tcx> { free: Option>, /// The cache for drop chain on “normal” exit into a particular BasicBlock. - cached_exits: FxHashMap<(BasicBlock, CodeExtent), BasicBlock>, + cached_exits: FxHashMap<(BasicBlock, CodeExtent<'tcx>), BasicBlock>, } struct DropData<'tcx> { @@ -180,7 +180,7 @@ struct FreeData<'tcx> { #[derive(Clone, Debug)] pub struct BreakableScope<'tcx> { /// Extent of the loop - pub extent: CodeExtent, + pub extent: CodeExtent<'tcx>, /// Where the body of the loop begins. `None` if block pub continue_block: Option, /// Block to branch into when the loop or block terminates (either by being `break`-en out @@ -248,10 +248,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// /// Returns the might_break attribute of the BreakableScope used. pub fn in_breakable_scope(&mut self, - loop_block: Option, - break_block: BasicBlock, - break_destination: Lvalue<'tcx>, - f: F) -> R + loop_block: Option, + break_block: BasicBlock, + break_destination: Lvalue<'tcx>, + f: F) -> R where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> R { let extent = self.topmost_scope(); @@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. - pub fn in_scope(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F) -> BlockAnd + pub fn in_scope(&mut self, extent: CodeExtent<'tcx>, mut block: BasicBlock, f: F) -> BlockAnd where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { 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 /// calls must be paired; using `in_scope` as a convenience /// wrapper maybe preferable. - pub fn push_scope(&mut self, extent: CodeExtent) { + pub fn push_scope(&mut self, extent: CodeExtent<'tcx>) { debug!("push_scope({:?})", extent); let vis_scope = self.visibility_scope; self.scopes.push(Scope { @@ -302,7 +302,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// drops onto the end of `block` that are needed. This must /// match 1-to-1 with `push_scope`. pub fn pop_scope(&mut self, - extent: CodeExtent, + extent: CodeExtent<'tcx>, mut block: BasicBlock) -> BlockAnd<()> { debug!("pop_scope({:?}, {:?})", extent, block); @@ -326,7 +326,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// module comment for details. pub fn exit_scope(&mut self, span: Span, - extent: CodeExtent, + extent: CodeExtent<'tcx>, mut block: BasicBlock, target: BasicBlock) { debug!("exit_scope(extent={:?}, block={:?}, target={:?})", extent, block, target); @@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// resolving `break` and `continue`. pub fn find_breakable_scope(&mut self, span: Span, - label: CodeExtent) + label: CodeExtent<'tcx>) -> &mut BreakableScope<'tcx> { // find the loop-scope with the correct id self.breakable_scopes.iter_mut() @@ -407,11 +407,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Returns the extent of the scope which should be exited by a /// return. - pub fn extent_of_return_scope(&self) -> CodeExtent { + pub fn extent_of_return_scope(&self) -> CodeExtent<'tcx> { // The outermost scope (`scopes[0]`) will be the `CallSiteScope`. // We want `scopes[1]`, which is the `ParameterScope`. assert!(self.scopes.len() >= 2); - assert!(match self.hir.tcx().region_maps().code_extent_data(self.scopes[1].extent) { + assert!(match *self.scopes[1].extent { CodeExtentData::ParameterScope { .. } => true, _ => false, }); @@ -420,7 +420,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Returns the topmost active scope, which is known to be alive until /// the next scope expression. - pub fn topmost_scope(&self) -> CodeExtent { + pub fn topmost_scope(&self) -> CodeExtent<'tcx> { self.scopes.last().expect("topmost_scope: no scopes present").extent } @@ -430,7 +430,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// `extent`. pub fn schedule_drop(&mut self, span: Span, - extent: CodeExtent, + extent: CodeExtent<'tcx>, lvalue: &Lvalue<'tcx>, lvalue_ty: Ty<'tcx>) { let needs_drop = self.hir.needs_drop(lvalue_ty); @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { scope.needs_cleanup = true; } let tcx = self.hir.tcx(); - let extent_span = extent.span(&tcx.region_maps(), &tcx.hir).unwrap(); + let extent_span = extent.span(&tcx.hir).unwrap(); // Attribute scope exit drops to scope's closing brace let scope_end = Span { lo: extent_span.hi, .. extent_span}; scope.drops.push(DropData { @@ -520,7 +520,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// There may only be one “free” scheduled in any given scope. pub fn schedule_box_free(&mut self, span: Span, - extent: CodeExtent, + extent: CodeExtent<'tcx>, value: &Lvalue<'tcx>, item_ty: Ty<'tcx>) { for scope in self.scopes.iter_mut().rev() { diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 1be07fba2b0cd..15c2df55cf3c8 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -24,7 +24,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { let stmts = mirror_stmts(cx, self.id, &*self.stmts); Block { targeted_by_break: self.targeted_by_break, - extent: cx.tcx.region_maps().node_extent(self.id), + extent: cx.tcx.node_extent(self.id), span: self.span, stmts: stmts, expr: self.expr.to_ref(), @@ -44,7 +44,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, result.push(StmtRef::Mirror(Box::new(Stmt { span: stmt.span, kind: StmtKind::Expr { - scope: cx.tcx.region_maps().node_extent(id), + scope: cx.tcx.node_extent(id), expr: expr.to_ref(), }, }))) @@ -60,14 +60,14 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, first_statement_index: index as u32, }); let remainder_extent = - cx.tcx.region_maps().lookup_code_extent(remainder_extent); + cx.tcx.intern_code_extent(remainder_extent); let pattern = Pattern::from_hir(cx.tcx, cx.tables(), &local.pat); result.push(StmtRef::Mirror(Box::new(Stmt { span: stmt.span, kind: StmtKind::Let { remainder_scope: remainder_extent, - init_scope: cx.tcx.region_maps().node_extent(id), + init_scope: cx.tcx.node_extent(id), pattern: pattern, initializer: local.init.to_ref(), }, @@ -84,7 +84,7 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { let block_ty = cx.tables().node_id_to_type(block.id); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(block.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, block.id); let expr = Expr { ty: block_ty, temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index ad51530b19152..e37df8822c892 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -26,8 +26,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(self.id); - let expr_extent = cx.tcx.region_maps().node_extent(self.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, self.id); + let expr_extent = cx.tcx.node_extent(self.id); debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span); @@ -216,7 +216,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; // Finally, create a destruction scope, if any. - if let Some(extent) = cx.tcx.region_maps().opt_destruction_extent(self.id) { + if let Some(extent) = cx.tcx.opt_destruction_extent(self.id) { expr = Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -238,7 +238,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { let expr_ty = cx.tables().expr_ty(expr); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); let kind = match expr.node { // Here comes the interesting stuff: @@ -610,7 +610,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, match dest.target_id { hir::ScopeTarget::Block(target_id) | hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(target_id)) => ExprKind::Break { - label: cx.tcx.region_maps().node_extent(target_id), + label: cx.tcx.node_extent(target_id), value: value.to_ref(), }, hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) => @@ -621,7 +621,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, match dest.target_id { hir::ScopeTarget::Block(_) => bug!("cannot continue to blocks"), hir::ScopeTarget::Loop(hir::LoopIdResult::Ok(loop_id)) => ExprKind::Continue { - label: cx.tcx.region_maps().node_extent(loop_id), + label: cx.tcx.node_extent(loop_id), }, hir::ScopeTarget::Loop(hir::LoopIdResult::Err(err)) => bug!("invalid loop id for continue: {}", err) @@ -686,7 +686,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprBox(ref value) => { ExprKind::Box { value: value.to_ref(), - value_extents: cx.tcx.region_maps().node_extent(value.id), + value_extents: cx.tcx.node_extent(value.id), } } hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() }, @@ -707,7 +707,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, method_call: ty::MethodCall) -> Expr<'tcx> { let callee = cx.tables().method_map[&method_call]; - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -791,7 +791,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); match def { Def::Local(def_id) => { @@ -827,8 +827,8 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will // have a bound region with number 0 - let region = ty::Region::ReFree(ty::FreeRegion { - scope: Some(cx.tcx.region_maps().node_extent(body_id)), + let region = ty::ReFree(ty::FreeRegion { + scope: Some(cx.tcx.node_extent(body_id)), bound_region: ty::BoundRegion::BrAnon(0), }); let region = cx.tcx.mk_region(region); @@ -979,7 +979,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, PassArgs::ByRef => { let region = cx.tcx.node_scope_region(expr.id); let (temp_lifetime, was_shrunk) = - cx.tcx.region_maps().temporary_scope2(expr.id); + cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); argrefs.extend(args.iter() .map(|arg| { let arg_ty = cx.tables().expr_ty_adjusted(arg); @@ -1031,7 +1031,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args); let ref_expr = Expr { temp_lifetime: temp_lifetime, @@ -1056,7 +1056,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_expr_id: closure_expr.id, }; let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap(); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(closure_expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, closure_expr.id); let var_ty = cx.tables().node_id_to_type(id_var); let captured_var = Expr { temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index a3982efd2d695..0e8992e62ea6c 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -32,7 +32,7 @@ pub use rustc_const_eval::pattern::{BindingMode, Pattern, PatternKind, FieldPatt #[derive(Clone, Debug)] pub struct Block<'tcx> { pub targeted_by_break: bool, - pub extent: CodeExtent, + pub extent: CodeExtent<'tcx>, pub span: Span, pub stmts: Vec>, pub expr: Option>, @@ -53,7 +53,7 @@ pub struct Stmt<'tcx> { pub enum StmtKind<'tcx> { Expr { /// scope for this statement; may be used as lifetime of temporaries - scope: CodeExtent, + scope: CodeExtent<'tcx>, /// expression being evaluated in this statement expr: ExprRef<'tcx>, @@ -62,11 +62,11 @@ pub enum StmtKind<'tcx> { Let { /// scope for variables bound in this let; covers this and /// remaining statements in block - remainder_scope: CodeExtent, + remainder_scope: CodeExtent<'tcx>, /// scope for the initialization itself; might be used as /// lifetime of temporaries - init_scope: CodeExtent, + init_scope: CodeExtent<'tcx>, /// let = ... pattern: Pattern<'tcx>, @@ -97,7 +97,7 @@ pub struct Expr<'tcx> { /// lifetime of this expression if it should be spilled into a /// temporary; should be None only if in a constant context - pub temp_lifetime: Option, + pub temp_lifetime: Option>, /// whether this temp lifetime was shrunk by #36082. pub temp_lifetime_was_shrunk: bool, @@ -112,12 +112,12 @@ pub struct Expr<'tcx> { #[derive(Clone, Debug)] pub enum ExprKind<'tcx> { Scope { - extent: CodeExtent, + extent: CodeExtent<'tcx>, value: ExprRef<'tcx>, }, Box { value: ExprRef<'tcx>, - value_extents: CodeExtent, + value_extents: CodeExtent<'tcx>, }, Call { ty: ty::Ty<'tcx>, @@ -205,16 +205,16 @@ pub enum ExprKind<'tcx> { id: DefId, }, Borrow { - region: &'tcx Region, + region: Region<'tcx>, borrow_kind: BorrowKind, arg: ExprRef<'tcx>, }, Break { - label: CodeExtent, + label: CodeExtent<'tcx>, value: Option>, }, Continue { - label: CodeExtent, + label: CodeExtent<'tcx>, }, Return { value: Option>, diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index cbd88733e82de..1abae515ae683 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -252,8 +252,8 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Ty<'tcx> { let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id); - let region = ty::Region::ReFree(ty::FreeRegion { - scope: Some(tcx.region_maps().item_extent(body_id.node_id)), + let region = ty::ReFree(ty::FreeRegion { + scope: Some(tcx.item_extent(body_id.node_id)), bound_region: ty::BoundRegion::BrEnv, }); let region = tcx.mk_region(region); diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index f275b4cafaf93..cb0625ceccfcb 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -480,7 +480,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> { borrow_id: ast::NodeId, _borrow_span: Span, cmt: mc::cmt<'tcx>, - _loan_region: &'tcx ty::Region, + _loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, loan_cause: euv::LoanCause) { // Kind of hacky, but we allow Unsafe coercions in constants. diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d672637649e85..c89e3ca8b68c9 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -53,7 +53,7 @@ pub trait AstConv<'gcx, 'tcx> { /// What lifetime should we use when a lifetime is omitted (and not elided)? fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>) - -> Option<&'tcx ty::Region>; + -> Option>; /// What type should we use when a type is omitted? fn ty_infer(&self, span: Span) -> Ty<'tcx>; @@ -104,7 +104,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { pub fn ast_region_to_region(&self, lifetime: &hir::Lifetime, def: Option<&ty::RegionParameterDef>) - -> &'tcx ty::Region + -> ty::Region<'tcx> { let tcx = self.tcx(); let r = match tcx.named_region_map.defs.get(&lifetime.id) { @@ -133,7 +133,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Some(&rl::Region::Free(scope, id)) => { let name = tcx.hir.name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: 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) })) @@ -1342,7 +1342,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { fn compute_object_lifetime_bound(&self, span: Span, existential_predicates: ty::Binder<&'tcx ty::Slice>>) - -> Option<&'tcx ty::Region> // if None, use the default + -> Option> // if None, use the default { let tcx = self.tcx(); @@ -1489,7 +1489,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected // and return from functions in multiple places. #[derive(PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { - pub region_bounds: Vec<&'tcx ty::Region>, + pub region_bounds: Vec>, pub implicitly_sized: bool, pub trait_bounds: Vec>, pub projection_bounds: Vec>, @@ -1533,7 +1533,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> { pub enum ExplicitSelf<'tcx> { ByValue, - ByReference(&'tcx ty::Region, hir::Mutability), + ByReference(ty::Region<'tcx>, hir::Mutability), ByBox } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 5d24df136ff19..45b0a571bd08a 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type); - let extent = self.tcx.region_maps().call_site_extent(expr.id, body.value.id); + let extent = self.tcx.call_site_extent(expr.id, body.value.id); let fn_sig = self.tcx.liberate_late_bound_regions(Some(extent), &sig); let fn_sig = self.inh.normalize_associated_types_in(body.value.span, body.value.id, &fn_sig); diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d21b5f739bd7b..d42532a714e2e 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -250,7 +250,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { exprs: &[E], a: Ty<'tcx>, b: Ty<'tcx>, - r_b: &'tcx ty::Region, + r_b: ty::Region<'tcx>, mt_b: TypeAndMut<'tcx>) -> CoerceResult<'tcx> where E: AsCoercionSite diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 4c9874cfa5a07..e4408413ee6c5 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -271,7 +271,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>, ty: ty::Ty<'tcx>, span: Span, - scope: region::CodeExtent) + scope: region::CodeExtent<'tcx>) -> Result<(), ErrorReported> { debug!("check_safety_of_destructor_if_necessary typ: {:?} scope: {:?}", diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8b366fd5a2770..729d25aaef541 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -781,7 +781,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_abi(tcx, span, fn_sig.abi()); // Compute the fty from point of view of inside fn. - let fn_scope = inh.tcx.region_maps().call_site_extent(id, body_id.node_id); + let fn_scope = inh.tcx.call_site_extent(id, body_id.node_id); let fn_sig = fn_sig.subst(inh.tcx, &inh.parameter_environment.free_substs); let fn_sig = @@ -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>) - -> Option<&'tcx ty::Region> { + -> Option> { let v = match def { Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330), None => infer::MiscVariable(span) @@ -1963,7 +1963,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// outlive the region `r`. pub fn register_region_obligation(&self, ty: Ty<'tcx>, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, cause: traits::ObligationCause<'tcx>) { let mut fulfillment_cx = self.fulfillment_cx.borrow_mut(); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a6f72898a5495..9a978934dda42 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -171,15 +171,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - region_bound_pairs: Vec<(&'tcx ty::Region, GenericKind<'tcx>)>, + region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>, - free_region_map: FreeRegionMap, + free_region_map: FreeRegionMap<'tcx>, // id of innermost fn body id body_id: ast::NodeId, // call_site scope of innermost fn - call_site_scope: Option, + call_site_scope: Option>, // id of innermost fn or loop 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) -> Option { + fn set_call_site_scope(&mut self, call_site_scope: Option>) + -> Option> { 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 call_site = self.tcx.region_maps().lookup_code_extent( + let call_site = self.tcx.intern_code_extent( region::CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id }); let old_call_site_scope = self.set_call_site_scope(Some(call_site)); @@ -302,7 +303,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { let old_body_id = self.set_body_id(body_id.node_id); self.relate_free_regions(&fn_sig_tys[..], body_id.node_id, span); - self.link_fn_args(self.tcx.region_maps().node_extent(body_id.node_id), &body.arguments); + self.link_fn_args(self.tcx.node_extent(body_id.node_id), &body.arguments); self.visit_body(body); self.visit_region_obligations(body_id.node_id); @@ -868,7 +869,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // call occurs. // // FIXME(#6268) to support nested method calls, should be callee_id - let callee_scope = self.tcx.region_maps().node_extent(call_expr.id); + let callee_scope = self.tcx.node_extent(call_expr.id); let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope)); debug!("callee_region={:?}", callee_region); @@ -982,8 +983,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn mk_subregion_due_to_dereference(&mut self, deref_span: Span, - minimum_lifetime: &'tcx ty::Region, - maximum_lifetime: &'tcx ty::Region) { + minimum_lifetime: ty::Region<'tcx>, + maximum_lifetime: ty::Region<'tcx>) { self.sub_regions(infer::DerefPointer(deref_span), minimum_lifetime, maximum_lifetime) } @@ -1021,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("constrain_index(index_expr=?, indexed_ty={}", self.ty_to_string(indexed_ty)); - let r_index_expr = ty::ReScope(self.tcx.region_maps().node_extent(index_expr.id)); + let r_index_expr = ty::ReScope(self.tcx.node_extent(index_expr.id)); if let ty::TyRef(r_ptr, mt) = indexed_ty.sty { match mt.ty.sty { ty::TySlice(_) | ty::TyStr => { @@ -1038,7 +1039,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn type_of_node_must_outlive(&mut self, origin: infer::SubregionOrigin<'tcx>, id: ast::NodeId, - minimum_lifetime: &'tcx ty::Region) + minimum_lifetime: ty::Region<'tcx>) { // Try to resolve the type. If we encounter an error, then typeck // is going to fail anyway, so just stop here and let typeck @@ -1101,7 +1102,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// Computes the guarantors for any ref bindings in a match and /// then ensures that the lifetime of the resulting pointer is /// linked to the lifetime of its guarantor (if any). - fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) { + fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); let mc = mc::MemCategorizationContext::new(self); for arg in args { @@ -1167,7 +1168,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// must outlive `callee_scope`. fn link_by_ref(&self, expr: &hir::Expr, - callee_scope: CodeExtent) { + callee_scope: CodeExtent<'tcx>) { debug!("link_by_ref(expr={:?}, callee_scope={:?})", expr, callee_scope); let mc = mc::MemCategorizationContext::new(self); @@ -1200,7 +1201,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// between regions, as explained in `link_reborrowed_region()`. fn link_region(&self, span: Span, - borrow_region: &'tcx ty::Region, + borrow_region: ty::Region<'tcx>, borrow_kind: ty::BorrowKind, borrow_cmt: mc::cmt<'tcx>) { let mut borrow_cmt = borrow_cmt; @@ -1297,10 +1298,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// recurse and process `ref_cmt` (see case 2 above). fn link_reborrowed_region(&self, span: Span, - borrow_region: &'tcx ty::Region, + borrow_region: ty::Region<'tcx>, borrow_kind: ty::BorrowKind, ref_cmt: mc::cmt<'tcx>, - ref_region: &'tcx ty::Region, + ref_region: ty::Region<'tcx>, mut ref_kind: ty::BorrowKind, note: mc::Note) -> Option<(mc::cmt<'tcx>, ty::BorrowKind)> @@ -1411,7 +1412,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { origin: infer::ParameterOrigin, substs: &Substs<'tcx>, expr_span: Span, - expr_region: &'tcx ty::Region) { + expr_region: ty::Region<'tcx>) { debug!("substs_wf_in_scope(substs={:?}, \ expr_region={:?}, \ origin={:?}, \ @@ -1436,7 +1437,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn type_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, ty: Ty<'tcx>, - region: &'tcx ty::Region) + region: ty::Region<'tcx>) { let ty = self.resolve_type(ty); @@ -1454,7 +1455,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn components_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, components: Vec>, - region: &'tcx ty::Region) + region: ty::Region<'tcx>) { for component in components { let origin = origin.clone(); @@ -1485,7 +1486,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn param_ty_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, param_ty: ty::ParamTy) { debug!("param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})", region, param_ty, origin); @@ -1497,7 +1498,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_must_outlive(&self, origin: infer::SubregionOrigin<'tcx>, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, projection_ty: ty::ProjectionTy<'tcx>) { debug!("projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})", @@ -1622,7 +1623,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_declared_bounds(&self, span: Span, projection_ty: ty::ProjectionTy<'tcx>) - -> Vec<&'tcx ty::Region> + -> Vec> { // First assemble bounds from where clauses and traits. @@ -1637,7 +1638,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn projection_bound(&self, span: Span, - declared_bounds: Vec<&'tcx ty::Region>, + declared_bounds: Vec>, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> { 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>) - -> Vec<&'tcx ty::Region> + -> Vec> { 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, span: Span, projection_ty: ty::ProjectionTy<'tcx>) - -> Vec<&'tcx ty::Region> + -> Vec> { debug!("projection_bounds(projection_ty={:?})", projection_ty); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 7b14684267173..a2c9b7876aafa 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -536,7 +536,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> { borrow_id: ast::NodeId, _borrow_span: Span, cmt: mc::cmt<'tcx>, - _loan_region: &'tcx ty::Region, + _loan_region: ty::Region<'tcx>, bk: ty::BorrowKind, _loan_cause: euv::LoanCause) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f306d5dd70f29..1887eaef36044 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -341,7 +341,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs); let mut implied_bounds = vec![]; - let free_id_outlive = fcx.tcx.region_maps().call_site_extent(item.id, body_id.node_id); + let free_id_outlive = fcx.tcx.call_site_extent(item.id, body_id.node_id); this.check_fn_or_method(fcx, item.span, sig, &predicates, Some(free_id_outlive), &mut implied_bounds); implied_bounds @@ -429,7 +429,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { span: Span, sig: ty::PolyFnSig<'tcx>, predicates: &ty::InstantiatedPredicates<'tcx>, - free_id_outlive: Option, + free_id_outlive: Option>, implied_bounds: &mut Vec>) { let free_substs = &fcx.parameter_environment.free_substs; @@ -453,7 +453,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, method_sig: &hir::MethodSig, method: &ty::AssociatedItem, - free_id_outlive: Option, + free_id_outlive: Option>, self_ty: ty::Ty<'tcx>) { // check that the type of the method's receiver matches the diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 35b2e8f8afcb8..ab2151544fc6e 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -76,7 +76,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { // early-bound versions of them, visible from the // outside of the function. This is needed by, and // only populated if there are any `impl Trait`. - free_to_bound_regions: DefIdMap<&'gcx ty::Region>, + free_to_bound_regions: DefIdMap>, body: &'gcx hir::Body, } @@ -275,7 +275,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } fn visit_free_region_map(&mut self) { - self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone(); + let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map); + let free_region_map = free_region_map.expect("all regions in free-region-map are global"); + self.tables.free_region_map = free_region_map; } fn visit_anon_types(&mut self) { @@ -522,7 +524,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> { // FIXME This should be carefully checked // We could use `self.report_error` but it doesn't accept a ty::Region, right now. - fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match self.infcx.fully_resolve(&r) { Ok(r) => r, Err(_) => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3cd8b8bd48914..0d75a1ecf3d8f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -215,7 +215,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>) - -> Option<&'tcx ty::Region> { + -> Option> { None } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 22be4491273ef..ee11b774cf261 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -75,7 +75,7 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { t.super_visit_with(self) } - fn visit_region(&mut self, r: &'tcx ty::Region) -> bool { + fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReEarlyBound(data) => { self.parameters.push(Parameter::from(data)); diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 5bbc285c3d5ce..529b2700679d5 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -479,7 +479,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { /// context with ambient variance `variance` fn add_constraints_from_region(&mut self, generics: &ty::Generics, - region: &'tcx ty::Region, + region: ty::Region<'tcx>, variance: VarianceTermPtr<'a>) { match *region { ty::ReEarlyBound(ref data) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a25eb60d2a2fc..5899ce9061166 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -726,7 +726,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { if let ty::TyTuple(ts, _) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { - if let &ty::Region::ReLateBound(..) = *reg { + if let &ty::RegionKind::ReLateBound(..) = *reg { debug!(" hit an ReLateBound {:?}", reg); if let Some(lt) = reg.clean(cx) { late_bounds.push(lt); @@ -819,7 +819,7 @@ impl Clean for ty::RegionParameterDef { } } -impl Clean> for ty::Region { +impl<'tcx> Clean> for ty::RegionKind<'tcx> { fn clean(&self, cx: &DocContext) -> Option { match *self { ty::ReStatic => Some(Lifetime::statik()), @@ -915,7 +915,7 @@ impl<'tcx> Clean for ty::SubtypePredicate<'tcx> { } } -impl<'tcx> Clean for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> { +impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { fn clean(&self, cx: &DocContext) -> WherePredicate { let ty::OutlivesPredicate(ref a, ref b) = *self; WherePredicate::RegionPredicate { @@ -925,7 +925,7 @@ impl<'tcx> Clean for ty::OutlivesPredicate<&'tcx ty::Region, &'t } } -impl<'tcx> Clean for ty::OutlivesPredicate, &'tcx ty::Region> { +impl<'tcx> Clean for ty::OutlivesPredicate, ty::Region<'tcx>> { fn clean(&self, cx: &DocContext) -> WherePredicate { let ty::OutlivesPredicate(ref ty, ref lt) = *self; diff --git a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs index a81c0846a2794..d1f957bf6b955 100644 --- a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs +++ b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs @@ -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 // http://rust-lang.org/COPYRIGHT. // From 73cd9bde373cc134aa2ebb6a8064d532621ca0a6 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 10 Apr 2017 00:00:08 -0700 Subject: [PATCH 06/17] introduce per-fn RegionMaps Instead of requesting the region maps for the entire crate, request for a given item etc. Several bits of code were modified to take `&RegionMaps` as input (e.g., the `resolve_regions_and_report_errors()` function). I am not totally happy with this setup -- I *think* I'd rather have the region maps be part of typeck tables -- but at least the `RegionMaps` works in a "parallel" way to `FreeRegionMap`, so it's not too bad. Given that I expect a lot of this code to go away with NLL, I didn't want to invest *too* much energy tweaking it. --- src/librustc/cfg/construct.rs | 6 +- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/hir/intravisit.rs | 19 ++- src/librustc/hir/map/mod.rs | 12 ++ src/librustc/infer/mod.rs | 14 +- .../infer/region_inference/graphviz.rs | 37 ++--- src/librustc/infer/region_inference/mod.rs | 82 +++++----- src/librustc/middle/expr_use_visitor.rs | 9 +- src/librustc/middle/free_region.rs | 153 +++++++++++------- src/librustc/middle/mem_categorization.rs | 19 ++- src/librustc/middle/region.rs | 80 +++++---- src/librustc/traits/mod.rs | 12 +- src/librustc/ty/context.rs | 13 +- src/librustc/ty/maps.rs | 15 +- src/librustc/ty/mod.rs | 2 +- src/librustc_borrowck/borrowck/check_loans.rs | 9 +- .../borrowck/gather_loans/lifetime.rs | 2 +- .../borrowck/gather_loans/mod.rs | 11 +- src/librustc_borrowck/borrowck/mod.rs | 39 ++--- src/librustc_borrowck/borrowck/move_data.rs | 13 +- src/librustc_const_eval/check_match.rs | 7 +- src/librustc_driver/driver.rs | 4 - src/librustc_driver/test.rs | 3 +- src/librustc_mir/build/matches/mod.rs | 2 +- src/librustc_mir/build/mod.rs | 9 +- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 16 +- src/librustc_mir/hair/cx/mod.rs | 22 +-- src/librustc_passes/consts.rs | 5 +- src/librustc_typeck/check/compare_method.rs | 30 ++-- src/librustc_typeck/check/dropck.rs | 7 +- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/regionck.rs | 55 ++++--- src/librustc_typeck/check/upvar.rs | 2 + src/librustc_typeck/coherence/builtin.rs | 4 +- .../kindck-implicit-close-over-mut-var.rs | 2 +- 36 files changed, 422 insertions(+), 303 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 7b7c204a0ee77..a8ad49c6582d4 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -15,9 +15,11 @@ use syntax::ast; use syntax::ptr::P; use hir::{self, PatKind}; +use hir::def_id::DefId; struct CFGBuilder<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + owner_def_id: DefId, tables: &'a ty::TypeckTables<'tcx>, graph: CFGGraph, fn_exit: CFGIndex, @@ -56,6 +58,7 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut cfg_builder = CFGBuilder { tcx: tcx, + owner_def_id, tables: tables, graph: graph, fn_exit: fn_exit, @@ -585,9 +588,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let mut data = CFGEdgeData { exiting_scopes: vec![] }; let mut scope = self.tcx.node_extent(from_expr.id); let target_scope = self.tcx.node_extent(scope_id); + let region_maps = self.tcx.region_maps(self.owner_def_id); while scope != target_scope { data.exiting_scopes.push(scope.node_id()); - scope = self.tcx.region_maps().encl_scope(scope); + scope = region_maps.encl_scope(scope); } self.graph.add_edge(from_index, to_index, data); } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index d05ede07c3f64..63a4e6196a2e9 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -56,7 +56,7 @@ pub enum DepNode { WorkProduct(Arc), // Represents different phases in the compiler. - RegionResolveCrate, + RegionMaps(D), Coherence, Resolve, CoherenceCheckTrait(D), @@ -197,7 +197,6 @@ impl DepNode { BorrowCheckKrate => Some(BorrowCheckKrate), MirKrate => Some(MirKrate), TypeckBodiesKrate => Some(TypeckBodiesKrate), - RegionResolveCrate => Some(RegionResolveCrate), Coherence => Some(Coherence), Resolve => Some(Resolve), Variance => Some(Variance), @@ -223,6 +222,7 @@ impl DepNode { def_ids.map(MirShim) } BorrowCheck(ref d) => op(d).map(BorrowCheck), + RegionMaps(ref d) => op(d).map(RegionMaps), RvalueCheck(ref d) => op(d).map(RvalueCheck), TransCrateItem(ref d) => op(d).map(TransCrateItem), TransInlinedItem(ref d) => op(d).map(TransInlinedItem), diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 2b0d53b2bc356..3e610dd3c0d87 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -39,7 +39,7 @@ use syntax::codemap::Spanned; use syntax_pos::Span; use hir::*; use hir::def::Def; -use hir::map::Map; +use hir::map::{self, Map}; use super::itemlikevisit::DeepVisitor; use std::cmp; @@ -140,6 +140,23 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'v> : Sized { + /// Invokes the suitable visitor method for the given `Node` + /// extracted from the hir map. + fn visit_hir_map_node(&mut self, node: map::Node<'v>) { + match node { + map::NodeItem(a) => self.visit_item(a), + map::NodeForeignItem(a) => self.visit_foreign_item(a), + map::NodeTraitItem(a) => self.visit_trait_item(a), + map::NodeImplItem(a) => self.visit_impl_item(a), + map::NodeExpr(a) => self.visit_expr(a), + map::NodeStmt(a) => self.visit_stmt(a), + map::NodeTy(a) => self.visit_ty(a), + map::NodePat(a) => self.visit_pat(a), + map::NodeBlock(a) => self.visit_block(a), + _ => bug!("Visitor::visit_hir_map_node() not yet impl for node `{:?}`", node) + } + } + /////////////////////////////////////////////////////////////////////////// // Nested items. diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 48b8a819fff03..cae5c5011ce7e 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -572,6 +572,18 @@ impl<'hir> Map<'hir> { } } + /// Check if the node is a non-closure function item + pub fn is_fn(&self, id: NodeId) -> bool { + let entry = if let Some(id) = self.find_entry(id) { id } else { return false }; + + match entry { + EntryItem(_, &Item { node: ItemFn(..), .. }) | + EntryTraitItem(_, &TraitItem { node: TraitItemKind::Method(..), .. }) | + EntryImplItem(_, &ImplItem { node: ImplItemKind::Method(..), .. }) => true, + _ => false, + } + } + /// If there is some error when walking the parents (e.g., a node does not /// have a parent in the map or a node can't be found), then we return the /// last good node id we found. Note that reaching the crate root (id == 0), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index a0451c5fe0b4d..e91af21c6db2c 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -20,7 +20,8 @@ pub use self::region_inference::{GenericKind, VerifyBound}; use hir::def_id::DefId; use hir; -use middle::free_region::FreeRegionMap; +use middle::free_region::{FreeRegionMap, RegionRelations}; +use middle::region::RegionMaps; use middle::mem_categorization as mc; use middle::mem_categorization::McResult; use middle::lang_items; @@ -1322,9 +1323,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn resolve_regions_and_report_errors(&self, - free_regions: &FreeRegionMap<'tcx>, - subject_node_id: ast::NodeId) { - let errors = self.region_vars.resolve_regions(free_regions, subject_node_id); + region_context: DefId, + region_map: &RegionMaps<'tcx>, + free_regions: &FreeRegionMap<'tcx>) { + let region_rels = RegionRelations::new(self.tcx, + region_context, + region_map, + free_regions); + let errors = self.region_vars.resolve_regions(®ion_rels); if !self.is_tainted_by_errors() { // As a heuristic, just skip reporting region errors // altogether if other errors have been reported while diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index 7de81e14d7754..c48b8f610a2b7 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -18,7 +18,9 @@ /// For clarity, rename the graphviz crate locally to dot. use graphviz as dot; -use ty::{self, TyCtxt}; +use hir::def_id::DefIndex; +use ty; +use middle::free_region::RegionRelations; use middle::region::CodeExtent; use super::Constraint; use infer::SubregionOrigin; @@ -32,7 +34,6 @@ use std::fs::File; use std::io; use std::io::prelude::*; use std::sync::atomic::{AtomicBool, Ordering}; -use syntax::ast; fn print_help_message() { println!("\ @@ -55,18 +56,18 @@ graphs will be printed. \n\ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>, - subject_node: ast::NodeId) + region_rels: &RegionRelations<'a, 'gcx, 'tcx>) { - let tcx = region_vars.tcx; + let context = region_rels.context; if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph { return; } let requested_node = env::var("RUST_REGION_GRAPH_NODE") - .ok().and_then(|s| s.parse().map(ast::NodeId::new).ok()); + .ok().and_then(|s| s.parse().map(DefIndex::new).ok()); - if requested_node.is_some() && requested_node != Some(subject_node) { + if requested_node.is_some() && requested_node != Some(context.index) { return; } @@ -98,7 +99,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( let mut new_str = String::new(); for c in output_template.chars() { if c == '%' { - new_str.push_str(&subject_node.to_string()); + new_str.push_str(&context.index.as_usize().to_string()); } else { new_str.push(c); } @@ -110,7 +111,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( }; let constraints = &*region_vars.constraints.borrow(); - match dump_region_constraints_to(tcx, constraints, &output_path) { + match dump_region_constraints_to(region_rels, constraints, &output_path) { Ok(()) => {} Err(e) => { let msg = format!("io error dumping region constraints: {}", e); @@ -120,8 +121,8 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( } struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'tcx>, graph_name: String, + region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>, map: &'a FxHashMap, SubregionOrigin<'tcx>>, node_ids: FxHashMap, usize>, } @@ -140,8 +141,8 @@ enum Edge<'tcx> { } impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { - fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, - name: String, + fn new(name: String, + region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>, map: &'a ConstraintMap<'tcx>) -> ConstraintGraph<'a, 'gcx, 'tcx> { let mut i = 0; @@ -159,17 +160,17 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { add_node(n2); } - tcx.region_maps().each_encl_scope(|sub, sup| { + region_rels.region_maps.each_encl_scope(|sub, sup| { add_node(Node::Region(ty::ReScope(sub))); add_node(Node::Region(ty::ReScope(sup))); }); } ConstraintGraph { - tcx: tcx, + map, + node_ids, + region_rels, graph_name: name, - map: map, - node_ids: node_ids, } } } @@ -245,7 +246,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { fn edges(&self) -> dot::Edges> { debug!("constraint graph has {} edges", self.map.len()); let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); - self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup))); + self.region_rels.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup))); debug!("region graph has {} edges", v.len()); Cow::Owned(v) } @@ -263,14 +264,14 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { pub type ConstraintMap<'tcx> = FxHashMap, SubregionOrigin<'tcx>>; -fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, +fn dump_region_constraints_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>, map: &ConstraintMap<'tcx>, path: &str) -> io::Result<()> { debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path); - let g = ConstraintGraph::new(tcx, format!("region_constraints"), map); + let g = ConstraintGraph::new(format!("region_constraints"), region_rels, map); debug!("dump_region_constraints calling render"); let mut v = Vec::new(); dot::render(&g, &mut v).unwrap(); diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 33754b738a091..fb699bbd2d25f 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -22,7 +22,7 @@ use super::unify_key; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING}; use rustc_data_structures::unify::{self, UnificationTable}; -use middle::free_region::FreeRegionMap; +use middle::free_region::RegionRelations; use ty::{self, Ty, TyCtxt}; use ty::{Region, RegionVid}; use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased}; @@ -33,7 +33,6 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::fmt; use std::mem; use std::u32; -use syntax::ast; mod graphviz; @@ -892,18 +891,17 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// constraints, assuming such values can be found; if they cannot, /// errors are reported. pub fn resolve_regions(&self, - free_regions: &FreeRegionMap<'tcx>, - subject_node: ast::NodeId) + region_rels: &RegionRelations<'a, 'gcx, 'tcx>) -> Vec> { debug!("RegionVarBindings: resolve_regions()"); let mut errors = vec![]; - let v = self.infer_variable_values(free_regions, &mut errors, subject_node); + let v = self.infer_variable_values(region_rels, &mut errors); *self.values.borrow_mut() = Some(v); errors } fn lub_concrete_regions(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { @@ -939,7 +937,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // at least as big as the block fr.scope_id". So, we can // reasonably compare free regions and scopes: if let Some(fr_scope) = fr.scope { - let r_id = self.tcx.region_maps().nearest_common_ancestor(fr_scope, s_id); + let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id); if r_id == fr_scope { // if the free region's scope `fr.scope_id` is bigger than // the scope region `s_id`, then the LUB is the free @@ -957,12 +955,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // The region corresponding to an outer block is a // subtype of the region corresponding to an inner // block. - self.tcx.mk_region(ReScope( - self.tcx.region_maps().nearest_common_ancestor(a_id, b_id))) + let lub = region_rels.region_maps.nearest_common_ancestor(a_id, b_id); + self.tcx.mk_region(ReScope(lub)) } (&ReFree(_), &ReFree(_)) => { - free_regions.lub_free_regions(self.tcx, a, b) + region_rels.lub_free_regions(a, b) } // For these types, we cannot define any additional @@ -996,24 +994,23 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>; impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn infer_variable_values(&self, - free_regions: &FreeRegionMap<'tcx>, - errors: &mut Vec>, - subject: ast::NodeId) + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, + errors: &mut Vec>) -> Vec> { let mut var_data = self.construct_var_data(); // Dorky hack to cause `dump_constraints` to only get called // if debug mode is enabled: - debug!("----() End constraint listing (subject={}) {:?}---", - subject, - self.dump_constraints(subject)); - graphviz::maybe_print_constraints_for(self, subject); + debug!("----() End constraint listing (context={:?}) {:?}---", + region_rels.context, + self.dump_constraints(region_rels)); + graphviz::maybe_print_constraints_for(self, region_rels); let graph = self.construct_graph(); self.expand_givens(&graph); - self.expansion(free_regions, &mut var_data); - self.collect_errors(free_regions, &mut var_data, errors); - self.collect_var_errors(free_regions, &var_data, &graph, errors); + self.expansion(region_rels, &mut var_data); + self.collect_errors(region_rels, &mut var_data, errors); + self.collect_var_errors(region_rels, &var_data, &graph, errors); var_data } @@ -1023,9 +1020,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { .collect() } - fn dump_constraints(&self, subject: ast::NodeId) { - debug!("----() Start constraint listing (subject={}) ()----", - subject); + fn dump_constraints(&self, free_regions: &RegionRelations<'a, 'gcx, 'tcx>) { + debug!("----() Start constraint listing (context={:?}) ()----", + free_regions.context); for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() { debug!("Constraint {} => {:?}", idx, constraint); } @@ -1056,21 +1053,21 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - fn expansion(&self, free_regions: &FreeRegionMap<'tcx>, var_values: &mut [VarValue<'tcx>]) { + fn expansion(&self, region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_values: &mut [VarValue<'tcx>]) { self.iterate_until_fixed_point("Expansion", |constraint, origin| { debug!("expansion: constraint={:?} origin={:?}", constraint, origin); match *constraint { ConstrainRegSubVar(a_region, b_vid) => { let b_data = &mut var_values[b_vid.index as usize]; - self.expand_node(free_regions, a_region, b_vid, b_data) + self.expand_node(region_rels, a_region, b_vid, b_data) } ConstrainVarSubVar(a_vid, b_vid) => { match var_values[a_vid.index as usize] { ErrorValue => false, Value(a_region) => { let b_node = &mut var_values[b_vid.index as usize]; - self.expand_node(free_regions, a_region, b_vid, b_node) + self.expand_node(region_rels, a_region, b_vid, b_node) } } } @@ -1085,7 +1082,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn expand_node(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, a_region: Region<'tcx>, b_vid: RegionVid, b_data: &mut VarValue<'tcx>) @@ -1108,7 +1105,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { match *b_data { Value(cur_region) => { - let lub = self.lub_concrete_regions(free_regions, a_region, cur_region); + let lub = self.lub_concrete_regions(region_rels, a_region, cur_region); if lub == cur_region { return false; } @@ -1132,7 +1129,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// cases where the region cannot grow larger than a fixed point) /// and check that they are satisfied. fn collect_errors(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_data: &mut Vec>, errors: &mut Vec>) { let constraints = self.constraints.borrow(); @@ -1146,7 +1143,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } ConstrainRegSubReg(sub, sup) => { - if free_regions.is_subregion_of(self.tcx, sub, sup) { + if region_rels.is_subregion_of(sub, sup) { continue; } @@ -1174,7 +1171,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // Do not report these errors immediately: // instead, set the variable value to error and // collect them later. - if !free_regions.is_subregion_of(self.tcx, a_region, b_region) { + if !region_rels.is_subregion_of(a_region, b_region) { debug!("collect_errors: region error at {:?}: \ cannot verify that {:?}={:?} <= {:?}", origin, @@ -1190,7 +1187,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { for verify in self.verifys.borrow().iter() { debug!("collect_errors: verify={:?}", verify); let sub = normalize(self.tcx, var_data, verify.region); - if verify.bound.is_met(self.tcx, free_regions, var_data, sub) { + if verify.bound.is_met(region_rels, var_data, sub) { continue; } @@ -1209,7 +1206,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// Go over the variables that were declared to be error variables /// and create a `RegionResolutionError` for each of them. fn collect_var_errors(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_data: &[VarValue<'tcx>], graph: &RegionGraph<'tcx>, errors: &mut Vec>) { @@ -1258,7 +1255,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { this portion of the code and think hard about it. =) */ let node_vid = RegionVid { index: idx as u32 }; - self.collect_error_for_expanding_node(free_regions, + self.collect_error_for_expanding_node(region_rels, graph, &mut dup_vec, node_vid, @@ -1311,7 +1308,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn collect_error_for_expanding_node(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, graph: &RegionGraph<'tcx>, dup_vec: &mut [u32], node_idx: RegionVid, @@ -1347,7 +1344,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { for lower_bound in &lower_bounds { for upper_bound in &upper_bounds { - if !free_regions.is_subregion_of(self.tcx, lower_bound.region, upper_bound.region) { + if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) { let origin = (*self.var_origins.borrow())[node_idx.index as usize].clone(); debug!("region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ sup: {:?}", @@ -1591,29 +1588,30 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { } } - fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - free_regions: &FreeRegionMap<'tcx>, + fn is_met(&self, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_values: &Vec>, min: ty::Region<'tcx>) -> bool { + let tcx = region_rels.tcx; match self { &VerifyBound::AnyRegion(ref rs) => rs.iter() .map(|&r| normalize(tcx, var_values, r)) - .any(|r| free_regions.is_subregion_of(tcx, min, r)), + .any(|r| region_rels.is_subregion_of(min, r)), &VerifyBound::AllRegions(ref rs) => rs.iter() .map(|&r| normalize(tcx, var_values, r)) - .all(|r| free_regions.is_subregion_of(tcx, min, r)), + .all(|r| region_rels.is_subregion_of(min, r)), &VerifyBound::AnyBound(ref bs) => bs.iter() - .any(|b| b.is_met(tcx, free_regions, var_values, min)), + .any(|b| b.is_met(region_rels, var_values, min)), &VerifyBound::AllBounds(ref bs) => bs.iter() - .all(|b| b.is_met(tcx, free_regions, var_values, min)), + .all(|b| b.is_met(region_rels, var_values, min)), } } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 9be05313439fd..a49f3d3b7a7fa 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -270,19 +270,24 @@ enum PassArgs { impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pub fn new(delegate: &'a mut (Delegate<'tcx>+'a), + context: DefId, infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self { - ExprUseVisitor::with_options(delegate, infcx, mc::MemCategorizationOptions::default()) + ExprUseVisitor::with_options(delegate, + infcx, + context, + mc::MemCategorizationOptions::default()) } pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a), infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId, options: mc::MemCategorizationOptions) -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::with_options(infcx, options), + mc: mc::MemCategorizationContext::with_options(infcx, context, options), delegate: delegate } } diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 1dc633c6d0040..2dc7aac04aede 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -15,10 +15,108 @@ //! `TransitiveRelation` type and use that to decide when one free //! region outlives another and so forth. +use hir::def_id::DefId; +use middle::region::RegionMaps; use ty::{self, Lift, TyCtxt, Region}; use ty::wf::ImpliedBound; use rustc_data_structures::transitive_relation::TransitiveRelation; +/// Combines a `RegionMaps` (which governs relationships between +/// scopes) and a `FreeRegionMap` (which governs relationships between +/// free regions) to yield a complete relation between concrete +/// regions. +/// +/// This stuff is a bit convoluted and should be refactored, but as we +/// move to NLL it'll all go away anyhow. +pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> { + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, + + /// context used to fetch the region maps + pub context: DefId, + + /// region maps for the given context + pub region_maps: &'a RegionMaps<'tcx>, + + /// free-region relationships + pub free_regions: &'a FreeRegionMap<'tcx>, +} + +impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> { + pub fn new( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + context: DefId, + region_maps: &'a RegionMaps<'tcx>, + free_regions: &'a FreeRegionMap<'tcx>, + ) -> Self { + Self { + tcx, + context, + region_maps, + free_regions, + } + } + + /// Determines whether one region is a subregion of another. This is intended to run *after + /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. + pub fn is_subregion_of(&self, + sub_region: ty::Region<'tcx>, + super_region: ty::Region<'tcx>) + -> bool { + let result = sub_region == super_region || { + match (sub_region, super_region) { + (&ty::ReEmpty, _) | + (_, &ty::ReStatic) => + true, + + (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => + self.region_maps.is_subscope_of(sub_scope, super_scope), + + (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { + // 1. It is safe to unwrap `fr.scope` because we + // should only ever wind up comparing against + // `ReScope` in the context of a method or + // body, where `fr.scope` should be `Some`. + self.region_maps.is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || + self.is_static(super_region) + } + + (&ty::ReFree(_), &ty::ReFree(_)) => + self.free_regions.relation.contains(&sub_region, &super_region) || + self.is_static(super_region), + + (&ty::ReStatic, &ty::ReFree(_)) => + self.is_static(super_region), + + _ => + false, + } + }; + debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", + sub_region, super_region, result); + result + } + + /// Determines whether this free-region is required to be 'static + fn is_static(&self, super_region: ty::Region<'tcx>) -> bool { + debug!("is_static(super_region={:?})", super_region); + match *super_region { + ty::ReStatic => true, + ty::ReFree(_) => { + let re_static = self.tcx.mk_region(ty::ReStatic); + self.free_regions.relation.contains(&re_static, &super_region) + } + _ => bug!("only free regions should be given to `is_static`") + } + } + + pub fn lub_free_regions(&self, + r_a: Region<'tcx>, + r_b: Region<'tcx>) + -> Region<'tcx> { + self.free_regions.lub_free_regions(self.tcx, r_a, r_b) + } +} + #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct FreeRegionMap<'tcx> { // Stores the relation `a < b`, where `a` and `b` are regions. @@ -116,61 +214,6 @@ impl<'tcx> FreeRegionMap<'tcx> { debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result); result } - - /// Determines whether one region is a subregion of another. This is intended to run *after - /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. - pub fn is_subregion_of<'a, 'gcx>(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - sub_region: ty::Region<'tcx>, - super_region: ty::Region<'tcx>) - -> bool { - let result = sub_region == super_region || { - match (sub_region, super_region) { - (&ty::ReEmpty, _) | - (_, &ty::ReStatic) => - true, - - (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => - tcx.region_maps().is_subscope_of(sub_scope, super_scope), - - (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { - // 1. It is safe to unwrap `fr.scope` because we - // should only ever wind up comparing against - // `ReScope` in the context of a method or - // body, where `fr.scope` should be `Some`. - tcx.region_maps().is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || - self.is_static(tcx, super_region) - } - - (&ty::ReFree(_), &ty::ReFree(_)) => - self.relation.contains(&sub_region, &super_region) || - self.is_static(tcx, super_region), - - (&ty::ReStatic, &ty::ReFree(_)) => - self.is_static(tcx, super_region), - - _ => - false, - } - }; - debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", - sub_region, super_region, result); - result - } - - /// Determines whether this free-region is required to be 'static - fn is_static<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, super_region: ty::Region<'tcx>) - -> bool { - debug!("is_static(super_region={:?})", 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`") - } - } } impl_stable_hash_for!(struct FreeRegionMap<'tcx> { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 3b1a9552ece26..0e2db746e45e4 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -70,6 +70,7 @@ pub use self::Note::*; use self::Aliasability::*; +use middle::region::RegionMaps; use hir::def_id::DefId; use hir::map as hir_map; use infer::InferCtxt; @@ -286,9 +287,10 @@ impl ast_node for hir::Pat { fn span(&self) -> Span { self.span } } -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + pub region_maps: Rc>, options: MemCategorizationOptions, } @@ -402,16 +404,21 @@ impl MutabilityCategory { } impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) + /// Context should be the `DefId` we use to fetch region-maps. + pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId) -> MemCategorizationContext<'a, 'gcx, 'tcx> { - MemCategorizationContext::with_options(infcx, MemCategorizationOptions::default()) + MemCategorizationContext::with_options(infcx, context, MemCategorizationOptions::default()) } pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId, options: MemCategorizationOptions) -> MemCategorizationContext<'a, 'gcx, 'tcx> { + let region_maps = infcx.tcx.region_maps(context); MemCategorizationContext { infcx: infcx, + region_maps: region_maps, options: options, } } @@ -786,7 +793,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; match fn_expr.node { - hir::ExprClosure(.., body_id, _) => body_id.node_id, + hir::ExprClosure(.., body_id, _) => body_id, _ => bug!() } }; @@ -796,7 +803,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: Some(self.tcx().item_extent(fn_body_id)), + scope: Some(self.tcx().item_extent(fn_body_id.node_id)), bound_region: ty::BrEnv })); @@ -845,7 +852,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>) { let (scope, old_scope) = - self.tcx().region_maps().old_and_new_temporary_scope(self.tcx(), id); + self.region_maps.old_and_new_temporary_scope(self.tcx(), id); (self.tcx().mk_region(match scope { Some(scope) => ty::ReScope(scope), None => ty::ReStatic diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 062432e27e549..fb0c3a29deffc 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -29,8 +29,7 @@ use syntax_pos::Span; use ty::TyCtxt; use ty::maps::Providers; -use hir; -use hir::def_id::{CrateNum, LOCAL_CRATE}; +use hir; use hir::def_id::DefId; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; @@ -226,6 +225,9 @@ pub struct RegionMaps<'tcx> { /// which that variable is declared. var_map: NodeMap>, + /// maps from a node-id to the associated destruction scope (if any) + destruction_scopes: NodeMap>, + /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is /// larger than the default. The map goes from the expression id /// to the cleanup scope id. For rvalues not present in this @@ -301,11 +303,22 @@ struct RegionResolutionVisitor<'a, 'tcx: 'a> { /// arbitrary amounts of stack space. Terminating scopes end /// up being contained in a DestructionScope that contains the /// destructor's execution. - terminating_scopes: NodeSet + terminating_scopes: NodeSet, } impl<'tcx> RegionMaps<'tcx> { + pub fn new() -> Self { + RegionMaps { + scope_map: FxHashMap(), + destruction_scopes: FxHashMap(), + var_map: NodeMap(), + rvalue_scopes: NodeMap(), + shrunk_rvalue_scopes: NodeMap(), + fn_tree: NodeMap(), + } + } + pub fn each_encl_scope(&self, mut e:E) where E: FnMut(CodeExtent<'tcx>, CodeExtent<'tcx>) { for (&child, &parent) in &self.scope_map { e(child, parent) @@ -317,6 +330,10 @@ impl<'tcx> RegionMaps<'tcx> { } } + pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option> { + self.destruction_scopes.get(&n).cloned() + } + /// Records that `sub_fn` is defined within `sup_fn`. These ids /// should be the id of the block that is the fn body, which is /// also the root of the region hierarchy for that fn. @@ -1029,18 +1046,18 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, body_id: hir::BodyId, sp: Span, id: ast::NodeId) { + visitor.cx.parent = Some(visitor.new_code_extent( + CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id })); + debug!("region::resolve_fn(id={:?}, \ - span={:?}, \ - body.id={:?}, \ - cx.parent={:?})", + span={:?}, \ + body.id={:?}, \ + cx.parent={:?})", id, visitor.tcx.sess.codemap().span_to_string(sp), body_id, visitor.cx.parent); - visitor.cx.parent = Some(visitor.new_code_extent( - CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id })); - let fn_decl_scope = visitor.new_code_extent( CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id }); @@ -1086,6 +1103,12 @@ impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> { let prev = self.region_maps.scope_map.insert(code_extent, p); assert!(prev.is_none()); } + + // record the destruction scopes for later so we can query them + if let &CodeExtentData::DestructionScope(n) = code_extent { + self.region_maps.destruction_scopes.insert(n, code_extent); + } + code_extent } @@ -1162,47 +1185,44 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { } } -pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc> { - tcx.region_resolve_crate(LOCAL_CRATE) -} - -fn region_resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) +fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_id: DefId) -> Rc> { - debug_assert!(crate_num == LOCAL_CRATE); - - let hir_map = &tcx.hir; + let fn_node_id = tcx.hir.as_local_node_id(fn_id) + .expect("fn DefId should be for LOCAL_CRATE"); + let node = tcx.hir.get(fn_node_id); + match node { + hir_map::NodeItem(_) | hir_map::NodeTraitItem(_) | hir_map::NodeImplItem(_) => { } + _ => { + let parent_id = tcx.hir.get_parent(fn_node_id); + let parent_def_id = tcx.hir.local_def_id(parent_id); + return tcx.region_maps(parent_def_id); + } + } - let krate = hir_map.krate(); - - let mut maps = RegionMaps { - scope_map: FxHashMap(), - var_map: NodeMap(), - rvalue_scopes: NodeMap(), - shrunk_rvalue_scopes: NodeMap(), - fn_tree: NodeMap(), - }; + let mut maps = RegionMaps::new(); { let mut visitor = RegionResolutionVisitor { tcx: tcx, region_maps: &mut maps, - map: hir_map, + map: &tcx.hir, cx: Context { root_id: None, parent: None, var_parent: None, }, - terminating_scopes: NodeSet() + terminating_scopes: NodeSet(), }; - krate.visit_all_item_likes(&mut visitor.as_deep_visitor()); + visitor.visit_hir_map_node(node); } + Rc::new(maps) } pub fn provide(providers: &mut Providers) { *providers = Providers { - region_resolve_crate, + region_maps, ..*providers }; } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 5ac79a8e72a50..4f7cb2b12a7ca 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -17,6 +17,7 @@ pub use self::ObligationCauseCode::*; use hir; use hir::def_id::DefId; +use middle::region::RegionMaps; use middle::free_region::FreeRegionMap; use ty::subst::Substs; use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate}; @@ -435,9 +436,10 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx // FIXME: this is gonna need to be removed ... /// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - unnormalized_env: ty::ParameterEnvironment<'tcx>, - cause: ObligationCause<'tcx>) - -> ty::ParameterEnvironment<'tcx> + region_context: DefId, + unnormalized_env: ty::ParameterEnvironment<'tcx>, + cause: ObligationCause<'tcx>) + -> ty::ParameterEnvironment<'tcx> { // I'm not wild about reporting errors here; I'd prefer to // have the errors get reported at a defined place (e.g., @@ -455,7 +457,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // can be sure that no errors should occur. let span = cause.span; - let body_id = cause.body_id; debug!("normalize_param_env_or_error(unnormalized_env={:?})", unnormalized_env); @@ -492,8 +493,9 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("normalize_param_env_or_error: normalized predicates={:?}", predicates); + let region_maps = RegionMaps::new(); let free_regions = FreeRegionMap::new(); - infcx.resolve_regions_and_report_errors(&free_regions, body_id); + infcx.resolve_regions_and_report_errors(region_context, ®ion_maps, &free_regions); let predicates = match infcx.fully_resolve(&predicates) { Ok(predicates) => predicates, Err(fixup_err) => { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3c6f833c4ef45..73b76736b2470 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; use middle::lang_items; -use middle::region::{CodeExtent, CodeExtentData, RegionMaps}; +use middle::region::{CodeExtent, CodeExtentData}; use middle::resolve_lifetime; use middle::stability; use mir::Mir; @@ -52,7 +52,6 @@ use std::mem; use std::ops::Deref; use std::iter; use std::cmp::Ordering; -use std::rc::Rc; use syntax::abi; use syntax::ast::{self, Name, NodeId}; use syntax::attr; @@ -656,12 +655,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { 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> { - 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)) @@ -712,10 +705,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { local as usize == global as usize } - pub fn region_maps(self) -> Rc> { - self.region_resolve_crate(LOCAL_CRATE) - } - /// Create a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 4a780b9178ecc..b8edfbf60f245 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -292,12 +292,6 @@ impl<'tcx> QueryDescription for queries::def_span<'tcx> { } } -impl<'tcx> QueryDescription for queries::region_resolve_crate<'tcx> { - fn describe(_: TyCtxt, _: CrateNum) -> String { - format!("resolve crate") - } -} - macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -578,7 +572,10 @@ define_maps! { <'tcx> [] reachable_set: reachability_dep_node(CrateNum) -> Rc, - [] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc>, + /// Per-function `RegionMaps`. The `DefId` should be the owner-def-id for the fn body; + /// in the case of closures or "inline" expressions, this will be redirected to the enclosing + /// fn item. + [] region_maps: RegionMaps(DefId) -> Rc>, [] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell>, @@ -601,10 +598,6 @@ fn reachability_dep_node(_: CrateNum) -> DepNode { DepNode::Reachability } -fn region_resolve_crate_dep_node(_: CrateNum) -> DepNode { - DepNode::RegionResolveCrate -} - fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode { instance.dep_node() } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e6a8459e00179..07aa627e59674 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2526,7 +2526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let body_id = free_id_outlive.map(|f| f.node_id()) .unwrap_or(DUMMY_NODE_ID); let cause = traits::ObligationCause::misc(span, body_id); - traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) + traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) } pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> { diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 96753d63af203..6e43943bc1747 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -199,7 +199,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, all_loans: all_loans, param_env: &infcx.parameter_environment }; - euv::ExprUseVisitor::new(&mut clcx, &infcx).consume_body(body); + euv::ExprUseVisitor::new(&mut clcx, bccx.owner_def_id, &infcx).consume_body(body); } #[derive(PartialEq)] @@ -238,9 +238,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { //! Like `each_issued_loan()`, but only considers loans that are //! currently in scope. - let tcx = self.tcx(); self.each_issued_loan(scope.node_id(), |loan| { - if tcx.region_maps().is_subscope_of(scope, loan.kill_scope) { + if self.bccx.region_maps.is_subscope_of(scope, loan.kill_scope) { op(loan) } else { true @@ -379,8 +378,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { new_loan); // Should only be called for loans that are in scope at the same time. - assert!(self.tcx().region_maps().scopes_intersect(old_loan.kill_scope, - new_loan.kill_scope)); + assert!(self.bccx.region_maps.scopes_intersect(old_loan.kill_scope, + new_loan.kill_scope)); self.report_error_if_loan_conflicts_with_restriction( old_loan, new_loan, old_loan, new_loan) && diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 9f8ffd86f5414..12854d3c97922 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } Categorization::Local(local_id) => { self.bccx.tcx.mk_region(ty::ReScope( - self.bccx.tcx.region_maps().var_scope(local_id))) + self.bccx.region_maps.var_scope(local_id))) } Categorization::StaticItem | Categorization::Deref(.., mc::UnsafePtr(..)) => { diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 09ed515939de6..9a5d1008c408e 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -51,7 +51,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, }; let body = glcx.bccx.tcx.hir.body(body); - euv::ExprUseVisitor::new(&mut glcx, &infcx).consume_body(body); + euv::ExprUseVisitor::new(&mut glcx, bccx.owner_def_id, &infcx).consume_body(body); glcx.report_potential_errors(); let GatherLoanCtxt { all_loans, move_data, .. } = glcx; @@ -458,7 +458,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { //! notably method arguments, the loan may be introduced only //! later, once it comes into scope. - if self.bccx.tcx.region_maps().is_subscope_of(borrow_scope, loan_scope) { + if self.bccx.region_maps.is_subscope_of(borrow_scope, loan_scope) { borrow_scope } else { loan_scope @@ -488,12 +488,11 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { //! with immutable `&` pointers, because borrows of such pointers //! do not require restrictions and hence do not cause a loan. - let lexical_scope = lp.kill_scope(self.bccx.tcx); - let rm = &self.bccx.tcx.region_maps(); - if rm.is_subscope_of(lexical_scope, loan_scope) { + let lexical_scope = lp.kill_scope(self.bccx); + if self.bccx.region_maps.is_subscope_of(lexical_scope, loan_scope) { lexical_scope } else { - assert!(self.bccx.tcx.region_maps().is_subscope_of(loan_scope, lexical_scope)); + assert!(self.bccx.region_maps.is_subscope_of(loan_scope, lexical_scope)); loan_scope } } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 1a7c700e23955..e5e5045bc29f9 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -34,7 +34,8 @@ use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; use rustc::middle::mem_categorization::ImmutabilityBlame; -use rustc::middle::region; +use rustc::middle::region::{self, RegionMaps}; +use rustc::middle::free_region::RegionRelations; use rustc::ty::{self, TyCtxt}; use rustc::ty::maps::Providers; @@ -88,11 +89,8 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) { let body_id = tcx.hir.body_owned_by(owner_id); let attributes = tcx.get_attrs(owner_def_id); let tables = tcx.typeck_tables_of(owner_def_id); - - let mut bccx = &mut BorrowckCtxt { - tcx: tcx, - tables: tables, - }; + let region_maps = tcx.region_maps(owner_def_id); + let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id }; let body = bccx.tcx.hir.body(body_id); @@ -149,7 +147,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, loan_dfcx.propagate(cfg, body); let flowed_moves = move_data::FlowedMoveData::new(move_data, - this.tcx, + this, cfg, id_range, body); @@ -170,11 +168,8 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( let owner_id = tcx.hir.body_owner(body_id); let owner_def_id = tcx.hir.local_def_id(owner_id); let tables = tcx.typeck_tables_of(owner_def_id); - - let mut bccx = BorrowckCtxt { - tcx: tcx, - tables: tables, - }; + let region_maps = tcx.region_maps(owner_def_id); + let mut bccx = BorrowckCtxt { tcx, tables, region_maps, owner_def_id }; let dataflow_data = build_borrowck_dataflow_data(&mut bccx, cfg, body_id); (bccx, dataflow_data) @@ -189,6 +184,10 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { // tables for the current thing we are checking; set to // Some in `borrowck_fn` and cleared later tables: &'a ty::TypeckTables<'tcx>, + + region_maps: Rc>, + + owner_def_id: DefId, } /////////////////////////////////////////////////////////////////////////// @@ -312,15 +311,15 @@ pub fn closure_to_block(closure_id: ast::NodeId, } impl<'a, 'tcx> LoanPath<'tcx> { - pub fn kill_scope(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> region::CodeExtent<'tcx> { + pub fn kill_scope(&self, bccx: &BorrowckCtxt<'a, 'tcx>) -> region::CodeExtent<'tcx> { match self.kind { - LpVar(local_id) => tcx.region_maps().var_scope(local_id), + LpVar(local_id) => bccx.region_maps.var_scope(local_id), LpUpvar(upvar_id) => { - let block_id = closure_to_block(upvar_id.closure_expr_id, tcx); - tcx.node_extent(block_id) + let block_id = closure_to_block(upvar_id.closure_expr_id, bccx.tcx); + bccx.tcx.node_extent(block_id) } LpDowncast(ref base, _) | - LpExtend(ref base, ..) => base.kill_scope(tcx), + LpExtend(ref base, ..) => base.kill_scope(bccx), } } @@ -479,7 +478,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { r_sup: ty::Region<'tcx>) -> bool { - self.tables.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup) + let region_rels = RegionRelations::new(self.tcx, + self.owner_def_id, + &self.region_maps, + &self.tables.free_region_map); + region_rels.is_subregion_of(r_sub, r_sup) } pub fn report(&self, err: BckError<'tcx>) { diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 3d7df7f037213..3e23086ec7bdd 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -523,7 +523,8 @@ impl<'a, 'tcx> MoveData<'tcx> { /// Moves are generated by moves and killed by assignments and /// scoping. Assignments are generated by assignment to variables and /// killed by scoping. See `README.md` for more details. - fn add_gen_kills(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + fn add_gen_kills(&self, + bccx: &BorrowckCtxt<'a, 'tcx>, dfcx_moves: &mut MoveDataFlow, dfcx_assign: &mut AssignDataFlow) { for (i, the_move) in self.moves.borrow().iter().enumerate() { @@ -546,7 +547,7 @@ impl<'a, 'tcx> MoveData<'tcx> { for path in self.paths.borrow().iter() { match path.loan_path.kind { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { - let kill_scope = path.loan_path.kill_scope(tcx); + let kill_scope = path.loan_path.kill_scope(bccx); let path = *self.path_map.borrow().get(&path.loan_path).unwrap(); self.kill_moves(path, kill_scope.node_id(), KillFrom::ScopeEnd, dfcx_moves); @@ -561,7 +562,7 @@ impl<'a, 'tcx> MoveData<'tcx> { let lp = self.path_loan_path(assignment.path); match lp.kind { LpVar(..) | LpUpvar(..) | LpDowncast(..) => { - let kill_scope = lp.kill_scope(tcx); + let kill_scope = lp.kill_scope(bccx); dfcx_assign.add_kill(KillFrom::ScopeEnd, kill_scope.node_id(), assignment_index); @@ -652,11 +653,13 @@ impl<'a, 'tcx> MoveData<'tcx> { impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { pub fn new(move_data: MoveData<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, + bccx: &BorrowckCtxt<'a, 'tcx>, cfg: &cfg::CFG, id_range: IdRange, body: &hir::Body) -> FlowedMoveData<'a, 'tcx> { + let tcx = bccx.tcx; + let mut dfcx_moves = DataFlowContext::new(tcx, "flowed_move_data_moves", @@ -676,7 +679,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { move_data.fixup_fragment_sets(tcx); - move_data.add_gen_kills(tcx, + move_data.add_gen_kills(bccx, &mut dfcx_moves, &mut dfcx_assign); diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 5a2fc9adc2f02..106b5a26d9564 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -14,6 +14,7 @@ use _match::WitnessPreference::*; use pattern::{Pattern, PatternContext, PatternError, PatternKind}; +use rustc::hir::def_id::DefId; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; @@ -45,9 +46,12 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { b: hir::BodyId, s: Span, id: ast::NodeId) { intravisit::walk_fn(self, fk, fd, b, s, id); + let region_context = self.tcx.hir.local_def_id(id); + MatchVisitor { tcx: self.tcx, tables: self.tcx.body_tables(b), + region_context: region_context, param_env: &ty::ParameterEnvironment::for_item(self.tcx, id) }.visit_body(self.tcx.hir.body(b)); } @@ -64,6 +68,7 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn struct MatchVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + region_context: DefId, tables: &'a ty::TypeckTables<'tcx>, param_env: &'a ty::ParameterEnvironment<'tcx> } @@ -517,7 +522,7 @@ fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) { let mut checker = MutationChecker { cx: cx, }; - ExprUseVisitor::new(&mut checker, &infcx).walk_expr(guard); + ExprUseVisitor::new(&mut checker, cx.region_context, &infcx).walk_expr(guard); }); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index bb3bda6827798..aa33d4b553998 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -924,10 +924,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, "load_dep_graph", || rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map)); - time(time_passes, - "region resolution", - || middle::region::resolve_crate(tcx)); - time(time_passes, "stability index", || { tcx.stability.borrow_mut().build(tcx) }); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 38f9854857115..1036b96d7f527 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -155,7 +155,8 @@ fn test_env(source_string: &str, body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); - infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID); + let def_id = tcx.hir.map.local_def_id(ast::CRATE_NODE_ID); + infcx.resolve_regions_and_report_errors(def_id, ®ion_map, &free_regions); assert_eq!(tcx.sess.err_count(), expected_err_count); }); }); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 7c12c9ef5fadd..2505e2f8211b0 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span) { let local_id = self.var_indices[&var]; let var_ty = self.local_decls[local_id].ty; - let extent = self.hir.tcx().region_maps().var_scope(var); + let extent = self.hir.region_maps.var_scope(var); self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty); } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 6c01e4315f3e9..b8f1b754b48e8 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -134,7 +134,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let tcx = hir.tcx(); let span = tcx.hir.span(fn_id); - let mut builder = Builder::new(hir, span, arguments.len(), return_ty); + let mut builder = Builder::new(hir.clone(), span, arguments.len(), return_ty); let call_site_extent = tcx.intern_code_extent( @@ -202,11 +202,10 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, let ty = hir.tables().expr_ty_adjusted(ast_expr); let owner_id = tcx.hir.body_owner(body_id); let span = tcx.hir.span(owner_id); - let mut builder = Builder::new(hir, span, 0, ty); + let mut builder = Builder::new(hir.clone(), span, 0, ty); - let region_maps = tcx.region_maps(); - let extent = region_maps.temporary_scope(tcx, ast_expr.id) - .unwrap_or(tcx.item_extent(owner_id)); + let extent = hir.region_maps.temporary_scope(tcx, ast_expr.id) + .unwrap_or(tcx.item_extent(owner_id)); let mut block = START_BLOCK; let _ = builder.in_scope(extent, block, |builder| { let expr = builder.hir.mirror(ast_expr); diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 15c2df55cf3c8..2ec4a8a07df71 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -84,7 +84,7 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { let block_ty = cx.tables().node_id_to_type(block.id); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, block.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, block.id); let expr = Expr { ty: block_ty, temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e37df8822c892..6a1817aba0983 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -26,7 +26,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, self.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, self.id); let expr_extent = cx.tcx.node_extent(self.id); debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span); @@ -216,7 +216,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; // Finally, create a destruction scope, if any. - if let Some(extent) = cx.tcx.opt_destruction_extent(self.id) { + if let Some(extent) = cx.region_maps.opt_destruction_extent(self.id) { expr = Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -238,7 +238,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { let expr_ty = cx.tables().expr_ty(expr); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id); let kind = match expr.node { // Here comes the interesting stuff: @@ -707,7 +707,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, method_call: ty::MethodCall) -> Expr<'tcx> { let callee = cx.tables().method_map[&method_call]; - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id); Expr { temp_lifetime: temp_lifetime, temp_lifetime_was_shrunk: was_shrunk, @@ -791,7 +791,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id); match def { Def::Local(def_id) => { @@ -979,7 +979,7 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, PassArgs::ByRef => { let region = cx.tcx.node_scope_region(expr.id); let (temp_lifetime, was_shrunk) = - cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); + cx.region_maps.temporary_scope2(cx.tcx, expr.id); argrefs.extend(args.iter() .map(|arg| { let arg_ty = cx.tables().expr_ty_adjusted(arg); @@ -1031,7 +1031,7 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, expr.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, expr.id); let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args); let ref_expr = Expr { temp_lifetime: temp_lifetime, @@ -1056,7 +1056,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_expr_id: closure_expr.id, }; let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap(); - let (temp_lifetime, was_shrunk) = cx.tcx.region_maps().temporary_scope2(cx.tcx, closure_expr.id); + let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(cx.tcx, closure_expr.id); let var_ty = cx.tables().node_id_to_type(id_var); let captured_var = Expr { temp_lifetime: temp_lifetime, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index e73eaafc4b9fe..3e9bcb3e18627 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -22,17 +22,20 @@ use rustc_const_eval::ConstContext; use rustc_data_structures::indexed_vec::Idx; use rustc::hir::def_id::DefId; use rustc::hir::map::blocks::FnLikeNode; +use rustc::middle::region::RegionMaps; use rustc::infer::InferCtxt; use rustc::ty::subst::Subst; use rustc::ty::{self, Ty, TyCtxt}; use syntax::symbol::{Symbol, InternedString}; use rustc::hir; use rustc_const_math::{ConstInt, ConstUsize}; +use std::rc::Rc; -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + pub region_maps: Rc>, constness: hir::Constness, /// True if this constant/function needs overflow checks. @@ -51,7 +54,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { MirSource::Promoted(..) => bug!(), }; - let attrs = infcx.tcx.hir.attrs(src.item_id()); + let tcx = infcx.tcx; + let src_id = src.item_id(); + let src_def_id = tcx.hir.local_def_id(src_id); + + let region_maps = tcx.region_maps(src_def_id); + + let attrs = tcx.hir.attrs(src_id); // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on @@ -60,17 +69,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { .any(|item| item.check_name("rustc_inherit_overflow_checks")); // Respect -C overflow-checks. - check_overflow |= infcx.tcx.sess.overflow_checks(); + check_overflow |= tcx.sess.overflow_checks(); // Constants and const fn's always need overflow checks. check_overflow |= constness == hir::Constness::Const; - Cx { - tcx: infcx.tcx, - infcx: infcx, - constness: constness, - check_overflow: check_overflow, - } + Cx { tcx, infcx, region_maps, constness, check_overflow } } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index cb0625ceccfcb..cd2d9165c6a53 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -130,7 +130,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { }; let outer_tables = self.tables; - self.tables = self.tcx.typeck_tables_of(self.tcx.hir.local_def_id(item_id)); + let item_def_id = self.tcx.hir.local_def_id(item_id); + self.tables = self.tcx.typeck_tables_of(item_def_id); let body = self.tcx.hir.body(body_id); if !self.in_fn { @@ -140,7 +141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| { let param_env = infcx.parameter_environment.clone(); let outer_penv = mem::replace(&mut self.param_env, param_env); - euv::ExprUseVisitor::new(self, &infcx).consume_body(body); + euv::ExprUseVisitor::new(self, item_def_id, &infcx).consume_body(body); outer_penv }); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 2e84aff49859d..80330afaad841 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -11,13 +11,13 @@ use rustc::hir::{self, ImplItemKind, TraitItemKind}; use rustc::infer::{self, InferOk}; use rustc::middle::free_region::FreeRegionMap; +use rustc::middle::region::RegionMaps; use rustc::ty::{self, TyCtxt}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; use rustc::ty::error::{ExpectedFound, TypeError}; use rustc::ty::subst::{Subst, Substs}; use rustc::util::common::ErrorReported; -use syntax::ast; use syntax_pos::Span; use super::{Inherited, FnCtxt}; @@ -30,14 +30,12 @@ use astconv::ExplicitSelf; /// /// - impl_m: type of the method we are checking /// - impl_m_span: span to use for reporting errors -/// - impl_m_body_id: id of the method body /// - trait_m: the method in the trait /// - impl_trait_ref: the TraitRef corresponding to the trait implementation pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, - impl_m_body_id: ast::NodeId, trait_m: &ty::AssociatedItem, impl_trait_ref: ty::TraitRef<'tcx>, trait_item_span: Option, @@ -72,7 +70,6 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Err(ErrorReported) = compare_predicate_entailment(tcx, impl_m, impl_m_span, - impl_m_body_id, trait_m, impl_trait_ref, old_broken_mode) { @@ -83,21 +80,25 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, - impl_m_body_id: ast::NodeId, trait_m: &ty::AssociatedItem, impl_trait_ref: ty::TraitRef<'tcx>, old_broken_mode: bool) -> Result<(), ErrorReported> { let trait_to_impl_substs = impl_trait_ref.substs; + // This node-id should be used for the `body_id` field on each + // `ObligationCause` (and the `FnCtxt`). This is what + // `regionck_item` expects. + let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); + let cause = ObligationCause { span: impl_m_span, - body_id: impl_m_body_id, + body_id: impl_m_node_id, code: ObligationCauseCode::CompareImplMethodObligation { item_name: impl_m.name, impl_item_def_id: impl_m.def_id, trait_item_def_id: trait_m.def_id, - lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None }, + lint_id: if !old_broken_mode { Some(impl_m_node_id) } else { None }, }, }; @@ -166,7 +167,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Create a parameter environment that represents the implementation's // method. - let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id); // Create mapping from impl to skolemized. @@ -217,9 +217,10 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Construct trait parameter environment and then shift it into the skolemized viewpoint. // The key step here is to update the caller_bounds's predicates to be // the new hybrid bounds we computed. - let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_body_id); + let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id); let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.predicates); let trait_param_env = traits::normalize_param_env_or_error(tcx, + impl_m.def_id, trait_param_env, normalize_cause.clone()); @@ -275,7 +276,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_sig.subst(tcx, impl_to_skol_substs); let impl_sig = inh.normalize_associated_types_in(impl_m_span, - impl_m_body_id, + impl_m_node_id, &impl_sig); let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig)); debug!("compare_impl_method: impl_fty={:?}", impl_fty); @@ -287,7 +288,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_sig.subst(tcx, trait_to_skol_substs); let trait_sig = inh.normalize_associated_types_in(impl_m_span, - impl_m_body_id, + impl_m_node_id, &trait_sig); let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig)); @@ -349,13 +350,14 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // region obligations that get overlooked. The right // thing to do is the code below. But we keep this old // pass around temporarily. + let region_maps = RegionMaps::new(); let mut free_regions = FreeRegionMap::new(); free_regions.relate_free_regions_from_predicates( &infcx.parameter_environment.caller_bounds); - infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id); + infcx.resolve_regions_and_report_errors(impl_m.def_id, ®ion_maps, &free_regions); } else { - let fcx = FnCtxt::new(&inh, impl_m_body_id); - fcx.regionck_item(impl_m_body_id, impl_m_span, &[]); + let fcx = FnCtxt::new(&inh, impl_m_node_id); + fcx.regionck_item(impl_m_node_id, impl_m_span, &[]); } Ok(()) diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index e4408413ee6c5..c20777a403aac 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -13,7 +13,7 @@ use check::regionck::RegionCtxt; use hir::def_id::DefId; use middle::free_region::FreeRegionMap; use rustc::infer::{self, InferOk}; -use middle::region; +use rustc::middle::region::{self, RegionMaps}; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::traits::{self, ObligationCause, Reveal}; @@ -116,8 +116,9 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( return Err(ErrorReported); } + let region_maps = RegionMaps::new(); let free_regions = FreeRegionMap::new(); - infcx.resolve_regions_and_report_errors(&free_regions, drop_impl_node_id); + infcx.resolve_regions_and_report_errors(drop_impl_did, ®ion_maps, &free_regions); Ok(()) }) } @@ -278,7 +279,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( ty, scope); - let parent_scope = match rcx.tcx.region_maps().opt_encl_scope(scope) { + let parent_scope = match rcx.region_maps.opt_encl_scope(scope) { Some(parent_scope) => parent_scope, // If no enclosing scope, then it must be the root scope // which cannot be outlived. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 729d25aaef541..7705041fc92d2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1237,14 +1237,13 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, err.emit() } } - hir::ImplItemKind::Method(_, body_id) => { + hir::ImplItemKind::Method(..) => { let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssociatedKind::Method { let err_count = tcx.sess.err_count(); compare_impl_method(tcx, &ty_impl_item, impl_item.span, - body_id.node_id, &ty_trait_item, impl_trait_ref, trait_span, @@ -1254,7 +1253,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, compare_impl_method(tcx, &ty_impl_item, impl_item.span, - body_id.node_id, &ty_trait_item, impl_trait_ref, trait_span, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 9a978934dda42..b241f52f62e9b 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -87,7 +87,8 @@ use check::FnCtxt; use middle::free_region::FreeRegionMap; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; -use middle::region::{self, CodeExtent}; +use middle::region::{self, CodeExtent, RegionMaps}; +use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty, MethodCall, TypeFoldable}; @@ -97,6 +98,7 @@ use rustc::ty::wf::ImpliedBound; use std::mem; use std::ops::Deref; +use std::rc::Rc; use syntax::ast; use syntax_pos::Span; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -112,8 +114,9 @@ macro_rules! ignore_err { impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn regionck_expr(&self, body: &'gcx hir::Body) { + let subject = self.tcx.hir.body_owner_def_id(body.id()); let id = body.value.id; - let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(id)); + let mut rcx = RegionCtxt::new(self, RepeatingScope(id), id, Subject(subject)); if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded rcx.visit_body(body); @@ -132,7 +135,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, wf_tys: &[Ty<'tcx>]) { debug!("regionck_item(item.id={:?}, wf_tys={:?}", item_id, wf_tys); - let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(item_id)); + let subject = self.tcx.hir.local_def_id(item_id); + let mut rcx = RegionCtxt::new(self, RepeatingScope(item_id), item_id, Subject(subject)); rcx.free_region_map.relate_free_regions_from_predicates( &self.parameter_environment.caller_bounds); rcx.relate_free_regions(wf_tys, item_id, span); @@ -144,8 +148,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn_id: ast::NodeId, body: &'gcx hir::Body) { debug!("regionck_fn(id={})", fn_id); + let subject = self.tcx.hir.body_owner_def_id(body.id()); let node_id = body.value.id; - let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(fn_id)); + let mut rcx = RegionCtxt::new(self, RepeatingScope(node_id), node_id, Subject(subject)); if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded @@ -173,6 +178,8 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>, + pub region_maps: Rc>, + free_region_map: FreeRegionMap<'tcx>, // id of innermost fn body id @@ -185,7 +192,7 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { repeating_scope: ast::NodeId, // id of AST node being analyzed (the subject of the analysis). - subject: ast::NodeId, + subject_def_id: DefId, } @@ -197,19 +204,21 @@ impl<'a, 'gcx, 'tcx> Deref for RegionCtxt<'a, 'gcx, 'tcx> { } pub struct RepeatingScope(ast::NodeId); -pub struct Subject(ast::NodeId); +pub struct Subject(DefId); impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn new(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, RepeatingScope(initial_repeating_scope): RepeatingScope, initial_body_id: ast::NodeId, Subject(subject): Subject) -> RegionCtxt<'a, 'gcx, 'tcx> { + let region_maps = fcx.tcx.region_maps(subject); RegionCtxt { fcx: fcx, + region_maps: region_maps, repeating_scope: initial_repeating_scope, body_id: initial_body_id, call_site_scope: None, - subject: subject, + subject_def_id: subject, region_bound_pairs: Vec::new(), free_region_map: FreeRegionMap::new(), } @@ -418,14 +427,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } fn resolve_regions_and_report_errors(&self) { - let subject_node_id = self.subject; - - self.fcx.resolve_regions_and_report_errors(&self.free_region_map, - subject_node_id); + self.fcx.resolve_regions_and_report_errors(self.subject_def_id, + &self.region_maps, + &self.free_region_map); } fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) { - let tcx = self.tcx; debug!("regionck::visit_pat(pat={:?})", pat); pat.each_binding(|_, id, span, _| { // If we have a variable that contains region'd data, that @@ -451,7 +458,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { // that the lifetime of any regions that appear in a // variable's type enclose at least the variable's scope. - let var_scope = tcx.region_maps().var_scope(id); + let var_scope = self.region_maps.var_scope(id); let var_region = self.tcx.mk_region(ty::ReScope(var_scope)); let origin = infer::BindingTypeIsNotValidAtDecl(span); @@ -570,7 +577,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // If necessary, constrain destructors in the unadjusted form of this // expression. let cmt_result = { - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); mc.cat_expr_unadjusted(expr) }; match cmt_result { @@ -587,7 +594,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // If necessary, constrain destructors in this expression. This will be // the adjusted form if there is an adjustment. let cmt_result = { - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); mc.cat_expr(expr) }; match cmt_result { @@ -949,7 +956,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { r, m); { - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i)); debug!("constrain_autoderefs: self_cmt={:?}", self_cmt); @@ -1061,7 +1068,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("link_addr_of(expr={:?}, base={:?})", expr, base); let cmt = { - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); ignore_err!(mc.cat_expr(base)) }; @@ -1079,7 +1086,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { None => { return; } Some(ref expr) => &**expr, }; - let mc = mc::MemCategorizationContext::new(self); + let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); self.link_pattern(mc, discr_cmt, &local.pat); } @@ -1089,7 +1096,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// linked to the lifetime of its guarantor (if any). fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) { debug!("regionck::for_match()"); - let mc = mc::MemCategorizationContext::new(self); + let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); let discr_cmt = ignore_err!(mc.cat_expr(discr)); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { @@ -1104,7 +1111,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// linked to the lifetime of its guarantor (if any). fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); - let mc = mc::MemCategorizationContext::new(self); + let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); for arg in args { let arg_ty = self.node_ty(arg.id); let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); @@ -1121,13 +1128,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// Link lifetimes of any ref bindings in `root_pat` to the pointers found /// in the discriminant, if needed. fn link_pattern<'t>(&self, - mc: mc::MemCategorizationContext<'a, 'gcx, 'tcx>, + mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>, discr_cmt: mc::cmt<'tcx>, root_pat: &hir::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat); - let _ = mc.cat_pattern(discr_cmt, root_pat, |_, sub_cmt, sub_pat| { + let _ = mc.cat_pattern(discr_cmt, root_pat, |_, sub_cmt, sub_pat| { match sub_pat.node { // `ref x` pattern PatKind::Binding(hir::BindByRef(mutbl), ..) => { @@ -1147,7 +1154,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { autoref: &adjustment::AutoBorrow<'tcx>) { debug!("link_autoref(autoderefs={}, autoref={:?})", autoderefs, autoref); - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs)); debug!("expr_cmt={:?}", expr_cmt); @@ -1171,7 +1178,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { callee_scope: CodeExtent<'tcx>) { debug!("link_by_ref(expr={:?}, callee_scope={:?})", expr, callee_scope); - let mc = mc::MemCategorizationContext::new(self); + let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); let expr_cmt = ignore_err!(mc.cat_expr(expr)); let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope)); self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index a2c9b7876aafa..227f06436ee17 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -164,9 +164,11 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id()); { + let body_owner_def_id = self.fcx.tcx.hir.body_owner_def_id(body.id()); let mut euv = euv::ExprUseVisitor::with_options(self, self.fcx, + body_owner_def_id, mc::MemCategorizationOptions { during_closure_kind_inference: true }); diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 57193b3584dfa..49785d8850f4d 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -12,6 +12,7 @@ //! up data structures required by type-checking/translation. use rustc::middle::free_region::FreeRegionMap; +use rustc::middle::region::RegionMaps; use rustc::middle::lang_items::UnsizeTraitLangItem; use rustc::traits::{self, ObligationCause, Reveal}; @@ -342,10 +343,11 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // Finally, resolve all regions. + let region_maps = RegionMaps::new(); let mut free_regions = FreeRegionMap::new(); free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment .caller_bounds); - infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id); + infcx.resolve_regions_and_report_errors(impl_did, ®ion_maps, &free_regions); CoerceUnsizedInfo { custom_kind: kind diff --git a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs index d1f957bf6b955..a81c0846a2794 100644 --- a/src/test/run-pass/kindck-implicit-close-over-mut-var.rs +++ b/src/test/run-pass/kindck-implicit-close-over-mut-var.rs @@ -1,4 +1,4 @@ -s// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // From 6c2f64bdd8213012562f56e8fc393d99803e1c27 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 29 Apr 2017 07:05:03 -0400 Subject: [PATCH 07/17] modify `ExprUseVisitor` and friends to take region-maps, not def-id --- src/librustc/middle/expr_use_visitor.rs | 9 +++++---- src/librustc/middle/mem_categorization.rs | 9 ++++----- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- .../borrowck/gather_loans/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 11 ++++++----- src/librustc_passes/consts.rs | 3 ++- src/librustc_typeck/check/regionck.rs | 18 +++++++++--------- src/librustc_typeck/check/upvar.rs | 3 ++- 8 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index a49f3d3b7a7fa..41f9311dd809b 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -23,6 +23,7 @@ use hir::def::Def; use hir::def_id::{DefId}; use infer::InferCtxt; use middle::mem_categorization as mc; +use middle::region::RegionMaps; use ty::{self, TyCtxt, adjustment}; use hir::{self, PatKind}; @@ -270,24 +271,24 @@ enum PassArgs { impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pub fn new(delegate: &'a mut (Delegate<'tcx>+'a), - context: DefId, + region_maps: &'a RegionMaps<'tcx>, infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self { ExprUseVisitor::with_options(delegate, infcx, - context, + region_maps, mc::MemCategorizationOptions::default()) } pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a), infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - context: DefId, + region_maps: &'a RegionMaps<'tcx>, options: mc::MemCategorizationOptions) -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::with_options(infcx, context, options), + mc: mc::MemCategorizationContext::with_options(infcx, region_maps, options), delegate: delegate } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 0e2db746e45e4..cbe69de401032 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -290,7 +290,7 @@ impl ast_node for hir::Pat { #[derive(Clone)] pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - pub region_maps: Rc>, + pub region_maps: &'a RegionMaps<'tcx>, options: MemCategorizationOptions, } @@ -406,16 +406,15 @@ impl MutabilityCategory { impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { /// Context should be the `DefId` we use to fetch region-maps. pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - context: DefId) + region_maps: &'a RegionMaps<'tcx>) -> MemCategorizationContext<'a, 'gcx, 'tcx> { - MemCategorizationContext::with_options(infcx, context, MemCategorizationOptions::default()) + MemCategorizationContext::with_options(infcx, region_maps, MemCategorizationOptions::default()) } pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - context: DefId, + region_maps: &'a RegionMaps<'tcx>, options: MemCategorizationOptions) -> MemCategorizationContext<'a, 'gcx, 'tcx> { - let region_maps = infcx.tcx.region_maps(context); MemCategorizationContext { infcx: infcx, region_maps: region_maps, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 6e43943bc1747..1c5a6c3985cfc 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -199,7 +199,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, all_loans: all_loans, param_env: &infcx.parameter_environment }; - euv::ExprUseVisitor::new(&mut clcx, bccx.owner_def_id, &infcx).consume_body(body); + euv::ExprUseVisitor::new(&mut clcx, &bccx.region_maps, &infcx).consume_body(body); } #[derive(PartialEq)] diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 9a5d1008c408e..8c1bcdc1fe2b0 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -51,7 +51,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, }; let body = glcx.bccx.tcx.hir.body(body); - euv::ExprUseVisitor::new(&mut glcx, bccx.owner_def_id, &infcx).consume_body(body); + euv::ExprUseVisitor::new(&mut glcx, &bccx.region_maps, &infcx).consume_body(body); glcx.report_potential_errors(); let GatherLoanCtxt { all_loans, move_data, .. } = glcx; diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 106b5a26d9564..6ec5f38aa5bb5 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -14,11 +14,11 @@ use _match::WitnessPreference::*; use pattern::{Pattern, PatternContext, PatternError, PatternKind}; -use rustc::hir::def_id::DefId; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization::{cmt}; +use rustc::middle::region::RegionMaps; use rustc::session::Session; use rustc::traits::Reveal; use rustc::ty::{self, Ty, TyCtxt}; @@ -47,11 +47,12 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { intravisit::walk_fn(self, fk, fd, b, s, id); let region_context = self.tcx.hir.local_def_id(id); + let region_maps = self.tcx.region_maps(region_context); MatchVisitor { tcx: self.tcx, tables: self.tcx.body_tables(b), - region_context: region_context, + region_maps: ®ion_maps, param_env: &ty::ParameterEnvironment::for_item(self.tcx, id) }.visit_body(self.tcx.hir.body(b)); } @@ -68,9 +69,9 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn struct MatchVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - region_context: DefId, tables: &'a ty::TypeckTables<'tcx>, - param_env: &'a ty::ParameterEnvironment<'tcx> + param_env: &'a ty::ParameterEnvironment<'tcx>, + region_maps: &'a RegionMaps<'tcx>, } impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { @@ -522,7 +523,7 @@ fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Expr) { let mut checker = MutationChecker { cx: cx, }; - ExprUseVisitor::new(&mut checker, cx.region_context, &infcx).walk_expr(guard); + ExprUseVisitor::new(&mut checker, cx.region_maps, &infcx).walk_expr(guard); }); } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index cd2d9165c6a53..47ea144dcde64 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -141,7 +141,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { let outer_penv = self.tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| { let param_env = infcx.parameter_environment.clone(); let outer_penv = mem::replace(&mut self.param_env, param_env); - euv::ExprUseVisitor::new(self, item_def_id, &infcx).consume_body(body); + let region_maps = &self.tcx.region_maps(item_def_id);; + euv::ExprUseVisitor::new(self, region_maps, &infcx).consume_body(body); outer_penv }); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index b241f52f62e9b..8a63d501da8c3 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -577,7 +577,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // If necessary, constrain destructors in the unadjusted form of this // expression. let cmt_result = { - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); mc.cat_expr_unadjusted(expr) }; match cmt_result { @@ -594,7 +594,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { // If necessary, constrain destructors in this expression. This will be // the adjusted form if there is an adjustment. let cmt_result = { - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); mc.cat_expr(expr) }; match cmt_result { @@ -956,7 +956,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { r, m); { - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i)); debug!("constrain_autoderefs: self_cmt={:?}", self_cmt); @@ -1068,7 +1068,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { debug!("link_addr_of(expr={:?}, base={:?})", expr, base); let cmt = { - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); ignore_err!(mc.cat_expr(base)) }; @@ -1086,7 +1086,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { None => { return; } Some(ref expr) => &**expr, }; - let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = &mc::MemCategorizationContext::new(self, &self.region_maps); let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); self.link_pattern(mc, discr_cmt, &local.pat); } @@ -1096,7 +1096,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// linked to the lifetime of its guarantor (if any). fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) { debug!("regionck::for_match()"); - let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = &mc::MemCategorizationContext::new(self, &self.region_maps); let discr_cmt = ignore_err!(mc.cat_expr(discr)); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { @@ -1111,7 +1111,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// linked to the lifetime of its guarantor (if any). fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); - let mc = &mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = &mc::MemCategorizationContext::new(self, &self.region_maps); for arg in args { let arg_ty = self.node_ty(arg.id); let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); @@ -1154,7 +1154,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { autoref: &adjustment::AutoBorrow<'tcx>) { debug!("link_autoref(autoderefs={}, autoref={:?})", autoderefs, autoref); - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs)); debug!("expr_cmt={:?}", expr_cmt); @@ -1178,7 +1178,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { callee_scope: CodeExtent<'tcx>) { debug!("link_by_ref(expr={:?}, callee_scope={:?})", expr, callee_scope); - let mc = mc::MemCategorizationContext::new(self, self.subject_def_id); + let mc = mc::MemCategorizationContext::new(self, &self.region_maps); let expr_cmt = ignore_err!(mc.cat_expr(expr)); let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope)); self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 227f06436ee17..9bfc5f3f0ea54 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -165,10 +165,11 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { { let body_owner_def_id = self.fcx.tcx.hir.body_owner_def_id(body.id()); + let region_maps = &self.fcx.tcx.region_maps(body_owner_def_id); let mut euv = euv::ExprUseVisitor::with_options(self, self.fcx, - body_owner_def_id, + region_maps, mc::MemCategorizationOptions { during_closure_kind_inference: true }); From 1dd082fb3e92e714f7d8e2f1de344a946b601141 Mon Sep 17 00:00:00 2001 From: Cameron Hart Date: Mon, 1 May 2017 23:13:22 +1000 Subject: [PATCH 08/17] Add simple `[repr(align)]` codegen test. Checks alloca and memcpy are aligned correctly. --- src/test/codegen/align-struct.rs | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/test/codegen/align-struct.rs diff --git a/src/test/codegen/align-struct.rs b/src/test/codegen/align-struct.rs new file mode 100644 index 0000000000000..d4828be037a49 --- /dev/null +++ b/src/test/codegen/align-struct.rs @@ -0,0 +1,57 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes +#![crate_type = "lib"] + +#![feature(attr_literals)] +#![feature(repr_align)] + +#[repr(align(64))] +pub struct Align64(i32); + +pub struct Nested64 { + a: Align64, + b: i32, + c: i32, + d: i8, +} + +pub enum Enum64 { + A(Align64), + B(i32), +} + +// CHECK-LABEL: @align64 +#[no_mangle] +pub fn align64(i : i32) -> Align64 { +// CHECK: %a64 = alloca %Align64, align 64 +// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 64, i32 64, i1 false) + let a64 = Align64(i); + a64 +} + +// CHECK-LABEL: @nested64 +#[no_mangle] +pub fn nested64(a: Align64, b: i32, c: i32, d: i8) -> Nested64 { +// CHECK: %n64 = alloca %Nested64, align 64 +// CHECK: %a = alloca %Align64, align 64 + let n64 = Nested64 { a, b, c, d }; + n64 +} + +// CHECK-LABEL: @enum64 +#[no_mangle] +pub fn enum64(a: Align64) -> Enum64 { +// CHECK: %e64 = alloca %Enum64, align 64 +// CHECK: %a = alloca %Align64, align 64 + let e64 = Enum64::A(a); + e64 +} From d4d74dafe8e7ef059e27d69b4ec518fa0228f4b2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 11:05:40 -0400 Subject: [PATCH 09/17] remove unused `is_fn` --- src/librustc/hir/map/mod.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index cae5c5011ce7e..48b8a819fff03 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -572,18 +572,6 @@ impl<'hir> Map<'hir> { } } - /// Check if the node is a non-closure function item - pub fn is_fn(&self, id: NodeId) -> bool { - let entry = if let Some(id) = self.find_entry(id) { id } else { return false }; - - match entry { - EntryItem(_, &Item { node: ItemFn(..), .. }) | - EntryTraitItem(_, &TraitItem { node: TraitItemKind::Method(..), .. }) | - EntryImplItem(_, &ImplItem { node: ImplItemKind::Method(..), .. }) => true, - _ => false, - } - } - /// If there is some error when walking the parents (e.g., a node does not /// have a parent in the map or a node can't be found), then we return the /// last good node id we found. Note that reaching the crate root (id == 0), From c0434e2babf59393b1677eef60d4b56b52ca6e18 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 11:09:36 -0400 Subject: [PATCH 10/17] pacify the mercilous tidy --- src/librustc/infer/region_inference/mod.rs | 4 +++- src/librustc/middle/mem_categorization.rs | 4 +++- src/librustc_mir/build/scope.rs | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index fb699bbd2d25f..39554d1fa3a3a 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -1053,7 +1053,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - fn expansion(&self, region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_values: &mut [VarValue<'tcx>]) { + fn expansion(&self, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, + var_values: &mut [VarValue<'tcx>]) { self.iterate_until_fixed_point("Expansion", |constraint, origin| { debug!("expansion: constraint={:?} origin={:?}", constraint, origin); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index cbe69de401032..11a364f92c316 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -408,7 +408,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, region_maps: &'a RegionMaps<'tcx>) -> MemCategorizationContext<'a, 'gcx, 'tcx> { - MemCategorizationContext::with_options(infcx, region_maps, MemCategorizationOptions::default()) + MemCategorizationContext::with_options(infcx, + region_maps, + MemCategorizationOptions::default()) } pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index fcd06835d9869..f9c08f34eaf3f 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -270,7 +270,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. - pub fn in_scope(&mut self, extent: CodeExtent<'tcx>, mut block: BasicBlock, f: F) -> BlockAnd + pub fn in_scope(&mut self, + extent: CodeExtent<'tcx>, + mut block: BasicBlock, + f: F) + -> BlockAnd where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { debug!("in_scope(extent={:?}, block={:?})", extent, block); From 3438cda788a14b34d7521133531d1fd5ade5a8b8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 11:18:15 -0400 Subject: [PATCH 11/17] use `closure_base_def_id` rather than walking up HIR --- src/librustc/middle/region.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index fb0c3a29deffc..2257c1fa634c4 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1188,20 +1188,17 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { fn region_maps<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_id: DefId) -> Rc> { - let fn_node_id = tcx.hir.as_local_node_id(fn_id) - .expect("fn DefId should be for LOCAL_CRATE"); - let node = tcx.hir.get(fn_node_id); - match node { - hir_map::NodeItem(_) | hir_map::NodeTraitItem(_) | hir_map::NodeImplItem(_) => { } - _ => { - let parent_id = tcx.hir.get_parent(fn_node_id); - let parent_def_id = tcx.hir.local_def_id(parent_id); - return tcx.region_maps(parent_def_id); - } + let closure_base_def_id = tcx.closure_base_def_id(fn_id); + if closure_base_def_id != fn_id { + return tcx.region_maps(closure_base_def_id); } let mut maps = RegionMaps::new(); + let fn_node_id = tcx.hir.as_local_node_id(fn_id) + .expect("fn DefId should be for LOCAL_CRATE"); + let node = tcx.hir.get(fn_node_id); + { let mut visitor = RegionResolutionVisitor { tcx: tcx, From b393d6436065ecba0ffb366e1ae67def664b7f26 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 13:24:25 -0400 Subject: [PATCH 12/17] kill regr test using ad-hoc lint This was a pretty narrow test to start with, and it's kind of a pain to update it. Not worth the trouble IMO. --- .../issue-37290/auxiliary/lint.rs | 68 ------------------- .../run-pass-fulldeps/issue-37290/main.rs | 30 -------- 2 files changed, 98 deletions(-) delete mode 100644 src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs delete mode 100644 src/test/run-pass-fulldeps/issue-37290/main.rs diff --git a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs b/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs deleted file mode 100644 index 778c49d144c02..0000000000000 --- a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This flag is needed for plugins to work: -// compile-flags: -C prefer-dynamic - -#![feature(plugin_registrar, rustc_private)] -#![crate_type = "dylib"] -#![deny(region_hierarchy)] - -extern crate syntax; -#[macro_use] -extern crate rustc; -extern crate rustc_plugin; - -use rustc::lint::{LateContext, LintPass, LateLintPass, LintArray, LintContext}; -use rustc::hir; -use rustc::hir::intravisit::FnKind; -use rustc::middle::region::CodeExtent; -use rustc::util::nodemap::FxHashMap; - -use syntax::ast::{self, NodeId}; -use syntax::codemap::Span; - -declare_lint!(REGION_HIERARCHY, Warn, "warn about bogus region hierarchy"); - -struct Pass { - map: FxHashMap -} - -impl LintPass for Pass { - fn get_lints(&self) -> LintArray { lint_array!(REGION_HIERARCHY) } -} - -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_fn(&mut self, cx: &LateContext, - fk: FnKind, _: &hir::FnDecl, body: &hir::Body, - span: Span, node: ast::NodeId) - { - if let FnKind::Closure(..) = fk { return } - - let mut extent = cx.tcx.region_maps.node_extent(body.value.id); - while let Some(parent) = cx.tcx.region_maps.opt_encl_scope(extent) { - extent = parent; - } - if let Some(other) = self.map.insert(extent, node) { - cx.span_lint(REGION_HIERARCHY, span, &format!( - "different fns {:?}, {:?} with the same root extent {:?}", - cx.tcx.hir.local_def_id(other), - cx.tcx.hir.local_def_id(node), - extent)); - } - } -} - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut ::rustc_plugin::Registry) { - reg.register_late_lint_pass(Box::new( - Pass { map: FxHashMap() } - )); -} diff --git a/src/test/run-pass-fulldeps/issue-37290/main.rs b/src/test/run-pass-fulldeps/issue-37290/main.rs deleted file mode 100644 index 394ad92b1d8c0..0000000000000 --- a/src/test/run-pass-fulldeps/issue-37290/main.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:lint.rs - -#![feature(plugin)] -#![plugin(lint)] - -struct Foo { -} - -impl Foo { - fn bar(&self) -> usize { - 22 - } - - fn baz(&self) -> usize { - 22 - } -} - -fn main() { } - From c008f0540e786b54e799ffed372adb4648d07e87 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 20:11:36 -0400 Subject: [PATCH 13/17] patch the `librustc_driver` unit tests --- src/librustc/middle/region.rs | 29 +++++++++++-------- src/librustc_driver/test.rs | 53 +++++++++++++++++------------------ 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2257c1fa634c4..d1d5e9d6cb18f 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -319,11 +319,28 @@ impl<'tcx> RegionMaps<'tcx> { } } + pub fn record_code_extent(&mut self, + child: CodeExtent<'tcx>, + parent: Option>) { + debug!("{:?}.parent = {:?}", child, parent); + + if let Some(p) = parent { + let prev = self.scope_map.insert(child, p); + assert!(prev.is_none()); + } + + // record the destruction scopes for later so we can query them + if let &CodeExtentData::DestructionScope(n) = child { + self.destruction_scopes.insert(n, child); + } + } + pub fn each_encl_scope(&self, mut e:E) where E: FnMut(CodeExtent<'tcx>, CodeExtent<'tcx>) { for (&child, &parent) in &self.scope_map { e(child, parent) } } + pub fn each_var_scope(&self, mut e:E) where E: FnMut(&ast::NodeId, CodeExtent<'tcx>) { for (child, parent) in self.var_map.iter() { e(child, parent) @@ -1098,17 +1115,7 @@ impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> { parent: Option>) -> 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()); - } - - // record the destruction scopes for later so we can query them - if let &CodeExtentData::DestructionScope(n) = code_extent { - self.region_maps.destruction_scopes.insert(n, code_extent); - } - + self.region_maps.record_code_extent(code_extent, parent); code_extent } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 1036b96d7f527..ced30fd64085c 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -16,7 +16,7 @@ use rustc_lint; use rustc_resolve::MakeGlobMap; use rustc::middle::lang_items; use rustc::middle::free_region::FreeRegionMap; -use rustc::middle::region::{self, CodeExtent}; +use rustc::middle::region::{CodeExtent, RegionMaps}; use rustc::middle::region::CodeExtentData; use rustc::middle::resolve_lifetime; use rustc::middle::stability; @@ -44,6 +44,7 @@ use rustc::hir; struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>, + region_maps: &'a mut RegionMaps<'tcx>, } struct RH<'a> { @@ -136,7 +137,6 @@ fn test_env(source_string: &str, // run just enough stuff to build a tcx: let lang_items = lang_items::collect_language_items(&sess, &hir_map); let named_region_map = resolve_lifetime::krate(&sess, &hir_map); - let region_map = region::resolve_crate(&sess, &hir_map); let index = stability::Index::new(&hir_map); TyCtxt::create_and_enter(&sess, ty::maps::Providers::default(), @@ -146,17 +146,16 @@ fn test_env(source_string: &str, resolutions, named_region_map.unwrap(), hir_map, - region_map, lang_items, index, "test_crate", |tcx| { tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| { - - body(Env { infcx: &infcx }); + let mut region_maps = RegionMaps::new(); + body(Env { infcx: &infcx, region_maps: &mut region_maps }); let free_regions = FreeRegionMap::new(); - let def_id = tcx.hir.map.local_def_id(ast::CRATE_NODE_ID); - infcx.resolve_regions_and_report_errors(def_id, ®ion_map, &free_regions); + let def_id = tcx.hir.local_def_id(ast::CRATE_NODE_ID); + infcx.resolve_regions_and_report_errors(def_id, ®ion_maps, &free_regions); assert_eq!(tcx.sess.err_count(), expected_err_count); }); }); @@ -167,23 +166,21 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { self.infcx.tcx } - pub fn create_region_hierarchy(&self, rh: &RH, parent: CodeExtent) { - let me = self.infcx.tcx.region_maps.intern_node(rh.id, parent); + pub fn create_region_hierarchy(&mut self, rh: &RH, parent: CodeExtent<'tcx>) { + let me = self.tcx().intern_code_extent(CodeExtentData::Misc(rh.id)); + self.region_maps.record_code_extent(me, Some(parent)); for child_rh in rh.sub { self.create_region_hierarchy(child_rh, me); } } - pub fn create_simple_region_hierarchy(&self) { + pub fn create_simple_region_hierarchy(&mut self) { // creates a region hierarchy where 1 is root, 10 and 11 are // children of 1, etc let node = ast::NodeId::from_u32; - let dscope = self.infcx - .tcx - .region_maps - .intern_code_extent(CodeExtentData::DestructionScope(node(1)), - region::ROOT_CODE_EXTENT); + let dscope = self.tcx().intern_code_extent(CodeExtentData::DestructionScope(node(1))); + self.region_maps.record_code_extent(dscope, None); self.create_region_hierarchy(&RH { id: node(1), sub: &[RH { @@ -327,13 +324,13 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> { - let r = ty::ReScope(self.tcx().region_maps.node_extent(ast::NodeId::from_u32(id))); + let r = ty::ReScope(self.tcx().node_extent(ast::NodeId::from_u32(id))); self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) } pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region<'tcx> { self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion { - scope: self.tcx().region_maps.item_extent(nid), + scope: Some(self.tcx().node_extent(nid)), bound_region: ty::BrAnon(id), })) } @@ -431,7 +428,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { #[test] fn contravariant_region_ptr_ok() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr1 = env.t_rptr_scope(1); let t_rptr10 = env.t_rptr_scope(10); @@ -443,7 +440,7 @@ fn contravariant_region_ptr_ok() { #[test] fn contravariant_region_ptr_err() { - test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr1 = env.t_rptr_scope(1); let t_rptr10 = env.t_rptr_scope(10); @@ -463,7 +460,7 @@ fn sub_free_bound_false() { //! //! does NOT hold. - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_free1 = env.t_rptr_free(1, 1); let t_rptr_bound1 = env.t_rptr_late_bound(1); @@ -480,7 +477,7 @@ fn sub_bound_free_true() { //! //! DOES hold. - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); let t_rptr_free1 = env.t_rptr_free(1, 1); @@ -515,7 +512,7 @@ fn lub_free_bound_infer() { //! that it yields `fn(&'x isize)` for some free `'x`, //! anyhow. - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP)); let t_rptr_bound1 = env.t_rptr_late_bound(1); @@ -539,7 +536,7 @@ fn lub_bound_bound() { #[test] fn lub_bound_free() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); let t_rptr_free1 = env.t_rptr_free(1, 1); @@ -573,7 +570,7 @@ fn lub_bound_bound_inverse_order() { #[test] fn lub_free_free() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_free1 = env.t_rptr_free(1, 1); let t_rptr_free2 = env.t_rptr_free(1, 2); @@ -586,7 +583,7 @@ fn lub_free_free() { #[test] fn lub_returning_scope() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_scope10 = env.t_rptr_scope(10); let t_rptr_scope11 = env.t_rptr_scope(11); @@ -599,7 +596,7 @@ fn lub_returning_scope() { #[test] fn glb_free_free_with_common_scope() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_free1 = env.t_rptr_free(1, 1); let t_rptr_free2 = env.t_rptr_free(1, 2); @@ -623,7 +620,7 @@ fn glb_bound_bound() { #[test] fn glb_bound_free() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { env.create_simple_region_hierarchy(); let t_rptr_bound1 = env.t_rptr_late_bound(1); let t_rptr_free1 = env.t_rptr_free(1, 1); @@ -745,7 +742,7 @@ fn subst_ty_renumber_some_bounds() { #[test] fn escaping() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| { // Situation: // Theta = [A -> &'a foo] env.create_simple_region_hierarchy(); From 7423966714aba0bedafee2d7c957363a25f2d849 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 1 May 2017 20:38:59 -0400 Subject: [PATCH 14/17] Fix incorrect hex value in doc comment example. --- src/libstd/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 4ec9076de6166..23ebeb4b8e3fc 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1035,7 +1035,7 @@ impl Child { /// ```no_run /// use std::process; /// -/// process::exit(0x0f00); +/// process::exit(0x0100); /// ``` /// /// [platform-specific behavior]: #platform-specific-behavior From 6cc765dcad14e305f892398d16e270b480eb435b Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 2 May 2017 04:38:46 +0200 Subject: [PATCH 15/17] Add a lint to disallow anonymous parameters --- src/librustc_lint/builtin.rs | 39 +++++++++++++++++++ src/librustc_lint/lib.rs | 5 +++ .../compile-fail/anon-params-deprecated.rs | 25 ++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/test/compile-fail/anon-params-deprecated.rs diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 57ed298809635..c9ec152841b20 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -45,6 +45,7 @@ use syntax::ast; use syntax::attr; use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes}; use syntax_pos::Span; +use syntax::symbol::keywords; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::FnKind; @@ -605,6 +606,44 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { } } +declare_lint! { + pub ANONYMOUS_PARAMETERS, + Allow, + "detects anonymous parameters" +} + +/// Checks for use of anonymous parameters (RFC 1685) +#[derive(Clone)] +pub struct AnonymousParameters; + +impl LintPass for AnonymousParameters { + fn get_lints(&self) -> LintArray { + lint_array!(ANONYMOUS_PARAMETERS) + } +} + +impl EarlyLintPass for AnonymousParameters { + fn check_trait_item(&mut self, cx: &EarlyContext, it: &ast::TraitItem) { + match it.node { + ast::TraitItemKind::Method(ref sig, _) => { + for arg in sig.decl.inputs.iter() { + match arg.pat.node { + ast::PatKind::Ident(_, ident, None) => { + if ident.node.name == keywords::Invalid.name() { + cx.span_lint(ANONYMOUS_PARAMETERS, + arg.pat.span, + "use of deprecated anonymous parameter"); + } + } + _ => (), + } + } + }, + _ => (), + } + } +} + declare_lint! { DEPRECATED_ATTR, Warn, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 8d759d89135ac..c1c14cb1fd29e 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -112,6 +112,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { add_early_builtin!(sess, UnusedParens, UnusedImportBraces, + AnonymousParameters, ); add_early_builtin_with_new!(sess, @@ -244,6 +245,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", }, + FutureIncompatibleInfo { + id: LintId::of(ANONYMOUS_PARAMETERS), + reference: "issue #41686 ", + }, ]); // Register renamed and removed lints diff --git a/src/test/compile-fail/anon-params-deprecated.rs b/src/test/compile-fail/anon-params-deprecated.rs new file mode 100644 index 0000000000000..76edae17dc104 --- /dev/null +++ b/src/test/compile-fail/anon-params-deprecated.rs @@ -0,0 +1,25 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![forbid(anonymous_parameters)] +// Test for the anonymous_parameters deprecation lint (RFC 1685) + +trait T { + fn foo(i32); //~ ERROR use of deprecated anonymous parameter + //~| WARNING hard error + + fn bar_with_default_impl(String, String) {} + //~^ ERROR use of deprecated anonymous parameter + //~| WARNING hard error + //~| ERROR use of deprecated anonymous parameter + //~| WARNING hard error +} + +fn main() {} From d290849a233bb2b06b01167c242b3886d2cf8681 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 2 May 2017 05:55:20 +0200 Subject: [PATCH 16/17] Removal pass for anonymous parameters Removes occurences of anonymous parameters from the rustc codebase, as they are to be deprecated. See issue #41686 and RFC 1685. --- src/libcore/convert.rs | 2 +- src/libcore/hash/sip.rs | 4 +- src/libcore/ops.rs | 4 +- src/librand/distributions/mod.rs | 2 +- src/librand/lib.rs | 2 +- src/librustc/session/config.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc_data_structures/indexed_vec.rs | 2 +- src/librustc_driver/lib.rs | 2 +- src/librustc_save_analysis/dump.rs | 48 ++++++++++----------- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/core.rs | 2 +- src/librustdoc/html/highlight.rs | 8 +++- src/libsyntax/ext/build.rs | 2 +- 14 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 084736685e3a7..f5dc38e8aab67 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -276,7 +276,7 @@ pub trait Into: Sized { pub trait From: Sized { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] - fn from(T) -> Self; + fn from(t: T) -> Self; } /// An attempted conversion that consumes `self`, which may or may not be diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 5f5d07b668237..db12496b6f320 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -403,8 +403,8 @@ impl Default for Hasher { #[doc(hidden)] trait Sip { - fn c_rounds(&mut State); - fn d_rounds(&mut State); + fn c_rounds(_: &mut State); + fn d_rounds(_: &mut State); } #[derive(Debug, Clone, Default)] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 175b3a5a69ac1..391b606f613f2 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -2878,10 +2878,10 @@ pub trait Carrier { type Error; /// Create a `Carrier` from a success value. - fn from_success(Self::Success) -> Self; + fn from_success(_: Self::Success) -> Self; /// Create a `Carrier` from an error value. - fn from_error(Self::Error) -> Self; + fn from_error(_: Self::Error) -> Self; /// Translate this `Carrier` to another implementation of `Carrier` with the /// same associated types. diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index eb9476efb7b4c..67b9449981e0f 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -53,7 +53,7 @@ pub trait Sample { // trait called `Sample` and the other should be `DependentSample`. pub trait IndependentSample: Sample { /// Generate a random value. - fn ind_sample(&self, &mut R) -> Support; + fn ind_sample(&self, _: &mut R) -> Support; } /// A wrapper for generating types that implement `Rand` via the diff --git a/src/librand/lib.rs b/src/librand/lib.rs index f2b43a20f944e..ca05db15ffeb9 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -329,7 +329,7 @@ impl<'a, R: fmt::Debug> fmt::Debug for AsciiGenerator<'a, R> { /// the same stream of randomness multiple times. pub trait SeedableRng: Rng { /// Reseed an RNG with the given seed. - fn reseed(&mut self, Seed); + fn reseed(&mut self, _: Seed); /// Create a new RNG with the given seed. fn from_seed(seed: Seed) -> Self; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0bb4cd69e0cd1..d107e9a84856f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1804,7 +1804,7 @@ mod dep_tracking { use rustc_back::PanicStrategy; pub trait DepTrackingHash { - fn hash(&self, &mut DefaultHasher, ErrorOutputType); + fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType); } macro_rules! impl_dep_tracking_hash_via_hash { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ac7a72e66655f..81b547d5a570a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1467,7 +1467,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub trait InternAs { type Output; - fn intern_with(self, F) -> Self::Output + fn intern_with(self, f: F) -> Self::Output where F: FnOnce(&T) -> R; } diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 62c430dda327f..0642ddc71622b 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -24,7 +24,7 @@ use rustc_serialize as serialize; /// /// (purpose: avoid mixing indexes for different bitvector domains.) pub trait Idx: Copy + 'static + Eq + Debug { - fn new(usize) -> Self; + fn new(idx: usize) -> Self; fn index(self) -> usize; } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e4ed2b8eb8fab..889f4dd4b9aac 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -343,7 +343,7 @@ pub trait CompilerCalls<'a> { // Create a CompilController struct for controlling the behaviour of // compilation. - fn build_controller(&mut self, &Session, &getopts::Matches) -> CompileController<'a>; + fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileController<'a>; } // CompilerCalls instance for a regular rustc build. diff --git a/src/librustc_save_analysis/dump.rs b/src/librustc_save_analysis/dump.rs index 84e1fb03f624e..795ff58e20607 100644 --- a/src/librustc_save_analysis/dump.rs +++ b/src/librustc_save_analysis/dump.rs @@ -13,28 +13,28 @@ use super::external_data::*; use rls_data::CratePreludeData; pub trait Dump { - fn crate_prelude(&mut self, CratePreludeData) {} - fn enum_data(&mut self, EnumData) {} - fn extern_crate(&mut self, ExternCrateData) {} - fn impl_data(&mut self, ImplData) {} - fn inheritance(&mut self, InheritanceData) {} - fn function(&mut self, FunctionData) {} - fn function_ref(&mut self, FunctionRefData) {} - fn function_call(&mut self, FunctionCallData) {} - fn method(&mut self, MethodData) {} - fn method_call(&mut self, MethodCallData) {} - fn macro_data(&mut self, MacroData) {} - fn macro_use(&mut self, MacroUseData) {} - fn mod_data(&mut self, ModData) {} - fn mod_ref(&mut self, ModRefData) {} - fn struct_data(&mut self, StructData) {} - fn struct_variant(&mut self, StructVariantData) {} - fn trait_data(&mut self, TraitData) {} - fn tuple_variant(&mut self, TupleVariantData) {} - fn type_ref(&mut self, TypeRefData) {} - fn typedef(&mut self, TypeDefData) {} - fn use_data(&mut self, UseData) {} - fn use_glob(&mut self, UseGlobData) {} - fn variable(&mut self, VariableData) {} - fn variable_ref(&mut self, VariableRefData) {} + fn crate_prelude(&mut self, _: CratePreludeData) {} + fn enum_data(&mut self, _: EnumData) {} + fn extern_crate(&mut self, _: ExternCrateData) {} + fn impl_data(&mut self, _: ImplData) {} + fn inheritance(&mut self, _: InheritanceData) {} + fn function(&mut self, _: FunctionData) {} + fn function_ref(&mut self, _: FunctionRefData) {} + fn function_call(&mut self, _: FunctionCallData) {} + fn method(&mut self, _: MethodData) {} + fn method_call(&mut self, _: MethodCallData) {} + fn macro_data(&mut self, _: MacroData) {} + fn macro_use(&mut self, _: MacroUseData) {} + fn mod_data(&mut self, _: ModData) {} + fn mod_ref(&mut self, _: ModRefData) {} + fn struct_data(&mut self, _: StructData) {} + fn struct_variant(&mut self, _: StructVariantData) {} + fn trait_data(&mut self, _: TraitData) {} + fn tuple_variant(&mut self, _: TupleVariantData) {} + fn type_ref(&mut self, _: TypeRefData) {} + fn typedef(&mut self, _: TypeDefData) {} + fn use_data(&mut self, _: UseData) {} + fn use_glob(&mut self, _: UseGlobData) {} + fn variable(&mut self, _: VariableData) {} + fn variable_ref(&mut self, _: VariableRefData) {} } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a25eb60d2a2fc..1229851928e47 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -503,7 +503,7 @@ impl<'a> Iterator for ListAttributesIter<'a> { pub trait AttributesExt { /// Finds an attribute as List and returns the list of attributes nested inside. - fn lists<'a>(&'a self, &'a str) -> ListAttributesIter<'a>; + fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>; } impl AttributesExt for [ast::Attribute] { @@ -518,7 +518,7 @@ impl AttributesExt for [ast::Attribute] { pub trait NestedAttributesExt { /// Returns whether the attribute list contains a specific `Word` - fn has_word(self, &str) -> bool; + fn has_word(self, word: &str) -> bool; } impl> NestedAttributesExt for I { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6417270b9c73b..5879be08881fb 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> DocContext<'a, 'tcx> { } pub trait DocAccessLevels { - fn is_doc_reachable(&self, DefId) -> bool; + fn is_doc_reachable(&self, did: DefId) -> bool; } impl DocAccessLevels for AccessLevels { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 15dada10c0dc1..c1f1cb43e41db 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -114,7 +114,7 @@ pub enum Class { pub trait Writer { /// Called when we start processing a span of text that should be highlighted. /// The `Class` argument specifies how it should be highlighted. - fn enter_span(&mut self, Class) -> io::Result<()>; + fn enter_span(&mut self, _: Class) -> io::Result<()>; /// Called at the end of a span of highlighted text. fn exit_span(&mut self) -> io::Result<()>; @@ -131,7 +131,11 @@ pub trait Writer { /// ``` /// The latter can be thought of as a shorthand for the former, which is /// more flexible. - fn string(&mut self, T, Class, Option<&TokenAndSpan>) -> io::Result<()>; + fn string(&mut self, + text: T, + klass: Class, + tas: Option<&TokenAndSpan>) + -> io::Result<()>; } // Implement `Writer` for anthing that can be written to, this just implements diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index e0fb46ff5eb09..09f22e8691e4c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -52,7 +52,7 @@ pub trait AstBuilder { fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; fn ty(&self, span: Span, ty: ast::TyKind) -> P; - fn ty_path(&self, ast::Path) -> P; + fn ty_path(&self, path: ast::Path) -> P; fn ty_ident(&self, span: Span, idents: ast::Ident) -> P; fn ty_rptr(&self, span: Span, From 14bbd0a5a3722bdcb4c5f36d81097e1fb992add3 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 2 May 2017 06:35:36 +0200 Subject: [PATCH 17/17] Address review --- src/libcore/convert.rs | 2 +- src/librustdoc/html/highlight.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index f5dc38e8aab67..21c75ad339511 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -276,7 +276,7 @@ pub trait Into: Sized { pub trait From: Sized { /// Performs the conversion. #[stable(feature = "rust1", since = "1.0.0")] - fn from(t: T) -> Self; + fn from(_: T) -> Self; } /// An attempted conversion that consumes `self`, which may or may not be diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c1f1cb43e41db..a40d1e6bdc917 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -134,7 +134,7 @@ pub trait Writer { fn string(&mut self, text: T, klass: Class, - tas: Option<&TokenAndSpan>) + tok: Option<&TokenAndSpan>) -> io::Result<()>; }