diff options
| author | Taylor Cramer <cramertaylorj@gmail.com> | 2017-04-10 00:00:08 -0700 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-04-30 17:03:30 -0400 |
| commit | 73cd9bde373cc134aa2ebb6a8064d532621ca0a6 (patch) | |
| tree | c27699bff217136b907b85b1cd76d6eba7089f18 /src/librustc | |
| parent | c7dc39dbf095f04839b57a1e34afc6ab29d905d3 (diff) | |
| download | rust-73cd9bde373cc134aa2ebb6a8064d532621ca0a6.tar.gz rust-73cd9bde373cc134aa2ebb6a8064d532621ca0a6.zip | |
introduce per-fn RegionMaps
Instead of requesting the region maps for the entire crate, request for a given item etc. Several bits of code were modified to take `&RegionMaps` as input (e.g., the `resolve_regions_and_report_errors()` function). I am not totally happy with this setup -- I *think* I'd rather have the region maps be part of typeck tables -- but at least the `RegionMaps` works in a "parallel" way to `FreeRegionMap`, so it's not too bad. Given that I expect a lot of this code to go away with NLL, I didn't want to invest *too* much energy tweaking it.
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/cfg/construct.rs | 6 | ||||
| -rw-r--r-- | src/librustc/dep_graph/dep_node.rs | 4 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 19 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 12 | ||||
| -rw-r--r-- | src/librustc/infer/mod.rs | 14 | ||||
| -rw-r--r-- | src/librustc/infer/region_inference/graphviz.rs | 37 | ||||
| -rw-r--r-- | src/librustc/infer/region_inference/mod.rs | 82 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 9 | ||||
| -rw-r--r-- | src/librustc/middle/free_region.rs | 153 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 19 | ||||
| -rw-r--r-- | src/librustc/middle/region.rs | 80 | ||||
| -rw-r--r-- | src/librustc/traits/mod.rs | 12 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 13 | ||||
| -rw-r--r-- | src/librustc/ty/maps.rs | 15 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 2 |
15 files changed, 287 insertions, 190 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 7b7c204a0ee..a8ad49c6582 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -15,9 +15,11 @@ use syntax::ast; use syntax::ptr::P; use hir::{self, PatKind}; +use hir::def_id::DefId; struct CFGBuilder<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + owner_def_id: DefId, tables: &'a ty::TypeckTables<'tcx>, graph: CFGGraph, fn_exit: CFGIndex, @@ -56,6 +58,7 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut cfg_builder = CFGBuilder { tcx: tcx, + owner_def_id, tables: tables, graph: graph, fn_exit: fn_exit, @@ -585,9 +588,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let mut data = CFGEdgeData { exiting_scopes: vec![] }; let mut scope = self.tcx.node_extent(from_expr.id); let target_scope = self.tcx.node_extent(scope_id); + let region_maps = self.tcx.region_maps(self.owner_def_id); while scope != target_scope { data.exiting_scopes.push(scope.node_id()); - scope = self.tcx.region_maps().encl_scope(scope); + scope = region_maps.encl_scope(scope); } self.graph.add_edge(from_index, to_index, data); } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index d05ede07c3f..63a4e6196a2 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -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 @@ impl<D: Clone + Debug> DepNode<D> { BorrowCheckKrate => Some(BorrowCheckKrate), MirKrate => Some(MirKrate), TypeckBodiesKrate => Some(TypeckBodiesKrate), - RegionResolveCrate => Some(RegionResolveCrate), Coherence => Some(Coherence), Resolve => Some(Resolve), Variance => Some(Variance), @@ -223,6 +222,7 @@ impl<D: Clone + Debug> DepNode<D> { def_ids.map(MirShim) } BorrowCheck(ref d) => op(d).map(BorrowCheck), + RegionMaps(ref d) => op(d).map(RegionMaps), RvalueCheck(ref d) => op(d).map(RvalueCheck), TransCrateItem(ref d) => op(d).map(TransCrateItem), TransInlinedItem(ref d) => op(d).map(TransInlinedItem), diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 2b0d53b2bc3..3e610dd3c0d 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -39,7 +39,7 @@ use syntax::codemap::Spanned; use syntax_pos::Span; use hir::*; use hir::def::Def; -use hir::map::Map; +use hir::map::{self, Map}; use super::itemlikevisit::DeepVisitor; use std::cmp; @@ -140,6 +140,23 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> { /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'v> : Sized { + /// Invokes the suitable visitor method for the given `Node` + /// extracted from the hir map. + fn visit_hir_map_node(&mut self, node: map::Node<'v>) { + match node { + map::NodeItem(a) => self.visit_item(a), + map::NodeForeignItem(a) => self.visit_foreign_item(a), + map::NodeTraitItem(a) => self.visit_trait_item(a), + map::NodeImplItem(a) => self.visit_impl_item(a), + map::NodeExpr(a) => self.visit_expr(a), + map::NodeStmt(a) => self.visit_stmt(a), + map::NodeTy(a) => self.visit_ty(a), + map::NodePat(a) => self.visit_pat(a), + map::NodeBlock(a) => self.visit_block(a), + _ => bug!("Visitor::visit_hir_map_node() not yet impl for node `{:?}`", node) + } + } + /////////////////////////////////////////////////////////////////////////// // Nested items. diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 48b8a819fff..cae5c5011ce 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -572,6 +572,18 @@ impl<'hir> Map<'hir> { } } + /// Check if the node is a non-closure function item + pub fn is_fn(&self, id: NodeId) -> bool { + let entry = if let Some(id) = self.find_entry(id) { id } else { return false }; + + match entry { + EntryItem(_, &Item { node: ItemFn(..), .. }) | + EntryTraitItem(_, &TraitItem { node: TraitItemKind::Method(..), .. }) | + EntryImplItem(_, &ImplItem { node: ImplItemKind::Method(..), .. }) => true, + _ => false, + } + } + /// If there is some error when walking the parents (e.g., a node does not /// have a parent in the map or a node can't be found), then we return the /// last good node id we found. Note that reaching the crate root (id == 0), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index a0451c5fe0b..e91af21c6db 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -20,7 +20,8 @@ pub use self::region_inference::{GenericKind, VerifyBound}; use hir::def_id::DefId; use hir; -use middle::free_region::FreeRegionMap; +use middle::free_region::{FreeRegionMap, RegionRelations}; +use middle::region::RegionMaps; use middle::mem_categorization as mc; use middle::mem_categorization::McResult; use middle::lang_items; @@ -1322,9 +1323,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn resolve_regions_and_report_errors(&self, - free_regions: &FreeRegionMap<'tcx>, - subject_node_id: ast::NodeId) { - let errors = self.region_vars.resolve_regions(free_regions, subject_node_id); + region_context: DefId, + region_map: &RegionMaps<'tcx>, + free_regions: &FreeRegionMap<'tcx>) { + let region_rels = RegionRelations::new(self.tcx, + region_context, + region_map, + free_regions); + let errors = self.region_vars.resolve_regions(®ion_rels); if !self.is_tainted_by_errors() { // As a heuristic, just skip reporting region errors // altogether if other errors have been reported while diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs index 7de81e14d77..c48b8f610a2 100644 --- a/src/librustc/infer/region_inference/graphviz.rs +++ b/src/librustc/infer/region_inference/graphviz.rs @@ -18,7 +18,9 @@ /// For clarity, rename the graphviz crate locally to dot. use graphviz as dot; -use ty::{self, TyCtxt}; +use hir::def_id::DefIndex; +use ty; +use middle::free_region::RegionRelations; use middle::region::CodeExtent; use super::Constraint; use infer::SubregionOrigin; @@ -32,7 +34,6 @@ use std::fs::File; use std::io; use std::io::prelude::*; use std::sync::atomic::{AtomicBool, Ordering}; -use syntax::ast; fn print_help_message() { println!("\ @@ -55,18 +56,18 @@ graphs will be printed. \n\ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>, - subject_node: ast::NodeId) + region_rels: &RegionRelations<'a, 'gcx, 'tcx>) { - let tcx = region_vars.tcx; + let context = region_rels.context; if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph { return; } let requested_node = env::var("RUST_REGION_GRAPH_NODE") - .ok().and_then(|s| s.parse().map(ast::NodeId::new).ok()); + .ok().and_then(|s| s.parse().map(DefIndex::new).ok()); - if requested_node.is_some() && requested_node != Some(subject_node) { + if requested_node.is_some() && requested_node != Some(context.index) { return; } @@ -98,7 +99,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( let mut new_str = String::new(); for c in output_template.chars() { if c == '%' { - new_str.push_str(&subject_node.to_string()); + new_str.push_str(&context.index.as_usize().to_string()); } else { new_str.push(c); } @@ -110,7 +111,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( }; let constraints = &*region_vars.constraints.borrow(); - match dump_region_constraints_to(tcx, constraints, &output_path) { + match dump_region_constraints_to(region_rels, constraints, &output_path) { Ok(()) => {} Err(e) => { let msg = format!("io error dumping region constraints: {}", e); @@ -120,8 +121,8 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( } struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'tcx>, graph_name: String, + region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>, map: &'a FxHashMap<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 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> { add_node(n2); } - tcx.region_maps().each_encl_scope(|sub, sup| { + region_rels.region_maps.each_encl_scope(|sub, sup| { add_node(Node::Region(ty::ReScope(sub))); add_node(Node::Region(ty::ReScope(sup))); }); } ConstraintGraph { - tcx: tcx, + map, + node_ids, + region_rels, graph_name: name, - map: map, - node_ids: node_ids, } } } @@ -245,7 +246,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { fn edges(&self) -> dot::Edges<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 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, '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(); diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index 33754b738a0..fb699bbd2d2 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -22,7 +22,7 @@ use super::unify_key; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING}; use rustc_data_structures::unify::{self, UnificationTable}; -use middle::free_region::FreeRegionMap; +use middle::free_region::RegionRelations; use ty::{self, Ty, TyCtxt}; use ty::{Region, RegionVid}; use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased}; @@ -33,7 +33,6 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::fmt; use std::mem; use std::u32; -use syntax::ast; mod graphviz; @@ -892,18 +891,17 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// constraints, assuming such values can be found; if they cannot, /// errors are reported. pub fn resolve_regions(&self, - free_regions: &FreeRegionMap<'tcx>, - subject_node: ast::NodeId) + region_rels: &RegionRelations<'a, 'gcx, 'tcx>) -> Vec<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 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // at least as big as the block fr.scope_id". So, we can // reasonably compare free regions and scopes: if let Some(fr_scope) = fr.scope { - let r_id = self.tcx.region_maps().nearest_common_ancestor(fr_scope, s_id); + let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id); if r_id == fr_scope { // if the free region's scope `fr.scope_id` is bigger than // the scope region `s_id`, then the LUB is the free @@ -957,12 +955,12 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // The region corresponding to an outer block is a // subtype of the region corresponding to an inner // block. - self.tcx.mk_region(ReScope( - self.tcx.region_maps().nearest_common_ancestor(a_id, b_id))) + let lub = region_rels.region_maps.nearest_common_ancestor(a_id, b_id); + self.tcx.mk_region(ReScope(lub)) } (&ReFree(_), &ReFree(_)) => { - free_regions.lub_free_regions(self.tcx, a, b) + region_rels.lub_free_regions(a, b) } // For these types, we cannot define any additional @@ -996,24 +994,23 @@ type RegionGraph<'tcx> = graph::Graph<(), Constraint<'tcx>>; impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { fn infer_variable_values(&self, - free_regions: &FreeRegionMap<'tcx>, - errors: &mut Vec<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 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { .collect() } - fn dump_constraints(&self, subject: ast::NodeId) { - debug!("----() Start constraint listing (subject={}) ()----", - subject); + fn dump_constraints(&self, free_regions: &RegionRelations<'a, 'gcx, 'tcx>) { + debug!("----() Start constraint listing (context={:?}) ()----", + free_regions.context); for (idx, (constraint, _)) in self.constraints.borrow().iter().enumerate() { debug!("Constraint {} => {:?}", idx, constraint); } @@ -1056,21 +1053,21 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } } - fn expansion(&self, free_regions: &FreeRegionMap<'tcx>, var_values: &mut [VarValue<'tcx>]) { + fn expansion(&self, region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_values: &mut [VarValue<'tcx>]) { self.iterate_until_fixed_point("Expansion", |constraint, origin| { debug!("expansion: constraint={:?} origin={:?}", constraint, origin); match *constraint { ConstrainRegSubVar(a_region, b_vid) => { let b_data = &mut var_values[b_vid.index as usize]; - self.expand_node(free_regions, a_region, b_vid, b_data) + self.expand_node(region_rels, a_region, b_vid, b_data) } ConstrainVarSubVar(a_vid, b_vid) => { match var_values[a_vid.index as usize] { ErrorValue => false, Value(a_region) => { let b_node = &mut var_values[b_vid.index as usize]; - self.expand_node(free_regions, a_region, b_vid, b_node) + self.expand_node(region_rels, a_region, b_vid, b_node) } } } @@ -1085,7 +1082,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn expand_node(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, a_region: Region<'tcx>, b_vid: RegionVid, b_data: &mut VarValue<'tcx>) @@ -1108,7 +1105,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { match *b_data { Value(cur_region) => { - let lub = self.lub_concrete_regions(free_regions, a_region, cur_region); + let lub = self.lub_concrete_regions(region_rels, a_region, cur_region); if lub == cur_region { return false; } @@ -1132,7 +1129,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// cases where the region cannot grow larger than a fixed point) /// and check that they are satisfied. fn collect_errors(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_data: &mut Vec<VarValue<'tcx>>, errors: &mut Vec<RegionResolutionError<'tcx>>) { let constraints = self.constraints.borrow(); @@ -1146,7 +1143,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } ConstrainRegSubReg(sub, sup) => { - if free_regions.is_subregion_of(self.tcx, sub, sup) { + if region_rels.is_subregion_of(sub, sup) { continue; } @@ -1174,7 +1171,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { // Do not report these errors immediately: // instead, set the variable value to error and // collect them later. - if !free_regions.is_subregion_of(self.tcx, a_region, b_region) { + if !region_rels.is_subregion_of(a_region, b_region) { debug!("collect_errors: region error at {:?}: \ cannot verify that {:?}={:?} <= {:?}", origin, @@ -1190,7 +1187,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { for verify in self.verifys.borrow().iter() { debug!("collect_errors: verify={:?}", verify); let sub = normalize(self.tcx, var_data, verify.region); - if verify.bound.is_met(self.tcx, free_regions, var_data, sub) { + if verify.bound.is_met(region_rels, var_data, sub) { continue; } @@ -1209,7 +1206,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { /// Go over the variables that were declared to be error variables /// and create a `RegionResolutionError` for each of them. fn collect_var_errors(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_data: &[VarValue<'tcx>], graph: &RegionGraph<'tcx>, errors: &mut Vec<RegionResolutionError<'tcx>>) { @@ -1258,7 +1255,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { this portion of the code and think hard about it. =) */ let node_vid = RegionVid { index: idx as u32 }; - self.collect_error_for_expanding_node(free_regions, + self.collect_error_for_expanding_node(region_rels, graph, &mut dup_vec, node_vid, @@ -1311,7 +1308,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { } fn collect_error_for_expanding_node(&self, - free_regions: &FreeRegionMap<'tcx>, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, graph: &RegionGraph<'tcx>, dup_vec: &mut [u32], node_idx: RegionVid, @@ -1347,7 +1344,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> { for lower_bound in &lower_bounds { for upper_bound in &upper_bounds { - if !free_regions.is_subregion_of(self.tcx, lower_bound.region, upper_bound.region) { + if !region_rels.is_subregion_of(lower_bound.region, upper_bound.region) { let origin = (*self.var_origins.borrow())[node_idx.index as usize].clone(); debug!("region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \ sup: {:?}", @@ -1591,29 +1588,30 @@ impl<'a, 'gcx, 'tcx> VerifyBound<'tcx> { } } - fn is_met(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - free_regions: &FreeRegionMap<'tcx>, + fn is_met(&self, + region_rels: &RegionRelations<'a, 'gcx, 'tcx>, var_values: &Vec<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)), } } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 9be05313439..a49f3d3b7a7 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -270,19 +270,24 @@ enum PassArgs { impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pub fn new(delegate: &'a mut (Delegate<'tcx>+'a), + context: DefId, infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self { - ExprUseVisitor::with_options(delegate, infcx, mc::MemCategorizationOptions::default()) + ExprUseVisitor::with_options(delegate, + infcx, + context, + mc::MemCategorizationOptions::default()) } pub fn with_options(delegate: &'a mut (Delegate<'tcx>+'a), infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId, options: mc::MemCategorizationOptions) -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::with_options(infcx, options), + mc: mc::MemCategorizationContext::with_options(infcx, context, options), delegate: delegate } } diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 1dc633c6d00..2dc7aac04ae 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -15,10 +15,108 @@ //! `TransitiveRelation` type and use that to decide when one free //! region outlives another and so forth. +use hir::def_id::DefId; +use middle::region::RegionMaps; use ty::{self, Lift, TyCtxt, Region}; use ty::wf::ImpliedBound; use rustc_data_structures::transitive_relation::TransitiveRelation; +/// Combines a `RegionMaps` (which governs relationships between +/// scopes) and a `FreeRegionMap` (which governs relationships between +/// free regions) to yield a complete relation between concrete +/// regions. +/// +/// This stuff is a bit convoluted and should be refactored, but as we +/// move to NLL it'll all go away anyhow. +pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> { + pub tcx: TyCtxt<'a, 'gcx, 'tcx>, + + /// context used to fetch the region maps + pub context: DefId, + + /// region maps for the given context + pub region_maps: &'a RegionMaps<'tcx>, + + /// free-region relationships + pub free_regions: &'a FreeRegionMap<'tcx>, +} + +impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> { + pub fn new( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + context: DefId, + region_maps: &'a RegionMaps<'tcx>, + free_regions: &'a FreeRegionMap<'tcx>, + ) -> Self { + Self { + tcx, + context, + region_maps, + free_regions, + } + } + + /// Determines whether one region is a subregion of another. This is intended to run *after + /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. + pub fn is_subregion_of(&self, + sub_region: ty::Region<'tcx>, + super_region: ty::Region<'tcx>) + -> bool { + let result = sub_region == super_region || { + match (sub_region, super_region) { + (&ty::ReEmpty, _) | + (_, &ty::ReStatic) => + true, + + (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => + self.region_maps.is_subscope_of(sub_scope, super_scope), + + (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { + // 1. It is safe to unwrap `fr.scope` because we + // should only ever wind up comparing against + // `ReScope` in the context of a method or + // body, where `fr.scope` should be `Some`. + self.region_maps.is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || + self.is_static(super_region) + } + + (&ty::ReFree(_), &ty::ReFree(_)) => + self.free_regions.relation.contains(&sub_region, &super_region) || + self.is_static(super_region), + + (&ty::ReStatic, &ty::ReFree(_)) => + self.is_static(super_region), + + _ => + false, + } + }; + debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", + sub_region, super_region, result); + result + } + + /// Determines whether this free-region is required to be 'static + fn is_static(&self, super_region: ty::Region<'tcx>) -> bool { + debug!("is_static(super_region={:?})", super_region); + match *super_region { + ty::ReStatic => true, + ty::ReFree(_) => { + let re_static = self.tcx.mk_region(ty::ReStatic); + self.free_regions.relation.contains(&re_static, &super_region) + } + _ => bug!("only free regions should be given to `is_static`") + } + } + + pub fn lub_free_regions(&self, + r_a: Region<'tcx>, + r_b: Region<'tcx>) + -> Region<'tcx> { + self.free_regions.lub_free_regions(self.tcx, r_a, r_b) + } +} + #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct FreeRegionMap<'tcx> { // Stores the relation `a < b`, where `a` and `b` are regions. @@ -116,61 +214,6 @@ impl<'tcx> FreeRegionMap<'tcx> { debug!("lub_free_regions(r_a={:?}, r_b={:?}) = {:?}", r_a, r_b, result); result } - - /// Determines whether one region is a subregion of another. This is intended to run *after - /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. - pub fn is_subregion_of<'a, 'gcx>(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - sub_region: ty::Region<'tcx>, - super_region: ty::Region<'tcx>) - -> bool { - let result = sub_region == super_region || { - match (sub_region, super_region) { - (&ty::ReEmpty, _) | - (_, &ty::ReStatic) => - true, - - (&ty::ReScope(sub_scope), &ty::ReScope(super_scope)) => - tcx.region_maps().is_subscope_of(sub_scope, super_scope), - - (&ty::ReScope(sub_scope), &ty::ReFree(fr)) => { - // 1. It is safe to unwrap `fr.scope` because we - // should only ever wind up comparing against - // `ReScope` in the context of a method or - // body, where `fr.scope` should be `Some`. - tcx.region_maps().is_subscope_of(sub_scope, fr.scope.unwrap() /*1*/) || - self.is_static(tcx, super_region) - } - - (&ty::ReFree(_), &ty::ReFree(_)) => - self.relation.contains(&sub_region, &super_region) || - self.is_static(tcx, super_region), - - (&ty::ReStatic, &ty::ReFree(_)) => - self.is_static(tcx, super_region), - - _ => - false, - } - }; - debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", - sub_region, super_region, result); - result - } - - /// Determines whether this free-region is required to be 'static - fn is_static<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, super_region: ty::Region<'tcx>) - -> bool { - debug!("is_static(super_region={:?})", super_region); - match *super_region { - ty::ReStatic => true, - ty::ReFree(_) => { - let re_static = tcx.mk_region(ty::ReStatic); - self.relation.contains(&re_static, &super_region) - } - _ => bug!("only free regions should be given to `is_static`") - } - } } impl_stable_hash_for!(struct FreeRegionMap<'tcx> { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 3b1a9552ece..0e2db746e45 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -70,6 +70,7 @@ pub use self::Note::*; use self::Aliasability::*; +use middle::region::RegionMaps; use hir::def_id::DefId; use hir::map as hir_map; use infer::InferCtxt; @@ -286,9 +287,10 @@ impl ast_node for hir::Pat { fn span(&self) -> Span { self.span } } -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct MemCategorizationContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + pub region_maps: Rc<RegionMaps<'tcx>>, options: MemCategorizationOptions, } @@ -402,16 +404,21 @@ impl MutabilityCategory { } impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) + /// Context should be the `DefId` we use to fetch region-maps. + pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId) -> MemCategorizationContext<'a, 'gcx, 'tcx> { - MemCategorizationContext::with_options(infcx, MemCategorizationOptions::default()) + MemCategorizationContext::with_options(infcx, context, MemCategorizationOptions::default()) } pub fn with_options(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + context: DefId, options: MemCategorizationOptions) -> MemCategorizationContext<'a, 'gcx, 'tcx> { + let region_maps = infcx.tcx.region_maps(context); MemCategorizationContext { infcx: infcx, + region_maps: region_maps, options: options, } } @@ -786,7 +793,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { }; match fn_expr.node { - hir::ExprClosure(.., body_id, _) => body_id.node_id, + hir::ExprClosure(.., body_id, _) => body_id, _ => bug!() } }; @@ -796,7 +803,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // The environment of a closure is guaranteed to // outlive any bindings introduced in the body of the // closure itself. - scope: Some(self.tcx().item_extent(fn_body_id)), + scope: Some(self.tcx().item_extent(fn_body_id.node_id)), bound_region: ty::BrEnv })); @@ -845,7 +852,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>) { let (scope, old_scope) = - self.tcx().region_maps().old_and_new_temporary_scope(self.tcx(), id); + self.region_maps.old_and_new_temporary_scope(self.tcx(), id); (self.tcx().mk_region(match scope { Some(scope) => ty::ReScope(scope), None => ty::ReStatic diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 062432e27e5..fb0c3a29def 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -29,8 +29,7 @@ use syntax_pos::Span; use ty::TyCtxt; use ty::maps::Providers; -use hir; -use hir::def_id::{CrateNum, LOCAL_CRATE}; +use hir; use hir::def_id::DefId; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; @@ -226,6 +225,9 @@ pub struct RegionMaps<'tcx> { /// which that variable is declared. var_map: NodeMap<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 @@ impl<'tcx> RegionMaps<'tcx> { } } + 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 @@ impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> { let prev = self.region_maps.scope_map.insert(code_extent, p); assert!(prev.is_none()); } + + // record the destruction scopes for later so we can query them + if let &CodeExtentData::DestructionScope(n) = code_extent { + self.region_maps.destruction_scopes.insert(n, code_extent); + } + code_extent } @@ -1162,47 +1185,44 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { } } -pub fn resolve_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<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 }; } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 5ac79a8e72a..4f7cb2b12a7 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -17,6 +17,7 @@ pub use self::ObligationCauseCode::*; use hir; use hir::def_id::DefId; +use middle::region::RegionMaps; use middle::free_region::FreeRegionMap; use ty::subst::Substs; use ty::{self, Ty, TyCtxt, TypeFoldable, ToPredicate}; @@ -435,9 +436,10 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx // FIXME: this is gonna need to be removed ... /// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - unnormalized_env: ty::ParameterEnvironment<'tcx>, - cause: ObligationCause<'tcx>) - -> ty::ParameterEnvironment<'tcx> + region_context: DefId, + unnormalized_env: ty::ParameterEnvironment<'tcx>, + cause: ObligationCause<'tcx>) + -> ty::ParameterEnvironment<'tcx> { // I'm not wild about reporting errors here; I'd prefer to // have the errors get reported at a defined place (e.g., @@ -455,7 +457,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // can be sure that no errors should occur. let span = cause.span; - let body_id = cause.body_id; debug!("normalize_param_env_or_error(unnormalized_env={:?})", unnormalized_env); @@ -492,8 +493,9 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("normalize_param_env_or_error: normalized predicates={:?}", predicates); + let region_maps = RegionMaps::new(); let free_regions = FreeRegionMap::new(); - infcx.resolve_regions_and_report_errors(&free_regions, body_id); + infcx.resolve_regions_and_report_errors(region_context, ®ion_maps, &free_regions); let predicates = match infcx.fully_resolve(&predicates) { Ok(predicates) => predicates, Err(fixup_err) => { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3c6f833c4ef..73b76736b24 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; use middle::lang_items; -use middle::region::{CodeExtent, CodeExtentData, RegionMaps}; +use middle::region::{CodeExtent, CodeExtentData}; use middle::resolve_lifetime; use middle::stability; use mir::Mir; @@ -52,7 +52,6 @@ use std::mem; use std::ops::Deref; use std::iter; use std::cmp::Ordering; -use std::rc::Rc; use syntax::abi; use syntax::ast::{self, Name, NodeId}; use syntax::attr; @@ -656,12 +655,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.intern_code_extent(CodeExtentData::Misc(n)) } - // TODO this is revealing side-effects of query, bad - pub fn opt_destruction_extent(self, n: ast::NodeId) -> Option<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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { 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 diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 4a780b9178e..b8edfbf60f2 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -292,12 +292,6 @@ impl<'tcx> QueryDescription for queries::def_span<'tcx> { } } -impl<'tcx> QueryDescription for queries::region_resolve_crate<'tcx> { - fn describe(_: TyCtxt, _: CrateNum) -> String { - format!("resolve crate") - } -} - macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -578,7 +572,10 @@ define_maps! { <'tcx> [] reachable_set: reachability_dep_node(CrateNum) -> Rc<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() } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e6a8459e001..07aa627e596 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2526,7 +2526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let body_id = free_id_outlive.map(|f| f.node_id()) .unwrap_or(DUMMY_NODE_ID); let cause = traits::ObligationCause::misc(span, body_id); - traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) + traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) } pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> { |
