Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On demandify region mapping #41662

Merged
merged 11 commits into from
May 2, 2017
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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this is_fn_or_method.

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