Skip to content

Commit a059cb2

Browse files
authored
Auto merge of #36601 - jseyfried:build_reduced_graph_in_expansion, r=nrc
Assign def ids and build the module graph during expansion r? @nrc
2 parents 322b553 + dfa69be commit a059cb2

File tree

16 files changed

+321
-281
lines changed

16 files changed

+321
-281
lines changed

src/librustc/hir/map/def_collector.rs

+75-40
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,39 @@ use middle::cstore::InlinedItem;
1818

1919
use syntax::ast::*;
2020
use syntax::visit;
21-
use syntax::parse::token;
21+
use syntax::parse::token::{self, keywords};
2222

2323
/// Creates def ids for nodes in the HIR.
24-
pub struct DefCollector<'ast> {
24+
pub struct DefCollector<'a> {
2525
// If we are walking HIR (c.f., AST), we need to keep a reference to the
2626
// crate.
27-
hir_crate: Option<&'ast hir::Crate>,
28-
definitions: &'ast mut Definitions,
27+
hir_crate: Option<&'a hir::Crate>,
28+
definitions: &'a mut Definitions,
2929
parent_def: Option<DefIndex>,
30+
pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
3031
}
3132

32-
impl<'ast> DefCollector<'ast> {
33-
pub fn new(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
33+
pub struct MacroInvocationData {
34+
pub id: NodeId,
35+
pub def_index: DefIndex,
36+
pub const_integer: bool,
37+
}
38+
39+
impl<'a> DefCollector<'a> {
40+
pub fn new(definitions: &'a mut Definitions) -> Self {
3441
DefCollector {
3542
hir_crate: None,
3643
definitions: definitions,
3744
parent_def: None,
45+
visit_macro_invoc: None,
3846
}
3947
}
4048

4149
pub fn extend(parent_node: NodeId,
4250
parent_def_path: DefPath,
4351
parent_def_id: DefId,
44-
definitions: &'ast mut Definitions)
45-
-> DefCollector<'ast> {
52+
definitions: &'a mut Definitions)
53+
-> Self {
4654
let mut collector = DefCollector::new(definitions);
4755

4856
assert_eq!(parent_def_path.krate, parent_def_id.krate);
@@ -65,7 +73,7 @@ impl<'ast> DefCollector<'ast> {
6573
self.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc);
6674
}
6775

68-
pub fn walk_item(&mut self, ii: &'ast InlinedItem, krate: &'ast hir::Crate) {
76+
pub fn walk_item(&mut self, ii: &'a InlinedItem, krate: &'a hir::Crate) {
6977
self.hir_crate = Some(krate);
7078
ii.visit(self);
7179
}
@@ -84,29 +92,28 @@ impl<'ast> DefCollector<'ast> {
8492
self.definitions.create_def_with_parent(parent, node_id, data)
8593
}
8694

87-
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
95+
pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
8896
let parent = self.parent_def;
8997
self.parent_def = Some(parent_def);
9098
f(self);
9199
self.parent_def = parent;
92100
}
93101

94-
fn visit_ast_const_integer(&mut self, expr: &Expr) {
95-
// Find the node which will be used after lowering.
96-
if let ExprKind::Paren(ref inner) = expr.node {
97-
return self.visit_ast_const_integer(inner);
98-
}
99-
100-
// FIXME(eddyb) Closures should have separate
101-
// function definition IDs and expression IDs.
102-
if let ExprKind::Closure(..) = expr.node {
103-
return;
102+
pub fn visit_ast_const_integer(&mut self, expr: &Expr) {
103+
match expr.node {
104+
// Find the node which will be used after lowering.
105+
ExprKind::Paren(ref inner) => return self.visit_ast_const_integer(inner),
106+
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, true),
107+
// FIXME(eddyb) Closures should have separate
108+
// function definition IDs and expression IDs.
109+
ExprKind::Closure(..) => return,
110+
_ => {}
104111
}
105112

106113
self.create_def(expr.id, DefPathData::Initializer);
107114
}
108115

109-
fn visit_hir_const_integer(&mut self, expr: &'ast hir::Expr) {
116+
fn visit_hir_const_integer(&mut self, expr: &hir::Expr) {
110117
// FIXME(eddyb) Closures should have separate
111118
// function definition IDs and expression IDs.
112119
if let hir::ExprClosure(..) = expr.node {
@@ -115,9 +122,19 @@ impl<'ast> DefCollector<'ast> {
115122

116123
self.create_def(expr.id, DefPathData::Initializer);
117124
}
125+
126+
fn visit_macro_invoc(&mut self, id: NodeId, const_integer: bool) {
127+
if let Some(ref mut visit) = self.visit_macro_invoc {
128+
visit(MacroInvocationData {
129+
id: id,
130+
const_integer: const_integer,
131+
def_index: self.parent_def.unwrap(),
132+
})
133+
}
134+
}
118135
}
119136

120-
impl<'ast> visit::Visitor for DefCollector<'ast> {
137+
impl<'a> visit::Visitor for DefCollector<'a> {
121138
fn visit_item(&mut self, i: &Item) {
122139
debug!("visit_item: {:?}", i);
123140

@@ -129,10 +146,14 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
129146
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
130147
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
131148
DefPathData::TypeNs(i.ident.name.as_str()),
149+
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
150+
return visit::walk_item(self, i);
151+
}
132152
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()),
133153
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
134154
DefPathData::ValueNs(i.ident.name.as_str()),
135-
ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name.as_str()),
155+
ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder
156+
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
136157
ItemKind::Use(..) => DefPathData::Misc,
137158
};
138159
let def = self.create_def(i.id, def_data);
@@ -198,7 +219,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
198219
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
199220
DefPathData::ValueNs(ti.ident.name.as_str()),
200221
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
201-
TraitItemKind::Macro(..) => DefPathData::MacroDef(ti.ident.name.as_str()),
222+
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
202223
};
203224

204225
let def = self.create_def(ti.id, def_data);
@@ -216,7 +237,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
216237
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
217238
DefPathData::ValueNs(ii.ident.name.as_str()),
218239
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
219-
ImplItemKind::Macro(..) => DefPathData::MacroDef(ii.ident.name.as_str()),
240+
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
220241
};
221242

222243
let def = self.create_def(ii.id, def_data);
@@ -232,9 +253,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
232253
fn visit_pat(&mut self, pat: &Pat) {
233254
let parent_def = self.parent_def;
234255

235-
if let PatKind::Ident(_, id, _) = pat.node {
236-
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
237-
self.parent_def = Some(def);
256+
match pat.node {
257+
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
258+
PatKind::Ident(_, id, _) => {
259+
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
260+
self.parent_def = Some(def);
261+
}
262+
_ => {}
238263
}
239264

240265
visit::walk_pat(self, pat);
@@ -244,25 +269,28 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
244269
fn visit_expr(&mut self, expr: &Expr) {
245270
let parent_def = self.parent_def;
246271

247-
if let ExprKind::Repeat(_, ref count) = expr.node {
248-
self.visit_ast_const_integer(count);
249-
}
250-
251-
if let ExprKind::Closure(..) = expr.node {
252-
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
253-
self.parent_def = Some(def);
272+
match expr.node {
273+
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
274+
ExprKind::Repeat(_, ref count) => self.visit_ast_const_integer(count),
275+
ExprKind::Closure(..) => {
276+
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
277+
self.parent_def = Some(def);
278+
}
279+
_ => {}
254280
}
255281

256282
visit::walk_expr(self, expr);
257283
self.parent_def = parent_def;
258284
}
259285

260286
fn visit_ty(&mut self, ty: &Ty) {
261-
if let TyKind::FixedLengthVec(_, ref length) = ty.node {
262-
self.visit_ast_const_integer(length);
263-
}
264-
if let TyKind::ImplTrait(..) = ty.node {
265-
self.create_def(ty.id, DefPathData::ImplTrait);
287+
match ty.node {
288+
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
289+
TyKind::FixedLengthVec(_, ref length) => self.visit_ast_const_integer(length),
290+
TyKind::ImplTrait(..) => {
291+
self.create_def(ty.id, DefPathData::ImplTrait);
292+
}
293+
_ => {}
266294
}
267295
visit::walk_ty(self, ty);
268296
}
@@ -274,6 +302,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
274302
fn visit_macro_def(&mut self, macro_def: &MacroDef) {
275303
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name.as_str()));
276304
}
305+
306+
fn visit_stmt(&mut self, stmt: &Stmt) {
307+
match stmt.node {
308+
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
309+
_ => visit::walk_stmt(self, stmt),
310+
}
311+
}
277312
}
278313

279314
// We walk the HIR rather than the AST when reading items from metadata.

src/librustc/hir/map/definitions.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
// except according to those terms.
1010

1111
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
12-
use hir::map::def_collector::DefCollector;
1312
use rustc_data_structures::fnv::FnvHashMap;
1413
use std::fmt::Write;
1514
use std::hash::{Hash, Hasher, SipHasher};
16-
use syntax::{ast, visit};
15+
use syntax::ast;
1716
use syntax::parse::token::{self, InternedString};
1817
use ty::TyCtxt;
1918
use util::nodemap::NodeMap;
@@ -224,12 +223,6 @@ impl Definitions {
224223
}
225224
}
226225

227-
pub fn collect(&mut self, krate: &ast::Crate) {
228-
let mut def_collector = DefCollector::new(self);
229-
def_collector.collect_root();
230-
visit::walk_crate(&mut def_collector, krate);
231-
}
232-
233226
/// Get the number of definitions.
234227
pub fn len(&self) -> usize {
235228
self.data.len()

src/librustc/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
pub use self::Node::*;
1212
use self::MapEntry::*;
1313
use self::collector::NodeCollector;
14-
use self::def_collector::DefCollector;
14+
pub use self::def_collector::{DefCollector, MacroInvocationData};
1515
pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
1616
DisambiguatedDefPathData, InlinedRootPath};
1717

src/librustc_driver/driver.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,12 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
639639
}
640640
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
641641

642+
// Currently, we ignore the name resolution data structures for the purposes of dependency
643+
// tracking. Instead we will run name resolution and include its output in the hash of each
644+
// item, much like we do for macro expansion. In other words, the hash reflects not just
645+
// its contents but the results of name resolution on those contents. Hopefully we'll push
646+
// this back at some point.
647+
let _ignore = sess.dep_graph.in_ignore();
642648
let mut crate_loader = CrateLoader::new(sess, &cstore, &krate, crate_name);
643649
let resolver_arenas = Resolver::arenas();
644650
let mut resolver =
@@ -733,9 +739,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
733739
})
734740
})?;
735741

