Skip to content

Commit 06c63f6

Browse files
committed
Auto merge of #39927 - nikomatsakis:incr-comp-skip-borrowck-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 #38520 as a drive-by fix. r? @eddyb
2 parents c0b7112 + d572aa2 commit 06c63f6

File tree

34 files changed

+266
-401
lines changed

34 files changed

+266
-401
lines changed

src/librustc/cfg/construct.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct LoopScope {
3232
}
3333

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

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

46-
// Find the function this expression is from.
47-
let mut node_id = body.id;
48-
loop {
49-
let node = tcx.hir.get(node_id);
50-
if hir::map::blocks::FnLikeNode::from_node(node).is_some() {
51-
break;
52-
}
53-
let parent = tcx.hir.get_parent_node(node_id);
54-
assert!(node_id != parent);
55-
node_id = parent;
56-
}
46+
// Find the tables for this body.
47+
let owner_def_id = tcx.hir.local_def_id(tcx.hir.body_owner(body.id()));
48+
let tables = tcx.item_tables(owner_def_id);
5749

5850
let mut cfg_builder = CFGBuilder {
5951
tcx: tcx,
60-
tables: tcx.item_tables(tcx.hir.local_def_id(node_id)),
52+
tables: tables,
6153
graph: graph,
6254
fn_exit: fn_exit,
6355
loop_scopes: Vec::new()
6456
};
65-
body_exit = cfg_builder.expr(body, entry);
57+
body_exit = cfg_builder.expr(&body.value, entry);
6658
cfg_builder.add_contained_edge(body_exit, fn_exit);
6759
let CFGBuilder {graph, ..} = cfg_builder;
6860
CFG {graph: graph,

src/librustc/cfg/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub type CFGEdge = graph::Edge<CFGEdgeData>;
5959

6060
impl CFG {
6161
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
62-
body: &hir::Expr) -> CFG {
62+
body: &hir::Body) -> CFG {
6363
construct::construct(tcx, body)
6464
}
6565

src/librustc/dep_graph/dep_node.rs

+6
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,10 @@ pub enum DepNode<D: Clone + Debug> {
8989

9090
// Represents the MIR for a fn; also used as the task node for
9191
// things read/modify that MIR.
92+
MirKrate,
9293
Mir(D),
9394

95+
BorrowCheckKrate,
9496
BorrowCheck(D),
9597
RvalueCheck(D),
9698
Reachability,
@@ -114,6 +116,7 @@ pub enum DepNode<D: Clone + Debug> {
114116
SizedConstraint(D),
115117
AssociatedItemDefIds(D),
116118
InherentImpls(D),
119+
TypeckBodiesKrate,
117120
TypeckTables(D),
118121
UsedTraitImports(D),
119122
MonomorphicConstEval(D),
@@ -209,6 +212,9 @@ impl<D: Clone + Debug> DepNode<D> {
209212

210213
match *self {
211214
Krate => Some(Krate),
215+
BorrowCheckKrate => Some(BorrowCheckKrate),
216+
MirKrate => Some(MirKrate),
217+
TypeckBodiesKrate => Some(TypeckBodiesKrate),
212218
CollectLanguageItems => Some(CollectLanguageItems),
213219
CheckStaticRecursion => Some(CheckStaticRecursion),
214220
ResolveLifetimes => Some(ResolveLifetimes),

src/librustc/dep_graph/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ pub use self::dep_node::WorkProductId;
2525
pub use self::graph::DepGraph;
2626
pub use self::graph::WorkProduct;
2727
pub use self::query::DepGraphQuery;
28+
pub use self::visit::visit_all_bodies_in_krate;
2829
pub use self::visit::visit_all_item_likes_in_krate;
2930
pub use self::raii::DepTask;

src/librustc/dep_graph/visit.rs

+10
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,13 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
7474
};
7575
krate.visit_all_item_likes(&mut tracking_visitor)
7676
}
77+
78+
pub fn visit_all_bodies_in_krate<'a, 'tcx, C>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callback: C)
79+
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
80+
{
81+
let krate = tcx.hir.krate();
82+
for &body_id in &krate.body_ids {
83+
let body_owner_def_id = tcx.hir.body_owner_def_id(body_id);
84+
callback(body_owner_def_id, body_id);
85+
}
86+
}

src/librustc/hir/lowering.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use hir::map::definitions::DefPathData;
4646
use hir::def_id::{DefIndex, DefId};
4747
use hir::def::{Def, PathResolution};
4848
use session::Session;
49-
use util::nodemap::{DefIdMap, NodeMap, FxHashMap};
49+
use util::nodemap::{DefIdMap, NodeMap};
5050

5151
use std::collections::BTreeMap;
5252
use std::iter;
@@ -78,7 +78,7 @@ pub struct LoweringContext<'a> {
7878

7979
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
8080
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
81-
bodies: FxHashMap<hir::BodyId, hir::Body>,
81+
bodies: BTreeMap<hir::BodyId, hir::Body>,
8282

8383
trait_impls: BTreeMap<DefId, Vec<NodeId>>,
8484
trait_default_impl: BTreeMap<DefId, NodeId>,
@@ -118,7 +118,7 @@ pub fn lower_crate(sess: &Session,
118118
items: BTreeMap::new(),
119119
trait_items: BTreeMap::new(),
120120
impl_items: BTreeMap::new(),
121-
bodies: FxHashMap(),
121+
bodies: BTreeMap::new(),
122122
trait_impls: BTreeMap::new(),
123123
trait_default_impl: BTreeMap::new(),
124124
loop_scopes: Vec::new(),
@@ -196,6 +196,7 @@ impl<'a> LoweringContext<'a> {
196196
let module = self.lower_mod(&c.module);
197197
let attrs = self.lower_attrs(&c.attrs);
198198
let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect();
199+
let body_ids = body_ids(&self.bodies);
199200

200201
hir::Crate {
201202
module: module,
@@ -206,6 +207,7 @@ impl<'a> LoweringContext<'a> {
206207
trait_items: self.trait_items,
207208
impl_items: self.impl_items,
208209
bodies: self.bodies,
210+
body_ids: body_ids,
209211
trait_impls: self.trait_impls,
210212
trait_default_impl: self.trait_default_impl,
211213
}
@@ -2524,3 +2526,11 @@ impl<'a> LoweringContext<'a> {
25242526
}
25252527
}
25262528
}
2529+
2530+
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
2531+
// Sorting by span ensures that we get things in order within a
2532+
// file, and also puts the files in a sensible order.
2533+
let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
2534+
body_ids.sort_by_key(|b| bodies[b].value.span);
2535+
body_ids
2536+
}

src/librustc/hir/map/def_collector.rs

+1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
259259
TyKind::ImplTrait(..) => {
260260
self.create_def(ty.id, DefPathData::ImplTrait);
261261
}
262+
TyKind::Typeof(ref expr) => self.visit_ast_const_integer(expr),
262263
_ => {}
263264
}
264265
visit::walk_ty(self, ty);

src/librustc/hir/map/definitions.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ pub enum DefPathData {
260260
/// Pattern binding
261261
Binding(InternedString),
262262
/// An `impl Trait` type node.
263-
ImplTrait
263+
ImplTrait,
264+
/// A `typeof` type node.
265+
Typeof,
264266
}
265267

266268
impl Definitions {
@@ -387,7 +389,8 @@ impl DefPathData {
387389
ClosureExpr |
388390
StructCtor |
389391
Initializer |
390-
ImplTrait => None
392+
ImplTrait |
393+
Typeof => None
391394
}
392395
}
393396

@@ -415,6 +418,7 @@ impl DefPathData {
415418
StructCtor => "{{constructor}}",
416419
Initializer => "{{initializer}}",
417420
ImplTrait => "{{impl-Trait}}",
421+
Typeof => "{{typeof}}",
418422
};
419423

420424
Symbol::intern(s).as_str()

src/librustc/hir/map/mod.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -168,43 +168,48 @@ impl<'hir> MapEntry<'hir> {
168168
})
169169
}
170170

