]> git.lizzy.rs Git - rust.git/commitdiff
introduce per-fn RegionMaps
authorTaylor Cramer <cramertaylorj@gmail.com>
Mon, 10 Apr 2017 07:00:08 +0000 (00:00 -0700)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 30 Apr 2017 21:03:30 +0000 (17:03 -0400)
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.

36 files changed:
src/librustc/cfg/construct.rs
src/librustc/dep_graph/dep_node.rs
src/librustc/hir/intravisit.rs
src/librustc/hir/map/mod.rs
src/librustc/infer/mod.rs
src/librustc/infer/region_inference/graphviz.rs
src/librustc/infer/region_inference/mod.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/free_region.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/traits/mod.rs
src/librustc/ty/context.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_const_eval/check_match.rs
src/librustc_driver/driver.rs
src/librustc_driver/test.rs
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/hair/cx/block.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_passes/consts.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/coherence/builtin.rs
src/test/run-pass/kindck-implicit-close-over-mut-var.rs

index 7b7c204a0ee77124a0fa8f16a64605ecdef42607..a8ad49c6582d4f14cc56311bcec6c57716a53d87 100644 (file)
 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 @@ fn add_exiting_edge(&mut self,
         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);
     }
index d05ede07c3f6477b672505b4208550c5eaafd45a..63a4e6196a2e9d8be4c14bc282c71f2631d9c37c 100644 (file)
@@ -56,7 +56,7 @@ pub enum DepNode<D: Clone + Debug> {
     WorkProduct(Arc<WorkProductId>),
 
     // Represents different phases in the compiler.
-    RegionResolveCrate,
+    RegionMaps(D),
     Coherence,
     Resolve,
     CoherenceCheckTrait(D),
@@ -197,7 +197,6 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             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 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
                 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),
index 2b0d53b2bc35645403aed989624f577e69c3abd1..3e610dd3c0d87a74eda2f237177080f37a1b9b24 100644 (file)
@@ -39,7 +39,7 @@
 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 @@ pub fn inter(self) -> Option<&'this Map<'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.
 
index 48b8a819fff03eb53d018baebac65a13f04db6de..cae5c5011ce7e64a9851d4d75aa11252479e490a 100644 (file)
@@ -572,6 +572,18 @@ pub fn is_argument(&self, id: NodeId) -> bool {
         }
     }
 
