Skip to content

Commit 73cd9bd

Browse files
cramertjnikomatsakis
authored andcommitted
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.
1 parent c7dc39d commit 73cd9bd

File tree

36 files changed

+422
-303
lines changed

36 files changed

+422
-303
lines changed

src/librustc/cfg/construct.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ use syntax::ast;
1515
use syntax::ptr::P;
1616

1717
use hir::{self, PatKind};
18+
use hir::def_id::DefId;
1819

1920
struct CFGBuilder<'a, 'tcx: 'a> {
2021
tcx: TyCtxt<'a, 'tcx, 'tcx>,
22+
owner_def_id: DefId,
2123
tables: &'a ty::TypeckTables<'tcx>,
2224
graph: CFGGraph,
2325
fn_exit: CFGIndex,
@@ -56,6 +58,7 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5658

5759
let mut cfg_builder = CFGBuilder {
5860
tcx: tcx,
61+
owner_def_id,
5962
tables: tables,
6063
graph: graph,
6164
fn_exit: fn_exit,
@@ -585,9 +588,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
585588
let mut data = CFGEdgeData { exiting_scopes: vec![] };
586589
let mut scope = self.tcx.node_extent(from_expr.id);
587590
let target_scope = self.tcx.node_extent(scope_id);
591+
let region_maps = self.tcx.region_maps(self.owner_def_id);
588592
while scope != target_scope {
589593
data.exiting_scopes.push(scope.node_id());
590-
scope = self.tcx.region_maps().encl_scope(scope);
594+
scope = region_maps.encl_scope(scope);
591595
}
592596
self.graph.add_edge(from_index, to_index, data);
593597
}

src/librustc/dep_graph/dep_node.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub enum DepNode<D: Clone + Debug> {
5656
WorkProduct(Arc<WorkProductId>),
5757

5858
// Represents different phases in the compiler.
59-
RegionResolveCrate,
59+
RegionMaps(D),
6060
Coherence,
6161
Resolve,
6262
CoherenceCheckTrait(D),
@@ -197,7 +197,6 @@ impl<D: Clone + Debug> DepNode<D> {
197197
BorrowCheckKrate => Some(BorrowCheckKrate),
198198
MirKrate => Some(MirKrate),
199199
TypeckBodiesKrate => Some(TypeckBodiesKrate),
200-
RegionResolveCrate => Some(RegionResolveCrate),
201200
Coherence => Some(Coherence),
202201
Resolve => Some(Resolve),
203202
Variance => Some(Variance),
@@ -223,6 +222,7 @@ impl<D: Clone + Debug> DepNode<D> {
223222
def_ids.map(MirShim)
224223
}
225224
BorrowCheck(ref d) => op(d).map(BorrowCheck),
225+
RegionMaps(ref d) => op(d).map(RegionMaps),
226226
RvalueCheck(ref d) => op(d).map(RvalueCheck),
227227
TransCrateItem(ref d) => op(d).map(TransCrateItem),
228228
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),

src/librustc/hir/intravisit.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use syntax::codemap::Spanned;
3939
use syntax_pos::Span;
4040
use hir::*;
4141
use hir::def::Def;
42-
use hir::map::Map;
42+
use hir::map::{self, Map};
4343
use super::itemlikevisit::DeepVisitor;
4444

4545
use std::cmp;
@@ -140,6 +140,23 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> {
140140
/// to monitor future changes to `Visitor` in case a new method with a
141141
/// new default implementation gets introduced.)
142142
pub trait Visitor<'v> : Sized {
143+
/// Invokes the suitable visitor method for the given `Node`
144+
/// extracted from the hir map.
145+
fn visit_hir_map_node(&mut self, node: map::Node<'v>) {
146+
match node {
147+
map::NodeItem(a) => self.visit_item(a),
148+
map::NodeForeignItem(a) => self.visit_foreign_item(a),
149+
map::NodeTraitItem(a) => self.visit_trait_item(a),
150+
map::NodeImplItem(a) => self.visit_impl_item(a),
151+
map::NodeExpr(a) => self.visit_expr(a),
152+
map::NodeStmt(a) => self.visit_stmt(a),
153+
map::NodeTy(a) => self.visit_ty(a),
154+
map::NodePat(a) => self.visit_pat(a),
155+
map::NodeBlock(a) => self.visit_block(a),
156+
_ => bug!("Visitor::visit_hir_map_node() not yet impl for node `{:?}`", node)
157+
}
158+
}
159+
143160
///////////////////////////////////////////////////////////////////////////
144161
// Nested items.
145162

src/librustc/hir/map/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,18 @@ impl<'hir> Map<'hir> {
572572
}
573573
}
574574

575+
/// Check if the node is a non-closure function item
576+
pub fn is_fn(&self, id: NodeId) -> bool {
577+
let entry = if let Some(id) = self.find_entry(id) { id } else { return false };
578+
579+
match entry {
580+
EntryItem(_, &Item { node: ItemFn(..), .. }) |
581+
EntryTraitItem(_, &TraitItem { node: TraitItemKind::Method(..), .. }) |
582+
EntryImplItem(_, &ImplItem { node: ImplItemKind::Method(..), .. }) => true,
583+
_ => false,
584+
}
585+
}
586+
575587
/// If there is some error when walking the parents (e.g., a node does not
576588
/// have a parent in the map or a node can't be found), then we return the
577589
/// last good node id we found. Note that reaching the crate root (id == 0),

src/librustc/infer/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ pub use self::region_inference::{GenericKind, VerifyBound};
2020

2121
use hir::def_id::DefId;
2222
use hir;
23-
use middle::free_region::FreeRegionMap;
23+
use middle::free_region::{FreeRegionMap, RegionRelations};
24+
use middle::region::RegionMaps;
2425
use middle::mem_categorization as mc;
2526
use middle::mem_categorization::McResult;
2627
use middle::lang_items;
@@ -1322,9 +1323,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13221323
}
13231324

