Skip to content

Commit

Permalink
Rollup merge of rust-lang#39927 - nikomatsakis:incr-comp-skip-borrowc…
Browse files Browse the repository at this point in the history
…k-2, r=eddyb

transition borrowck to visit all **bodies** and not item-likes

This is a better structure for incremental compilation and also more compatible with the eventual borrowck mir. It also fixes rust-lang#38520 as a drive-by fix.

r? @eddyb
  • Loading branch information
frewsxcv committed Feb 24, 2017
2 parents 3b379c7 + fed58f3 commit 32cc287
Show file tree
Hide file tree
Showing 28 changed files with 242 additions and 306 deletions.
20 changes: 6 additions & 14 deletions src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct LoopScope {
}

pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
body: &hir::Expr) -> CFG {
body: &hir::Body) -> CFG {
let mut graph = graph::Graph::new();
let entry = graph.add_node(CFGNodeData::Entry);

Expand All @@ -43,26 +43,18 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let fn_exit = graph.add_node(CFGNodeData::Exit);
let body_exit;

// Find the function this expression is from.
let mut node_id = body.id;
loop {
let node = tcx.hir.get(node_id);
if hir::map::blocks::FnLikeNode::from_node(node).is_some() {
break;
}
let parent = tcx.hir.get_parent_node(node_id);
assert!(node_id != parent);
node_id = parent;
}
// Find the tables for this body.
let owner_def_id = tcx.hir.local_def_id(tcx.hir.body_owner(body.id()));
let tables = tcx.item_tables(owner_def_id);

let mut cfg_builder = CFGBuilder {
tcx: tcx,
tables: tcx.item_tables(tcx.hir.local_def_id(node_id)),
tables: tables,
graph: graph,
fn_exit: fn_exit,
loop_scopes: Vec::new()
};
body_exit = cfg_builder.expr(body, entry);
body_exit = cfg_builder.expr(&body.value, entry);
cfg_builder.add_contained_edge(body_exit, fn_exit);
let CFGBuilder {graph, ..} = cfg_builder;
CFG {graph: graph,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/cfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub type CFGEdge = graph::Edge<CFGEdgeData>;

impl CFG {
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
body: &hir::Expr) -> CFG {
body: &hir::Body) -> CFG {
construct::construct(tcx, body)
}

Expand Down
2 changes: 2 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub enum DepNode<D: Clone + Debug> {
// things read/modify that MIR.
Mir(D),

BorrowCheckKrate,
BorrowCheck(D),
RvalueCheck(D),
Reachability,
Expand Down Expand Up @@ -206,6 +207,7 @@ impl<D: Clone + Debug> DepNode<D> {

match *self {
Krate => Some(Krate),
BorrowCheckKrate => Some(BorrowCheckKrate),
CollectLanguageItems => Some(CollectLanguageItems),
CheckStaticRecursion => Some(CheckStaticRecursion),
ResolveLifetimes => Some(ResolveLifetimes),
Expand Down
1 change: 1 addition & 0 deletions src/librustc/dep_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ pub use self::dep_node::WorkProductId;
pub use self::graph::DepGraph;
pub use self::graph::WorkProduct;
pub use self::query::DepGraphQuery;
pub use self::visit::visit_all_bodies_in_krate;
pub use self::visit::visit_all_item_likes_in_krate;
pub use self::raii::DepTask;
10 changes: 10 additions & 0 deletions src/librustc/dep_graph/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,13 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
};
krate.visit_all_item_likes(&mut tracking_visitor)
}

pub fn visit_all_bodies_in_krate<'a, 'tcx, C>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callback: C)
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
{
let krate = tcx.hir.krate();
for &body_id in &krate.body_ids {
let body_owner_def_id = tcx.hir.body_owner_def_id(body_id);
callback(body_owner_def_id, body_id);
}
}
16 changes: 13 additions & 3 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use hir::map::definitions::DefPathData;
use hir::def_id::{DefIndex, DefId};
use hir::def::{Def, PathResolution};
use session::Session;
use util::nodemap::{DefIdMap, NodeMap, FxHashMap};
use util::nodemap::{DefIdMap, NodeMap};

use std::collections::BTreeMap;
use std::iter;
Expand Down Expand Up @@ -77,7 +77,7 @@ pub struct LoweringContext<'a> {

trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
bodies: FxHashMap<hir::BodyId, hir::Body>,
bodies: BTreeMap<hir::BodyId, hir::Body>,

type_def_lifetime_params: DefIdMap<usize>,
}
Expand Down Expand Up @@ -111,7 +111,7 @@ pub fn lower_crate(sess: &Session,
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
bodies: FxHashMap(),
bodies: BTreeMap::new(),
type_def_lifetime_params: DefIdMap(),
}.lower_crate(krate)
}
Expand Down Expand Up @@ -185,6 +185,7 @@ impl<'a> LoweringContext<'a> {
let module = self.lower_mod(&c.module);
let attrs = self.lower_attrs(&c.attrs);
let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect();
let body_ids = body_ids(&self.bodies);

hir::Crate {
module: module,
Expand All @@ -195,6 +196,7 @@ impl<'a> LoweringContext<'a> {
trait_items: self.trait_items,
impl_items: self.impl_items,
bodies: self.bodies,
body_ids: body_ids,
}
}

Expand Down Expand Up @@ -2408,3 +2410,11 @@ impl<'a> LoweringContext<'a> {
}
}
}

fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
// Sorting by span ensures that we get things in order within a
// file, and also puts the files in a sensible order.
let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
body_ids.sort_by_key(|b| bodies[b].value.span);
body_ids
}
29 changes: 17 additions & 12 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,43 +168,48 @@ impl<'hir> MapEntry<'hir> {
})
}

fn is_body_owner(self, node_id: NodeId) -> bool {
fn associated_body(self) -> Option<BodyId> {
match self {
EntryItem(_, item) => {
match item.node {
ItemConst(_, body) |
ItemStatic(.., body) |
ItemFn(_, _, _, _, _, body) => body.node_id == node_id,
_ => false
ItemFn(_, _, _, _, _, body) => Some(body),
_ => None,
}
}

EntryTraitItem(_, item) => {
match item.node {
TraitItemKind::Const(_, Some(body)) |
TraitItemKind::Method(_, TraitMethod::Provided(body)) => {
body.node_id == node_id
}
_ => false
TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
_ => None
}
}

EntryImplItem(_, item) => {
match item.node {
ImplItemKind::Const(_, body) |
ImplItemKind::Method(_, body) => body.node_id == node_id,
_ => false
ImplItemKind::Method(_, body) => Some(body),
_ => None,
}
}

EntryExpr(_, expr) => {
match expr.node {
ExprClosure(.., body, _) => body.node_id == node_id,
_ => false
ExprClosure(.., body, _) => Some(body),
_ => None,
}
}

_ => false
_ => None
}
}

fn is_body_owner(self, node_id: NodeId) -> bool {
match self.associated_body() {
Some(b) => b.node_id == node_id,
None => false,
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub use self::PathParameters::*;

use hir::def::Def;
use hir::def_id::DefId;
use util::nodemap::{NodeMap, FxHashMap, FxHashSet};
use util::nodemap::{NodeMap, FxHashSet};

use syntax_pos::{Span, ExpnId, DUMMY_SP};
use syntax::codemap::{self, Spanned};
Expand Down Expand Up @@ -409,7 +409,13 @@ pub struct Crate {

pub trait_items: BTreeMap<TraitItemId, TraitItem>,
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
pub bodies: FxHashMap<BodyId, Body>,
pub bodies: BTreeMap<BodyId, Body>,

/// A list of the body ids written out in the order in which they
/// appear in the crate. If you're going to process all the bodies
/// in the crate, you should iterate over this list rather than the keys
/// of bodies.
pub body_ids: Vec<BodyId>,
}

impl Crate {
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/middle/free_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use ty::{self, TyCtxt, FreeRegion, Region};
use ty::wf::ImpliedBound;
use rustc_data_structures::transitive_relation::TransitiveRelation;

#[derive(Clone)]
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct FreeRegionMap {
// Stores the relation `a < b`, where `a` and `b` are regions.
relation: TransitiveRelation<Region>
Expand All @@ -30,6 +30,10 @@ impl FreeRegionMap {
FreeRegionMap { relation: TransitiveRelation::new() }
}

pub fn is_empty(&self) -> bool {
self.relation.is_empty()
}

pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
implied_bounds: &[ImpliedBound<'tcx>])
{
Expand Down
25 changes: 6 additions & 19 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ pub struct TypeckTables<'tcx> {

/// Lints for the body of this fn generated by typeck.
pub lints: lint::LintTable,

/// Stores the free-region relationships that were deduced from
/// its where clauses and parameter types. These are then
/// read-again by borrowck.
pub free_region_map: FreeRegionMap,
}

impl<'tcx> TypeckTables<'tcx> {
Expand All @@ -259,6 +264,7 @@ impl<'tcx> TypeckTables<'tcx> {
fru_field_types: NodeMap(),
cast_kinds: NodeMap(),
lints: lint::LintTable::new(),
free_region_map: FreeRegionMap::new(),
}
}

Expand Down Expand Up @@ -406,14 +412,6 @@ pub struct GlobalCtxt<'tcx> {

pub region_maps: RegionMaps,

// For each fn declared in the local crate, type check stores the
// free-region relationships that were deduced from its where
// clauses and parameter types. These are then read-again by
// borrowck. (They are not used during trans, and hence are not
// serialized or needed for cross-crate fns.)
free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
// FIXME: jroesch make this a refcell

pub tables: RefCell<DepTrackingMap<maps::TypeckTables<'tcx>>>,

/// Maps from a trait item to the trait item "descriptor"
Expand Down Expand Up @@ -706,16 +704,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
interned
}

pub fn store_free_region_map(self, id: NodeId, map: FreeRegionMap) {
if self.free_region_maps.borrow_mut().insert(id, map).is_some() {
bug!("Tried to overwrite interned FreeRegionMap for NodeId {:?}", id)
}
}

pub fn free_region_map(self, id: NodeId) -> FreeRegionMap {
self.free_region_maps.borrow()[&id].clone()
}

pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
value.lift_to_tcx(self)
}
Expand Down Expand Up @@ -762,7 +750,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
types: common_types,
named_region_map: named_region_map,
region_maps: region_maps,
free_region_maps: RefCell::new(FxHashMap()),
item_variance_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
variance_computed: Cell::new(false),
sess: s,
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2668,6 +2668,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
dep_graph::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn, visitor);
}

/// Invokes `callback` for each body in the krate. This will
/// create a read edge from `DepNode::Krate` to the current task;
/// it is meant to be run in the context of some global task like
/// `BorrowckCrate`. The callback would then create a task like
/// `BorrowckBody(DefId)` to process each individual item.
pub fn visit_all_bodies_in_krate<C>(self, callback: C)
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
{
dep_graph::visit_all_bodies_in_krate(self.global_tcx(), callback)
}

/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
/// with the name of the crate containing the impl.
pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_borrowck/borrowck/fragments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc::middle::mem_categorization as mc;
use std::mem;
use std::rc::Rc;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
use syntax_pos::DUMMY_SP;

#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum Fragment {
Expand Down Expand Up @@ -200,14 +200,15 @@ impl FragmentSets {

pub fn instrument_move_fragments<'a, 'tcx>(this: &MoveData<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
sp: Span,
id: ast::NodeId) {
let span_err = tcx.hir.attrs(id).iter()
.any(|a| a.check_name("rustc_move_fragments"));
let print = tcx.sess.opts.debugging_opts.print_move_fragments;

if !span_err && !print { return; }

let sp = tcx.hir.span(id);

let instrument_all_paths = |kind, vec_rc: &Vec<MovePathIndex>| {
for (i, mpi) in vec_rc.iter().enumerate() {
let lp = || this.path_loan_path(*mpi);
Expand Down
Loading

0 comments on commit 32cc287

Please sign in to comment.