+    /// 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),
index a0451c5fe0b4df2b54927dc8d86de7dcf20992fe..e91af21c6db2c3d7acc6085b0aff8c13afb61a2b 100644 (file)
@@ -20,7 +20,8 @@
 
 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 @@ pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'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(&region_rels);
         if !self.is_tainted_by_errors() {
             // As a heuristic, just skip reporting region errors
             // altogether if other errors have been reported while
index 7de81e14d7754f66efa6ccf8aeb689b038e335f9..c48b8f610a2b735eea07a629d42b5d9e38d926d0 100644 (file)
@@ -18,7 +18,9 @@
 /// For clarity, rename the graphviz crate locally to dot.
 use graphviz as dot;
 
-use ty::{self, TyCtxt};
+use hir::def_id::DefIndex;
+use ty;
+use middle::free_region::RegionRelations;
 use middle::region::CodeExtent;
 use super::Constraint;
 use infer::SubregionOrigin;
@@ -32,7 +34,6 @@
 use std::io;
 use std::io::prelude::*;
 use std::sync::atomic::{AtomicBool, Ordering};
-use syntax::ast;
 
 fn print_help_message() {
     println!("\
@@ -55,18 +56,18 @@ fn print_help_message() {
 
 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<Constraint<'tcx>, SubregionOrigin<'tcx>>,
     node_ids: FxHashMap<Node<'tcx>, 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 @@ fn new(tcx: TyCtxt<'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 @@ fn nodes(&self) -> dot::Nodes<Node<'tcx>> {
     fn edges(&self) -> dot::Edges<Edge<'tcx>> {
         debug!("constraint graph has {} edges", self.map.len());
         let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
-        self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
+        self.region_rels.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
         debug!("region graph has {} edges", v.len());
         Cow::Owned(v)
     }
@@ -263,14 +264,14 @@ fn target(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
 
 pub type ConstraintMap<'tcx> = FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
 
-fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+fn dump_region_constraints_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
                                               map: &ConstraintMap<'tcx>,
                                               path: &str)
                                               -> io::Result<()> {
     debug!("dump_region_constraints map (len: {}) path: {}",
            map.len(),
            path);
-    let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
+    let g = ConstraintGraph::new(format!("region_constraints"), region_rels, map);
     debug!("dump_region_constraints calling render");
     let mut v = Vec::new();
     dot::render(&g, &mut v).unwrap();
index 33754b738a09134d366fbb16f6c962562b884bbd..fb699bbd2d25f90d194d7e48401e67911777798f 100644 (file)
@@ -22,7 +22,7 @@
 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::fmt;
 use std::mem;
 use std::u32;
-use syntax::ast;
 
 mod graphviz;
 
@@ -892,18 +891,17 @@ pub fn tainted(&self,
     /// 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<RegionResolutionError<'tcx>> {
         debug!("RegionVarBindings: resolve_regions()");
         let mut errors = vec![];
-        let v = self.infer_variable_values(free_regions, &mut errors, subject_node);
+        let v = self.infer_variable_values(region_rels, &mut errors);
         *self.values.borrow_mut() = Some(v);
         errors
     }
 
     fn lub_concrete_regions(&self,
-                            free_regions: &FreeRegionMap<'tcx>,
+                            region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
                             a: Region<'tcx>,
                             b: Region<'tcx>)
                             -> Region<'tcx> {
@@ -939,7 +937,7 @@ fn lub_concrete_regions(&self,
                 // 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 @@ fn lub_concrete_regions(&self,
                 // 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 @@ struct RegionAndOrigin<'tcx> {
 
 impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
     fn infer_variable_values(&self,
-                             free_regions: &FreeRegionMap<'tcx>,
-                             errors: &mut Vec<RegionResolutionError<'tcx>>,
-                             subject: ast::NodeId)
+                             region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
+                             errors: &mut Vec<RegionResolutionError<'tcx>>)
                              -> Vec<VarValue<'tcx>> {
         let mut var_data = self.construct_var_data();
 
         // Dorky hack to cause `dump_constraints` to only get called
         // if debug mode is enabled:
-        debug!("----() End constraint listing (subject={}) {:?}---",
-               subject,
-               self.dump_constraints(subject));
-        graphviz::maybe_print_constraints_for(self, subject);
+        debug!("----() End constraint listing (context={:?}) {:?}---",
+               region_rels.context,
+               self.dump_constraints(region_rels));
+        graphviz::maybe_print_constraints_for(self, region_rels);
 
         let graph = self.construct_graph();
         self.expand_givens(&graph);
-        self.expansion(free_regions, &mut var_data);
-        self.collect_errors(free_regions, &mut var_data, errors);
-        self.collect_var_errors(free_regions, &var_data, &graph, errors);
+        self.expansion(region_rels, &mut var_data);
+        self.collect_errors(region_rels, &mut var_data, errors);
+        self.collect_var_errors(region_rels, &var_data, &graph, errors);
         var_data
     }
 
@@ -1023,9 +1020,9 @@ fn construct_var_data(&self) -> Vec<VarValue<'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 @@ fn expand_givens(&self, graph: &RegionGraph) {
         }
     }
 
-    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 @@ fn expansion(&self, free_regions: &FreeRegionMap<'tcx>, var_values: &mut [VarVal
     }
 
     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 @@ fn expand_node(&self,
 
         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 @@ fn expand_node(&self,
     /// 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<VarValue<'tcx>>,
                       errors: &mut Vec<RegionResolutionError<'tcx>>) {
         let constraints = self.constraints.borrow();
@@ -1146,7 +1143,7 @@ fn collect_errors(&self,
                 }
 
                 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 @@ fn collect_errors(&self,
                     // 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 @@ fn collect_errors(&self,
         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 @@ fn collect_errors(&self,
     /// 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<RegionResolutionError<'tcx>>) {
@@ -1258,7 +1255,7 @@ fn collect_var_errors(&self,
                        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 @@ fn construct_graph(&self) -> RegionGraph<'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 @@ fn free_regions_first(a: &RegionAndOrigin, b: &RegionAndOrigin) -> Ordering {
 
         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 @@ pub fn and(self, vb: VerifyBound<'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<VarValue<'tcx>>,
               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)),
         }
     }
 }
index 9be05313439fd1648db0dccbf6191d7ea85462a4..a49f3d3b7a7fa6c1e110a6d167f24dde173cc61d 100644 (file)
@@ -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
         }
     }
index 1dc633c6d0040b060bbe7e59596c84ecd8f3b00f..2dc7aac04aede4bc53413f5fefd0d65cb9b6ec13 100644 (file)
 //! `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 @@ pub fn lub_free_regions<'a, 'gcx>(&self,
         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> {
index 3b1a9552ece26b5429842a10b4b28647b2698363..0e2db746e45e4bc747d0db30776f8f572191cb2f 100644 (file)
@@ -70,6 +70,7 @@
 
 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 @@ fn id(&self) -> ast::NodeId { self.id }
     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<RegionMaps<'tcx>>,
     options: MemCategorizationOptions,
 }
 
@@ -402,16 +404,21 @@ pub fn to_user_str(&self) -> &'static str {
 }
 
 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 @@ fn env_deref(&self,
             };
 
             match fn_expr.node {
-                hir::ExprClosure(.., body_id, _) => body_id.node_id,
+                hir::ExprClosure(.., body_id, _) => body_id,
                 _ => bug!()
             }
         };
