Skip to content

Commit 659ce5b

Browse files
committed
Auto merge of #29903 - nikomatsakis:incr-comp-ool-items, r=nrc,mw
This PR moves items into a separate map stored in the krate, rather than storing them inline in the HIR. The HIR visitor is also modified to skip visiting nested items by default. The goal here is to ensure that if you get access to the HIR for one item, you don't automatically get access to a bunch of other items, for better dependency tracking. r? @nrc cc @eddyb
2 parents 28f6b88 + fb28d48 commit 659ce5b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1386
-1264
lines changed

src/librustc/front/map/blocks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc_front::hir::{Block, FnDecl};
2929
use syntax::ast::{Name, NodeId};
3030
use rustc_front::hir as ast;
3131
use syntax::codemap::Span;
32-
use rustc_front::visit::FnKind;
32+
use rustc_front::intravisit::FnKind;
3333

3434
/// An FnLikeNode is a Node that is like a fn, in that it has a decl
3535
/// and a body (as well as a NodeId, a span, etc).

src/librustc/front/map/collector.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::MapEntry::*;
1313

1414
use rustc_front::hir::*;
1515
use rustc_front::util;
16-
use rustc_front::visit::{self, Visitor};
16+
use rustc_front::intravisit::{self, Visitor};
1717
use middle::def_id::{CRATE_DEF_INDEX, DefIndex};
1818
use std::iter::repeat;
1919
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
@@ -22,14 +22,16 @@ use syntax::codemap::Span;
2222
/// A Visitor that walks over an AST and collects Node's into an AST
2323
/// Map.
2424
pub struct NodeCollector<'ast> {
25+
pub krate: &'ast Crate,
2526
pub map: Vec<MapEntry<'ast>>,
2627
pub definitions: Definitions,
2728
pub parent_node: NodeId,
2829
}
2930

3031
impl<'ast> NodeCollector<'ast> {
31-
pub fn root() -> NodeCollector<'ast> {
32+
pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> {
3233
let mut collector = NodeCollector {
34+
krate: krate,
3335
map: vec![],
3436
definitions: Definitions::new(),
3537
parent_node: CRATE_NODE_ID,
@@ -44,13 +46,15 @@ impl<'ast> NodeCollector<'ast> {
4446
collector
4547
}
4648

47-
pub fn extend(parent: &'ast InlinedParent,
49+
pub fn extend(krate: &'ast Crate,
50+
parent: &'ast InlinedParent,
4851
parent_node: NodeId,
4952
parent_def_path: DefPath,
5053
map: Vec<MapEntry<'ast>>,
5154
definitions: Definitions)
5255
-> NodeCollector<'ast> {
5356
let mut collector = NodeCollector {
57+
krate: krate,
5458
map: map,
5559
parent_node: parent_node,
5660
definitions: definitions,
@@ -107,6 +111,13 @@ impl<'ast> NodeCollector<'ast> {
107111
}
108112

109113
impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
114+
/// Because we want to track parent items and so forth, enable
115+
/// deep walking so that we walk nested items in the context of
116+
/// their outer items.
117+
fn visit_nested_item(&mut self, item: ItemId) {
118+
self.visit_item(self.krate.item(item.id))
119+
}
120+
110121
fn visit_item(&mut self, i: &'ast Item) {
111122
// Pick the def data. This need not be unique, but the more
112123
// information we encapsulate into
@@ -173,7 +184,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
173184
}
174185
_ => {}
175186
}
176-
visit::walk_item(self, i);
187+
intravisit::walk_item(self, i);
177188
self.parent_node = parent_node;
178189
}
179190

@@ -184,7 +195,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
184195

185196
let parent_node = self.parent_node;
186197
self.parent_node = foreign_item.id;
187-
visit::walk_foreign_item(self, foreign_item);
198+
intravisit::walk_foreign_item(self, foreign_item);
188199
self.parent_node = parent_node;
189200
}
190201

@@ -195,7 +206,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
195206
DefPathData::TypeParam(ty_param.name));
196207
}
197208

198-
visit::walk_generics(self, generics);
209+
intravisit::walk_generics(self, generics);
199210
}
200211

201212
fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
@@ -217,7 +228,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
217228
_ => { }
218229
}
219230

220-
visit::walk_trait_item(self, ti);
231+
intravisit::walk_trait_item(self, ti);
221232

222233
self.parent_node = parent_node;
223234
}
@@ -240,7 +251,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
240251
_ => { }
241252
}
242253

243-
visit::walk_impl_item(self, ii);
254+
intravisit::walk_impl_item(self, ii);
244255

245256
self.parent_node = parent_node;
246257
}
@@ -259,7 +270,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
259270