13241325
pub fn resolve_regions_and_report_errors(&self,
1325-
free_regions: &FreeRegionMap<'tcx>,
1326-
subject_node_id: ast::NodeId) {
1327-
let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
1326+
region_context: DefId,
1327+
region_map: &RegionMaps<'tcx>,
1328+
free_regions: &FreeRegionMap<'tcx>) {
1329+
let region_rels = RegionRelations::new(self.tcx,
1330+
region_context,
1331+
region_map,
1332+
free_regions);
1333+
let errors = self.region_vars.resolve_regions(&region_rels);
13281334
if !self.is_tainted_by_errors() {
13291335
// As a heuristic, just skip reporting region errors
13301336
// altogether if other errors have been reported while

src/librustc/infer/region_inference/graphviz.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
/// For clarity, rename the graphviz crate locally to dot.
1919
use graphviz as dot;
2020

21-
use ty::{self, TyCtxt};
21+
use hir::def_id::DefIndex;
22+
use ty;
23+
use middle::free_region::RegionRelations;
2224
use middle::region::CodeExtent;
2325
use super::Constraint;
2426
use infer::SubregionOrigin;
@@ -32,7 +34,6 @@ use std::fs::File;
3234
use std::io;
3335
use std::io::prelude::*;
3436
use std::sync::atomic::{AtomicBool, Ordering};
35-
use syntax::ast;
3637

3738
fn print_help_message() {
3839
println!("\
@@ -55,18 +56,18 @@ graphs will be printed. \n\
5556

5657
pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
5758
region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>,
58-
subject_node: ast::NodeId)
59+
region_rels: &RegionRelations<'a, 'gcx, 'tcx>)
5960
{
60-
let tcx = region_vars.tcx;
61+
let context = region_rels.context;
6162

6263
if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph {
6364
return;
6465
}
6566

6667
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
67-
.ok().and_then(|s| s.parse().map(ast::NodeId::new).ok());
68+
.ok().and_then(|s| s.parse().map(DefIndex::new).ok());
6869

69-
if requested_node.is_some() && requested_node != Some(subject_node) {
70+
if requested_node.is_some() && requested_node != Some(context.index) {
7071
return;
7172
}
7273

@@ -98,7 +99,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
9899
let mut new_str = String::new();
99100
for c in output_template.chars() {
100101
if c == '%' {
101-
new_str.push_str(&subject_node.to_string());
102+
new_str.push_str(&context.index.as_usize().to_string());
102103
} else {
103104
new_str.push(c);
104105
}
@@ -110,7 +111,7 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
110111
};
111112

112113
let constraints = &*region_vars.constraints.borrow();
113-
match dump_region_constraints_to(tcx, constraints, &output_path) {
114+
match dump_region_constraints_to(region_rels, constraints, &output_path) {
114115
Ok(()) => {}
115116
Err(e) => {
116117
let msg = format!("io error dumping region constraints: {}", e);
@@ -120,8 +121,8 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
120121
}
121122

122123
struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
123-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
124124
graph_name: String,
125+
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
125126
map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
126127
node_ids: FxHashMap<Node<'tcx>, usize>,
127128
}
@@ -140,8 +141,8 @@ enum Edge<'tcx> {
140141
}
141142

142143
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
143-
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
144-
name: String,
144+
fn new(name: String,
145+
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
145146
map: &'a ConstraintMap<'tcx>)
146147
-> ConstraintGraph<'a, 'gcx, 'tcx> {
147148
let mut i = 0;
@@ -159,17 +160,17 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
159160
add_node(n2);
160161
}
161162

162-
tcx.region_maps().each_encl_scope(|sub, sup| {
163+
region_rels.region_maps.each_encl_scope(|sub, sup| {
163164
add_node(Node::Region(ty::ReScope(sub)));
164165
add_node(Node::Region(ty::ReScope(sup)));
165166
});
166167
}
167168

168169
ConstraintGraph {
169-
tcx: tcx,
170+
map,
171+
node_ids,
172+
region_rels,
170173
graph_name: name,
171-
map: map,
172-
node_ids: node_ids,
173174
}
174175
}
175176
}
@@ -245,7 +246,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
245246
fn edges(&self) -> dot::Edges<Edge<'tcx>> {
246247
debug!("constraint graph has {} edges", self.map.len());
247248
let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
248-
self.tcx.region_maps().each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
249+
self.region_rels.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup)));
249250
debug!("region graph has {} edges", v.len());
250251
Cow::Owned(v)
251252
}
@@ -263,14 +264,14 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
263264

264265
pub type ConstraintMap<'tcx> = FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
265266

266-
fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
267+
fn dump_region_constraints_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
267268
map: &ConstraintMap<'tcx>,
268269
path: &str)
269270
-> io::Result<()> {
270271
debug!("dump_region_constraints map (len: {}) path: {}",
271272
map.len(),
272273
path);
273-
let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
274+
let g = ConstraintGraph::new(format!("region_constraints"), region_rels, map);
274275
debug!("dump_region_constraints calling render");
275276
let mut v = Vec::new();
276277
dot::render(&g, &mut v).unwrap();

0 commit comments

Comments
 (0)