@@ -796,7 +803,7 @@ fn env_deref(&self,
             // 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 @@ fn env_deref(&self,
     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
index 062432e27e549d67c37618ac424edf6964f3e9eb..fb0c3a29deffc5931931a34ed08258babfd6767a 100644 (file)
@@ -29,8 +29,7 @@
 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<CodeExtent<'tcx>>,
 
+    /// maps from a node-id to the associated destruction scope (if any)
+    destruction_scopes: NodeMap<CodeExtent<'tcx>>,
+
     /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
     /// larger than the default. The map goes from the expression id
     /// 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<E>(&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 @@ pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, CodeExtent
         }
     }
 
+    pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option<CodeExtent<'tcx>> {
+        self.destruction_scopes.get(&n).cloned()
+    }
+
     /// Records that `sub_fn` is defined within `sup_fn`. These ids
     /// should be the id of the block that is the fn body, which is
     /// also the root of the region hierarchy for that fn.
@@ -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 @@ pub fn intern_code_extent(&mut self,
             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 @@ fn visit_local(&mut self, l: &'tcx Local) {
     }
 }
 
-pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<RegionMaps<'tcx>> {
-    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<RegionMaps<'tcx>>
 {
-    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
     };
 }
index 5ac79a8e72a50e09ee62041ef98a8e129bf9485f..4f7cb2b12a7caa505060bb9a1882114391155cc3 100644 (file)
@@ -17,6 +17,7 @@
 
 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, &region_maps, &free_regions);
         let predicates = match infcx.fully_resolve(&predicates) {
             Ok(predicates) => predicates,
             Err(fixup_err) => {
index 3c6f833c4ef45f78cf38b40a985d6d49acb0e4a2..73b76736b2470f6b4af9ad43914e7f47e3f3e168 100644 (file)
@@ -21,7 +21,7 @@
 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::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 @@ pub fn node_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
         self.intern_code_extent(CodeExtentData::Misc(n))
     }
 
-    // TODO this is revealing side-effects of query, bad
-    pub fn opt_destruction_extent(self, n: ast::NodeId) -> Option<CodeExtent<'gcx>> {
-        let s = CodeExtentData::DestructionScope(n);
-        self.code_extent_interner.borrow().get(&s).cloned()
-    }
-
     // Returns the code extent for an item - the destruction scope.
     pub fn item_extent(self, n: ast::NodeId) -> CodeExtent<'gcx> {
         self.intern_code_extent(CodeExtentData::DestructionScope(n))
@@ -712,10 +705,6 @@ fn is_global(self) -> bool {
         local as usize == global as usize
     }
 
-    pub fn region_maps(self) -> Rc<RegionMaps<'tcx>> {
-        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
index 4a780b9178ecc0a718f77a93362c5a772abcd478..b8edfbf60f245a8caa6f0b7fca81eb2ccf3f5043 100644 (file)
@@ -292,12 +292,6 @@ fn describe(_: TyCtxt, _: DefId) -> String {
     }
 }
 
-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 @@ fn default() -> Self {
 
     [] reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
 
-    [] region_resolve_crate: region_resolve_crate_dep_node(CrateNum) -> Rc<RegionMaps<'tcx>>,
+    /// Per-function `RegionMaps`. The `DefId` should be the owner-def-id for the fn body;
+    /// in the case of closures or "inline" expressions, this will be redirected to the enclosing
+    /// fn item.
+    [] region_maps: RegionMaps(DefId) -> Rc<RegionMaps<'tcx>>,
 
     [] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
 
@@ -601,10 +598,6 @@ fn reachability_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::Reachability
 }
 