260271
let parent_node = self.parent_node;
261272
self.parent_node = pat.id;
262-
visit::walk_pat(self, pat);
273+
intravisit::walk_pat(self, pat);
263274
self.parent_node = parent_node;
264275
}
265276

@@ -273,7 +284,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
273284

274285
let parent_node = self.parent_node;
275286
self.parent_node = expr.id;
276-
visit::walk_expr(self, expr);
287+
intravisit::walk_expr(self, expr);
277288
self.parent_node = parent_node;
278289
}
279290

@@ -282,21 +293,21 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
282293
self.insert(id, NodeStmt(stmt));
283294
let parent_node = self.parent_node;
284295
self.parent_node = id;
285-
visit::walk_stmt(self, stmt);
296+
intravisit::walk_stmt(self, stmt);
286297
self.parent_node = parent_node;
287298
}
288299

289-
fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
300+
fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
290301
b: &'ast Block, s: Span, id: NodeId) {
291302
assert_eq!(self.parent_node, id);
292-
visit::walk_fn(self, fk, fd, b, s);
303+
intravisit::walk_fn(self, fk, fd, b, s);
293304
}
294305

295306
fn visit_block(&mut self, block: &'ast Block) {
296307
self.insert(block.id, NodeBlock(block));
297308
let parent_node = self.parent_node;
298309
self.parent_node = block.id;
299-
visit::walk_block(self, block);
310+
intravisit::walk_block(self, block);
300311
self.parent_node = parent_node;
301312
}
302313

src/librustc/front/map/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax::parse::token;
2525

2626
use rustc_front::hir::*;
2727
use rustc_front::fold::Folder;
28-
use rustc_front::visit;
28+
use rustc_front::intravisit;
2929
use rustc_front::print::pprust;
3030

3131
use arena::TypedArena;
@@ -809,9 +809,11 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
809809
}
810810

811811
pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
812-
let mut collector = NodeCollector::root();
813-
visit::walk_crate(&mut collector, &forest.krate);
814-
let NodeCollector { map, definitions, .. } = collector;
812+
let (map, definitions) = {
813+
let mut collector = NodeCollector::root(&forest.krate);
814+
intravisit::walk_crate(&mut collector, &forest.krate);
815+
(collector.map, collector.definitions)
816+
};
815817