736-
// Collect defintions for def ids.
737-
time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
738-
739742
time(sess.time_passes(),
740743
"early lint checks",
741744
|| lint::check_ast_crate(sess, &krate));
@@ -745,13 +748,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
745748
|| ast_validation::check_crate(sess, &krate));
746749

747750
time(sess.time_passes(), "name resolution", || -> CompileResult {
748-
// Currently, we ignore the name resolution data structures for the purposes of dependency
749-
// tracking. Instead we will run name resolution and include its output in the hash of each
750-
// item, much like we do for macro expansion. In other words, the hash reflects not just
751-
// its contents but the results of name resolution on those contents. Hopefully we'll push
752-
// this back at some point.
753-
let _ignore = sess.dep_graph.in_ignore();
754-
resolver.build_reduced_graph(&krate);
755751
resolver.resolve_imports();
756752

757753
// Since import resolution will eventually happen in expansion,

src/librustc_metadata/diagnostics.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ Erroneous code examples:
9898
9999
```compile_fail,E0466
100100
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
101-
extern crate some_crate;
101+
extern crate core as some_crate;
102102
103103
#[macro_use(i_want = "some_macros")] // error: invalid import declaration
104-
extern crate another_crate;
104+
extern crate core as another_crate;
105105
```
106106
107107
This is a syntax error at the level of attribute declarations. The proper
@@ -135,10 +135,10 @@ Erroneous code examples:
135135
136136
```compile_fail,E0467
137137
#[macro_reexport] // error: no macros listed for export
138-
extern crate macros_for_good;
138+
extern crate core as macros_for_good;
139139
140140
#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
141-
extern crate other_macros_for_good;
141+
extern crate core as other_macros_for_good;
142142
```
143143
144144
This is a syntax error at the level of attribute declarations.
@@ -165,8 +165,8 @@ Example of erroneous code:
165165
```compile_fail,E0468
166166
mod foo {
167167
#[macro_use(helpful_macro)] // error: must be at crate root to import
168-
extern crate some_crate; // macros from another crate
169-
helpful_macro!(...)
168+
extern crate core; // macros from another crate
169+
helpful_macro!(...);
170170
}
171171
```
172172

0 commit comments

Comments
 (0)