171-
fn is_body_owner(self, node_id: NodeId) -> bool {
171+
fn associated_body(self) -> Option<BodyId> {
172172
match self {
173173
EntryItem(_, item) => {
174174
match item.node {
175175
ItemConst(_, body) |
176176
ItemStatic(.., body) |
177-
ItemFn(_, _, _, _, _, body) => body.node_id == node_id,
178-
_ => false
177+
ItemFn(_, _, _, _, _, body) => Some(body),
178+
_ => None,
179179
}
180180
}
181181

182182
EntryTraitItem(_, item) => {
183183
match item.node {
184184
TraitItemKind::Const(_, Some(body)) |
185-
TraitItemKind::Method(_, TraitMethod::Provided(body)) => {
186-
body.node_id == node_id
187-
}
188-
_ => false
185+
TraitItemKind::Method(_, TraitMethod::Provided(body)) => Some(body),
186+
_ => None
189187
}
190188
}
191189

192190
EntryImplItem(_, item) => {
193191
match item.node {
194192
ImplItemKind::Const(_, body) |
195-
ImplItemKind::Method(_, body) => body.node_id == node_id,
196-
_ => false
193+
ImplItemKind::Method(_, body) => Some(body),
194+
_ => None,
197195
}
198196
}
199197

200198
EntryExpr(_, expr) => {
201199
match expr.node {
202-
ExprClosure(.., body, _) => body.node_id == node_id,
203-
_ => false
200+
ExprClosure(.., body, _) => Some(body),
201+
_ => None,
204202
}
205203
}
206204

207-
_ => false
205+
_ => None
206+
}
207+
}
208+
209+
fn is_body_owner(self, node_id: NodeId) -> bool {
210+
match self.associated_body() {
211+
Some(b) => b.node_id == node_id,
212+
None => false,
208213
}
209214
}
210215
}

src/librustc/hir/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub use self::PathParameters::*;
3131

3232
use hir::def::Def;
3333
use hir::def_id::DefId;
34-
use util::nodemap::{NodeMap, FxHashMap, FxHashSet};
34+
use util::nodemap::{NodeMap, FxHashSet};
3535