816818
if log_enabled!(::log::DEBUG) {
817819
// This only makes sense for ordered stores; note the
@@ -847,7 +849,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
847849
-> &'ast InlinedItem {
848850
let mut fld = IdAndSpanUpdater { fold_ops: fold_ops };
849851
let ii = match ii {
850-
II::Item(i) => II::Item(fld.fold_item(i)),
852+
II::Item(i) => II::Item(i.map(|i| fld.fold_item(i))),
851853
II::TraitItem(d, ti) => {
852854
II::TraitItem(fld.fold_ops.new_def_id(d),
853855
fld.fold_trait_item(ti))
@@ -867,6 +869,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
867869
let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
868870
let mut collector =
869871
NodeCollector::extend(
872+
map.krate(),
870873
ii_parent,
871874
ii_parent_id,
872875
def_path,

src/librustc/lint/context.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use syntax::parse::token::InternedString;
4444
use syntax::ast;
4545
use rustc_front::hir;
4646
use rustc_front::util;
47-
use rustc_front::visit as hir_visit;
47+
use rustc_front::intravisit as hir_visit;
4848
use syntax::visit as ast_visit;
4949
use syntax::diagnostic;
5050

@@ -555,7 +555,6 @@ impl<'a> EarlyContext<'a> {
555555
{
556556
let mut v = ast_util::IdVisitor {
557557
operation: self,
558-
pass_through_items: false,
559558
visited_outermost: false,
560559
};
561560
f(&mut v);
@@ -583,11 +582,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
583582
fn visit_ids<F>(&mut self, f: F)
584583
where F: FnOnce(&mut util::IdVisitor<LateContext>)
585584
{
586-
let mut v = util::IdVisitor {
587-
operation: self,
588-
pass_through_items: false,
589-
visited_outermost: false,
590-
};
585+
let mut v = util::IdVisitor::new(self);
591586
f(&mut v);
592587
}
593588
}
@@ -611,10 +606,12 @@ impl<'a, 'tcx> LintContext for LateContext<'a, 'tcx> {
611606
}
612607

613608
fn enter_attrs(&mut self, attrs: &[ast::Attribute]) {
609+
debug!("late context: enter_attrs({:?})", attrs);
614610
run_lints!(self, enter_lint_attrs, late_passes, attrs);
615611
}
616612

617613
fn exit_attrs(&mut self, attrs: &[ast::Attribute]) {
614+
debug!("late context: exit_attrs({:?})", attrs);
618615
run_lints!(self, exit_lint_attrs, late_passes, attrs);
619616
}
620617
}
@@ -638,15 +635,24 @@ impl<'a> LintContext for EarlyContext<'a> {
638635
}
639636

640637
fn enter_attrs(&mut self, attrs: &[ast::Attribute]) {
638+
debug!("early context: exit_attrs({:?})", attrs);
641639
run_lints!(self, enter_lint_attrs, early_passes, attrs);
642640
}
643641

644642
fn exit_attrs(&mut self, attrs: &[ast::Attribute]) {
643+
debug!("early context: exit_attrs({:?})", attrs);
645644
run_lints!(self, exit_lint_attrs, early_passes, attrs);
646645
}
647646
}
648647

649648
impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
649+
/// Because lints are scoped lexically, we want to walk nested
650+
/// items in the context of the outer item, so enable
651+
/// deep-walking.
652+
fn visit_nested_item(&mut self, item: hir::ItemId) {
653+
self.visit_item(self.tcx.map.expect_item(item.id))
654+
}
655+
650656
fn visit_item(&mut self, it: &hir::Item) {
651657
self.with_lint_attrs(&it.attrs, |cx| {
652658
run_lints!(cx, check_item, late_passes, it);
@@ -952,6 +958,7 @@ impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> {
952958
match self.sess().lints.borrow_mut().remove(&id) {
953959
None => {}
954960
Some(lints) => {
961+
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
955962
for (lint_id, span, msg) in lints {
956963
self.span_lint(lint_id.lint, span, &msg[..])
957964
}
@@ -1008,16 +1015,14 @@ impl LateLintPass for GatherNodeLevels {
10081015
///
10091016
/// Consumes the `lint_store` field of the `Session`.
10101017
pub fn check_crate(tcx: &ty::ctxt,
1011-
krate: &hir::Crate,
10121018
exported_items: &ExportedItems) {
1013-
1019+
let krate = tcx.map.krate();
10141020
let mut cx = LateContext::new(tcx, krate, exported_items);
10151021

10161022
// Visit the whole crate.
10171023
cx.with_lint_attrs(&krate.attrs, |cx| {
10181024
cx.visit_id(ast::CRATE_NODE_ID);
10191025
cx.visit_ids(|v| {
1020-
v.visited_outermost = true;
10211026
hir_visit::walk_crate(v, krate);
10221027
});
10231028

src/librustc/lint/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub use self::LintSource::*;
3434
use std::hash;
3535
use std::ascii::AsciiExt;
3636
use syntax::codemap::Span;
37-
use rustc_front::visit::FnKind;
37+
use rustc_front::intravisit::FnKind;
3838
use syntax::visit as ast_visit;
3939
use syntax::ast;
4040
use rustc_front::hir;
@@ -218,7 +218,7 @@ pub type EarlyLintPassObject = Box<EarlyLintPass + 'static>;
218218
pub type LateLintPassObject = Box<LateLintPass + 'static>;
219219

220220
/// Identifies a lint known to the compiler.
221-
#[derive(Clone, Copy)]
221+
#[derive(Clone, Copy, Debug)]
222222
pub struct LintId {
223223
// Identity is based on pointer equality of this field.
224224
lint: &'static Lint,

src/librustc/metadata/creader.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use syntax::attr;
3737
use syntax::attr::AttrMetaMethods;
3838
use syntax::parse::token::InternedString;
3939
use syntax::util::small_vector::SmallVector;
40-
use rustc_front::visit;
40+
use rustc_front::intravisit::Visitor;
4141
use rustc_front::hir;
4242
use log;
4343

@@ -53,10 +53,9 @@ pub struct CrateReader<'a> {
5353
foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
5454
}
5555

56-
impl<'a, 'b, 'v> visit::Visitor<'v> for LocalCrateReader<'a, 'b> {
57-
fn visit_item(&mut self, a: &hir::Item) {
56+
impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> {
57+
fn visit_item(&mut self, a: &'hir hir::Item) {
5858
self.process_item(a);
59-
visit::walk_item(self, a);
6059
}
6160
}
6261

@@ -716,7 +715,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
716715
// etc.
717716
pub fn read_crates(&mut self, krate: &hir::Crate) {
718717
self.process_crate(krate);
719-
visit::walk_crate(self, krate);
718+
krate.visit_all_items(self);
720719
self.creader.inject_allocator_crate();
721720

722721
if log_enabled!(log::INFO) {

0 commit comments

Comments
 (0)