-fn region_resolve_crate_dep_node(_: CrateNum) -> DepNode<DefId> {
-    DepNode::RegionResolveCrate
-}
-
 fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
index e6a8459e001791a6fae28cfc8eca48f5bbc6cf73..07aa627e59674aaf7ee596dcee087eb15a35ac86 100644 (file)
@@ -2526,7 +2526,7 @@ pub fn construct_parameter_environment(self,
         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> {
index 96753d63af2031f3f2736a5b51172e84f907a675..6e43943bc1747059c7ffcfbd1c969b5f01586f03 100644 (file)
@@ -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 @@ pub fn each_in_scope_loan<F>(&self, scope: region::CodeExtent<'tcx>, mut op: F)
         //! 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 @@ pub fn report_error_if_loans_conflict(&self,
                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) &&
index 9f8ffd86f5414cc7b0c7aedda517ff121a7e1e9b..12854d3c9792251d54f4a3ff040c2a64c827285b 100644 (file)
@@ -116,7 +116,7 @@ fn scope(&self, cmt: &mc::cmt<'tcx>) -> ty::Region<'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(..)) => {
index 09ed515939de646eb17ca6c282a025fd59b3b3c5..9a5d1008c408ed885e986f5b36188460182e358c 100644 (file)
@@ -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 @@ pub fn compute_gen_scope(&self,
         //! 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 @@ pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent<'tcx>, lp: &Loan
         //! 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
         }
     }
index 1a7c700e23955e4cc1cf6ed29ab036b93e32fcab..e5e5045bc29f9a228c8db961f8232100f693f8b8 100644 (file)
@@ -34,7 +34,8 @@
 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<RegionMaps<'tcx>>,
+
+    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 @@ pub fn is_subregion_of(&self,
                            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>) {
index 3d7df7f0372131b7532157023edbcdd99ec6f308..3e23086ec7bddc5f03591064f084347fd6df151f 100644 (file)
@@ -523,7 +523,8 @@ fn fixup_fragment_sets(&self, tcx: TyCtxt<'a, 'tcx, '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 @@ fn add_gen_kills(&self, tcx: TyCtxt<'a, 'tcx, '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 @@ fn add_gen_kills(&self, tcx: TyCtxt<'a, 'tcx, '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 @@ fn kill_moves(&self,
 
 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 @@ pub fn new(move_data: MoveData<'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);
 
index 5a2fc9adc2f0250821c21b6cf29054c17d1972bf..106b5a26d9564243c40e4d799d24178a53ff0e36 100644 (file)
@@ -14,6 +14,7 @@
 
 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 @@ fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
                 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);
     });
 }
 
index bb3bda6827798b37cc37e79ee5f68fa57f7e9a86..aa33d4b55399818240221378260859c068dfdc1f 100644 (file)
@@ -924,10 +924,6 @@ macro_rules! try_with_f {
              "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)
         });
index 38f9854857115191dbf4b66630653960f7441c79..1036b96d7f5270d21081af5e690f61e0c2b58c2d 100644 (file)
@@ -155,7 +155,8 @@ fn test_env<F>(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, &region_map, &free_regions);
             assert_eq!(tcx.sess.err_count(), expected_err_count);
         });
     });
index 7c12c9ef5fadd103fec1f1734fe1a93538d8ebb9..2505e2f8211b0c612a77a3664616aa4472e42a75 100644 (file)
@@ -202,7 +202,7 @@ pub fn storage_live_binding(&mut self, block: BasicBlock, var: NodeId, span: Spa
     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);
     }
 
index 6c01e4315f3e9a5eda20c9830cc5cd24f0679527..b8f1b754b48e82c51377f89c093dc29f092ed4d7 100644 (file)
@@ -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);
index 15c2df55cf3c8e745a8c7d428ed0e87aafa2aa93..2ec4a8a07df71640d0538d5effdd867a66bb2e92 100644 (file)
@@ -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,
index e37df8822c89253f3873423260f0b5a60be0cb2a..6a1817aba09835348459479f38e11b15ff15fc44 100644 (file)
@@ -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 @@ fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
         };
 
         // 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,
