Skip to content

Commit

Permalink
introduce per-fn RegionMaps
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cramertj authored and nikomatsakis committed Apr 30, 2017
1 parent c7dc39d commit 73cd9bd
Show file tree
Hide file tree
Showing 36 changed files with 422 additions and 303 deletions.
6 changes: 5 additions & 1 deletion src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand Down
19 changes: 18 additions & 1 deletion src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.

Expand Down
12 changes: 12 additions & 0 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
14 changes: 10 additions & 4 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(&region_rels);
if !self.is_tainted_by_errors() {
// As a heuristic, just skip reporting region errors
// altogether if other errors have been reported while
Expand Down
37 changes: 19 additions & 18 deletions src/librustc/infer/region_inference/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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!("\
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand All @@ -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>,
}
Expand All @@ -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;
Expand All @@ -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,
}
}
}
Expand Down Expand Up @@ -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)
}
Expand All @@ -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();
Expand Down
Loading

0 comments on commit 73cd9bd

Please sign in to comment.