3636
use syntax_pos::{Span, ExpnId, DUMMY_SP};
3737
use syntax::codemap::{self, Spanned};
@@ -409,10 +409,15 @@ pub struct Crate {
409409

410410
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
411411
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
412-
pub bodies: FxHashMap<BodyId, Body>,
413-
412+
pub bodies: BTreeMap<BodyId, Body>,
414413
pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
415414
pub trait_default_impl: BTreeMap<DefId, NodeId>,
415+
416+
/// A list of the body ids written out in the order in which they
417+
/// appear in the crate. If you're going to process all the bodies
418+
/// in the crate, you should iterate over this list rather than the keys
419+
/// of bodies.
420+
pub body_ids: Vec<BodyId>,
416421
}
417422

418423
impl Crate {

src/librustc/middle/free_region.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ty::{self, TyCtxt, FreeRegion, Region};
1919
use ty::wf::ImpliedBound;
2020
use rustc_data_structures::transitive_relation::TransitiveRelation;
2121

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

33+
pub fn is_empty(&self) -> bool {
34+
self.relation.is_empty()
35+
}
36+
3337
pub fn relate_free_regions_from_implied_bounds<'tcx>(&mut self,
3438
implied_bounds: &[ImpliedBound<'tcx>])
3539
{

src/librustc/ty/context.rs

+6-18
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ pub struct TypeckTables<'tcx> {
248248
/// If any errors occurred while type-checking this body,
249249
/// this field will be set to `true`.
250250
pub tainted_by_errors: bool,
251+
252+
/// Stores the free-region relationships that were deduced from
253+
/// its where clauses and parameter types. These are then
254+
/// read-again by borrowck.
255+
pub free_region_map: FreeRegionMap,
251256
}
252257

253258
impl<'tcx> TypeckTables<'tcx> {
@@ -267,6 +272,7 @@ impl<'tcx> TypeckTables<'tcx> {
267272
lints: lint::LintTable::new(),
268273
used_trait_imports: DefIdSet(),
269274
tainted_by_errors: false,
275+
free_region_map: FreeRegionMap::new(),
270276
}
271277
}
272278

@@ -414,13 +420,6 @@ pub struct GlobalCtxt<'tcx> {
414420

415421
pub region_maps: RegionMaps,
416422

417-
// For each fn declared in the local crate, type check stores the
418-
// free-region relationships that were deduced from its where
419-
// clauses and parameter types. These are then read-again by
420-
// borrowck. (They are not used during trans, and hence are not
421-
// serialized or needed for cross-crate fns.)
422-
free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
423-
424423
pub hir: hir_map::Map<'tcx>,
425424
pub maps: maps::Maps<'tcx>,
426425

@@ -645,16 +644,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
645644
interned
646645
}
647646

648-
pub fn store_free_region_map(self, id: NodeId, map: FreeRegionMap) {
649-
if self.free_region_maps.borrow_mut().insert(id, map).is_some() {
650-
bug!("Tried to overwrite interned FreeRegionMap for NodeId {:?}", id)
651-
}
652-
}
653-
654-
pub fn free_region_map(self, id: NodeId) -> FreeRegionMap {
655-
self.free_region_maps.borrow()[&id].clone()
656-
}
657-
658647
pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
659648
value.lift_to_tcx(self)
660649
}
@@ -707,7 +696,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
707696
types: common_types,
708697
named_region_map: named_region_map,
709698
region_maps: region_maps,
710-
free_region_maps: RefCell::new(FxHashMap()),
711699
variance_computed: Cell::new(false),
712700
trait_map: resolutions.trait_map,
713701
fulfilled_predicates: RefCell::new(fulfilled_predicates),

src/librustc/ty/item_path.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
180180
data @ DefPathData::MacroDef(..) |
181181
data @ DefPathData::ClosureExpr |
182182
data @ DefPathData::Binding(..) |
183-
data @ DefPathData::ImplTrait => {
183+
data @ DefPathData::ImplTrait |
184+
data @ DefPathData::Typeof => {
184185
let parent_def_id = self.parent_def_id(def_id).unwrap();
185186
self.push_item_path(buffer, parent_def_id);
186187
buffer.push(&data.as_interned_str());

src/librustc/ty/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2602,6 +2602,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26022602
dep_graph::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn, visitor);
26032603
}
26042604

2605+
/// Invokes `callback` for each body in the krate. This will
2606+
/// create a read edge from `DepNode::Krate` to the current task;
2607+
/// it is meant to be run in the context of some global task like
2608+
/// `BorrowckCrate`. The callback would then create a task like
2609+
/// `BorrowckBody(DefId)` to process each individual item.
2610+
pub fn visit_all_bodies_in_krate<C>(self, callback: C)
2611+
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
2612+
{
2613+
dep_graph::visit_all_bodies_in_krate(self.global_tcx(), callback)
2614+
}
2615+
26052616
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
26062617
/// with the name of the crate containing the impl.
26072618
pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {

0 commit comments

Comments
 (0)