index e73eaafc4b9fe4d3c6e3d6de15c8da6d8b35e5c5..3e9bcb3e18627939b3652bc62e493c8442c40a7f 100644 (file)
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::blocks::FnLikeNode;
+use rustc::middle::region::RegionMaps;
 use rustc::infer::InferCtxt;
 use rustc::ty::subst::Subst;
 use rustc::ty::{self, Ty, TyCtxt};
 use syntax::symbol::{Symbol, InternedString};
 use rustc::hir;
 use rustc_const_math::{ConstInt, ConstUsize};
+use std::rc::Rc;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+    pub region_maps: Rc<RegionMaps<'tcx>>,
     constness: hir::Constness,
 
     /// True if this constant/function needs overflow checks.
@@ -51,7 +54,13 @@ pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, src: MirSource) -> Cx<'a, 'gcx,
             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 @@ pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, src: MirSource) -> Cx<'a, 'gcx,
             .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 }
     }
 }
 
index cb0625ceccfcb836c6552c267d33de86002050ad..cd2d9165c6a53d3ae79af27e5beca0871e1988c6 100644 (file)
@@ -130,7 +130,8 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         };
 
         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 @@ fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         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
         });
 
index 2e84aff49859d0d07c28f6760402d66cd8f9f8fd..80330afaad841b0b1736641b18a3092508650948 100644 (file)
 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};
 ///
 /// - impl_m: type of the method we are checking
 /// - impl_m_span: span to use for reporting errors
-/// - impl_m_body_id: id of the method body
 /// - trait_m: the method in the trait
 /// - impl_trait_ref: the TraitRef corresponding to the trait implementation
 
 pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      impl_m: &ty::AssociatedItem,
                                      impl_m_span: Span,
-                                     impl_m_body_id: ast::NodeId,
                                      trait_m: &ty::AssociatedItem,
                                      impl_trait_ref: ty::TraitRef<'tcx>,
                                      trait_item_span: Option<Span>,
@@ -72,7 +70,6 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     if let Err(ErrorReported) = compare_predicate_entailment(tcx,
                                                              impl_m,
                                                              impl_m_span,
-                                                             impl_m_body_id,
                                                              trait_m,
                                                              impl_trait_ref,
                                                              old_broken_mode) {
@@ -83,21 +80,25 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                           impl_m: &ty::AssociatedItem,
                                           impl_m_span: Span,
-                                          impl_m_body_id: ast::NodeId,
                                           trait_m: &ty::AssociatedItem,
                                           impl_trait_ref: ty::TraitRef<'tcx>,
                                           old_broken_mode: bool)
                                           -> Result<(), ErrorReported> {
     let trait_to_impl_substs = impl_trait_ref.substs;
 
+    // This node-id should be used for the `body_id` field on each
+    // `ObligationCause` (and the `FnCtxt`). This is what
+    // `regionck_item` expects.
+    let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
+
     let cause = ObligationCause {
         span: impl_m_span,
-        body_id: impl_m_body_id,
+        body_id: impl_m_node_id,
         code: ObligationCauseCode::CompareImplMethodObligation {
             item_name: impl_m.name,
             impl_item_def_id: impl_m.def_id,
             trait_item_def_id: trait_m.def_id,
-            lint_id: if !old_broken_mode { Some(impl_m_body_id) } else { None },
+            lint_id: if !old_broken_mode { Some(impl_m_node_id) } else { None },
         },
     };
 
@@ -166,7 +167,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Create a parameter environment that represents the implementation's
     // method.
-    let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
     let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id);
 
     // Create mapping from impl to skolemized.
@@ -217,9 +217,10 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // Construct trait parameter environment and then shift it into the skolemized viewpoint.
     // The key step here is to update the caller_bounds's predicates to be
     // the new hybrid bounds we computed.
-    let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_body_id);
+    let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
     let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.predicates);
     let trait_param_env = traits::normalize_param_env_or_error(tcx,
+                                                               impl_m.def_id,
                                                                trait_param_env,
                                                                normalize_cause.clone());
 
@@ -275,7 +276,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             impl_sig.subst(tcx, impl_to_skol_substs);
         let impl_sig =
             inh.normalize_associated_types_in(impl_m_span,
-                                              impl_m_body_id,
+                                              impl_m_node_id,
                                               &impl_sig);
         let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
         debug!("compare_impl_method: impl_fty={:?}", impl_fty);
@@ -287,7 +288,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             trait_sig.subst(tcx, trait_to_skol_substs);
         let trait_sig =
             inh.normalize_associated_types_in(impl_m_span,
-                                              impl_m_body_id,
+                                              impl_m_node_id,
                                               &trait_sig);
         let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig));
 
@@ -349,13 +350,14 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // region obligations that get overlooked.  The right
             // thing to do is the code below. But we keep this old
             // pass around temporarily.
+            let region_maps = RegionMaps::new();
             let mut free_regions = FreeRegionMap::new();
             free_regions.relate_free_regions_from_predicates(
                 &infcx.parameter_environment.caller_bounds);
-            infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
+            infcx.resolve_regions_and_report_errors(impl_m.def_id, &region_maps, &free_regions);
         } else {
-            let fcx = FnCtxt::new(&inh, impl_m_body_id);
-            fcx.regionck_item(impl_m_body_id, impl_m_span, &[]);
+            let fcx = FnCtxt::new(&inh, impl_m_node_id);
+            fcx.regionck_item(impl_m_node_id, impl_m_span, &[]);
         }
 
         Ok(())
index e4408413ee6c59dd751b2c0f7dcc616a83d3bd83..c20777a403aac7a2b36f97e54b88da7826ede900 100644 (file)
@@ -13,7 +13,7 @@
 use hir::def_id::DefId;
 use middle::free_region::FreeRegionMap;
 use rustc::infer::{self, InferOk};
-use middle::region;
+use rustc::middle::region::{self, RegionMaps};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::traits::{self, ObligationCause, Reveal};
@@ -116,8 +116,9 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
             return Err(ErrorReported);
         }
 
+        let region_maps = RegionMaps::new();
         let free_regions = FreeRegionMap::new();
-        infcx.resolve_regions_and_report_errors(&free_regions, drop_impl_node_id);
+        infcx.resolve_regions_and_report_errors(drop_impl_did, &region_maps, &free_regions);
         Ok(())
     })
 }
@@ -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.
index 729d25aaef541c60b52be3bc32ecd4ea1f87cd0e..7705041fc92d2f527616c3e6a8dddf616b353126 100644 (file)
@@ -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,
index 9a978934dda4220de3fee04b576ffd723ad0b60e..b241f52f62e9b0dd082bd6f20d988927f5933fad 100644 (file)
@@ -87,7 +87,8 @@
 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 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 @@ pub fn regionck_item(&self,
                          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 @@ pub fn regionck_fn(&self,
                        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<RegionMaps<'tcx>>,
+
     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 @@ fn deref(&self) -> &Self::Target {
 }
 
 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 @@ fn relate_free_regions(&mut self,
     }
 
     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 @@ fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
             // 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 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
             // 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 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
         // 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 @@ fn constrain_autoderefs(&mut self,
                            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 @@ fn link_addr_of(&mut self, expr: &hir::Expr,
         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 @@ fn link_local(&self, local: &hir::Local) {
             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 @@ fn link_local(&self, local: &hir::Local) {
     /// 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 @@ fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
     /// 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 @@ fn link_fn_args(&self, body_scope: CodeExtent<'tcx>, args: &[hir::Arg]) {
     /// 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 @@ fn link_autoref(&self,
                     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 @@ fn link_by_ref(&self,
                    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);
index a2c9b7876aafadf43a5e01aae436e1bbda7b222d..227f06436ee1751ef92cfb64f19df261e25f602f 100644 (file)
@@ -164,9 +164,11 @@ fn analyze_closure(&mut self,
         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
                                                   });
index 57193b3584dfa97b80f93be60cbb21ecf5910761..49785d8850f4de72595df5d4eb08904edef7e1d9 100644 (file)
@@ -12,6 +12,7 @@
 //! up data structures required by type-checking/translation.
 
 use rustc::middle::free_region::FreeRegionMap;
+use rustc::middle::region::RegionMaps;
 use rustc::middle::lang_items::UnsizeTraitLangItem;
 
 use rustc::traits::{self, ObligationCause, Reveal};
@@ -342,10 +343,11 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
 
         // Finally, resolve all regions.
+        let region_maps = RegionMaps::new();
         let mut free_regions = FreeRegionMap::new();
         free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment
             .caller_bounds);
-        infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
+        infcx.resolve_regions_and_report_errors(impl_did, &region_maps, &free_regions);
 
         CoerceUnsizedInfo {
             custom_kind: kind
index d1f957bf6b955370b946932f6e8cb8ede36b98d8..a81c0846a279489534080fc789c3cb7ef5509040 100644 (file)
@@ -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.
 //