Skip to content

Commit e272946

Browse files
committed
def_collector: Simplify tracking of macro invocation parents
Avoid the tricky scheme with callbacks and keep the invocation parent data where it logically belongs - in `Definitions`. This also allows to create `InvocationData` entries in resolve when the data is actually ready, and remove cells and "uninitialized" variants from it.
1 parent aff9738 commit e272946

File tree

6 files changed

+55
-87
lines changed

6 files changed

+55
-87
lines changed

src/librustc/hir/map/def_collector.rs

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::hir::map::definitions::*;
2-
use crate::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
3-
use crate::session::CrateDisambiguator;
2+
use crate::hir::def_id::DefIndex;
43

54
use syntax::ast::*;
65
use syntax::ext::hygiene::Mark;
@@ -14,31 +13,12 @@ pub struct DefCollector<'a> {
1413
definitions: &'a mut Definitions,
1514
parent_def: Option<DefIndex>,
1615
expansion: Mark,
17-
pub visit_macro_invoc: Option<&'a mut dyn FnMut(MacroInvocationData)>,
18-
}
19-
20-
pub struct MacroInvocationData {
21-
pub mark: Mark,
22-
pub def_index: DefIndex,
2316
}
2417

2518
impl<'a> DefCollector<'a> {
2619
pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
27-
DefCollector {
28-
definitions,
29-
expansion,
30-
parent_def: None,
31-
visit_macro_invoc: None,
32-
}
33-
}
34-
35-
pub fn collect_root(&mut self,
36-
crate_name: &str,
37-
crate_disambiguator: CrateDisambiguator) {
38-
let root = self.definitions.create_root_def(crate_name,
39-
crate_disambiguator);
40-
assert_eq!(root, CRATE_DEF_INDEX);
41-
self.parent_def = Some(root);
20+
let parent_def = Some(definitions.invocation_parent(expansion));
21+
DefCollector { definitions, parent_def, expansion }
4222
}
4323

4424
fn create_def(&mut self,
@@ -97,12 +77,7 @@ impl<'a> DefCollector<'a> {
9777
}
9878

9979
fn visit_macro_invoc(&mut self, id: NodeId) {
100-
if let Some(ref mut visit) = self.visit_macro_invoc {
101-
visit(MacroInvocationData {
102-
mark: id.placeholder_to_mark(),
103-
def_index: self.parent_def.unwrap(),
104-
})
105-
}
80+
self.definitions.set_invocation_parent(id.placeholder_to_mark(), self.parent_def.unwrap());
10681
}
10782
}
10883

src/librustc/hir/map/definitions.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ pub struct Definitions {
100100
expansions_that_defined: FxHashMap<DefIndex, Mark>,
101101
next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
102102
def_index_to_span: FxHashMap<DefIndex, Span>,
103+
/// When collecting definitions from an AST fragment produced by a macro invocation `Mark`
104+
/// we know what parent node that fragment should be attached to thanks to this table.
105+
invocation_parents: FxHashMap<Mark, DefIndex>,
103106
}
104107

105108
/// A unique identifier that we can use to lookup a definition
@@ -434,6 +437,7 @@ impl Definitions {
434437
assert!(self.def_index_to_node.is_empty());
435438
self.def_index_to_node.push(ast::CRATE_NODE_ID);
436439
self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
440+
self.set_invocation_parent(Mark::root(), root_index);
437441

438442
// Allocate some other DefIndices that always must exist.
439443
GlobalMetaDataKind::allocate_def_indices(self);
@@ -526,6 +530,15 @@ impl Definitions {
526530
pub fn add_parent_module_of_macro_def(&mut self, mark: Mark, module: DefId) {
527531
self.parent_modules_of_macro_defs.insert(mark, module);
528532
}
533+
534+
pub fn invocation_parent(&self, invoc_id: Mark) -> DefIndex {
535+
self.invocation_parents[&invoc_id]
536+
}
537+
538+
pub fn set_invocation_parent(&mut self, invoc_id: Mark, parent: DefIndex) {
539+
let old_parent = self.invocation_parents.insert(invoc_id, parent);
540+
assert!(old_parent.is_none(), "parent def-index is reset for an invocation");
541+
}
529542
}
530543

531544
impl DefPathData {

src/librustc/hir/map/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use self::collector::NodeCollector;
2-
pub use self::def_collector::{DefCollector, MacroInvocationData};
2+
pub use self::def_collector::DefCollector;
33
pub use self::definitions::{
44
Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, DefPathHash
55
};

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -944,12 +944,19 @@ pub struct BuildReducedGraphVisitor<'a, 'b> {
944944

945945
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
946946
fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
947-
let mark = id.placeholder_to_mark();
948-
self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark);
949-
let invocation = self.resolver.invocations[&mark];
950-
invocation.module.set(self.resolver.current_module);
951-
invocation.parent_legacy_scope.set(self.current_legacy_scope);
952-
invocation
947+
let invoc_id = id.placeholder_to_mark();
948+
949+
self.resolver.current_module.unresolved_invocations.borrow_mut().insert(invoc_id);
950+
951+
let invocation_data = self.resolver.arenas.alloc_invocation_data(InvocationData {
952+
module: self.resolver.current_module,
953+
parent_legacy_scope: self.current_legacy_scope,
954+
output_legacy_scope: Cell::new(None),
955+
});
956+
let old_invocation_data = self.resolver.invocations.insert(invoc_id, invocation_data);
957+
assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation");
958+
959+
invocation_data
953960
}
954961
}
955962

src/librustc_resolve/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use GenericParameters::*;
1919
use RibKind::*;
2020
use smallvec::smallvec;
2121

22-
use rustc::hir::map::{Definitions, DefCollector};
22+
use rustc::hir::map::Definitions;
2323
use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str};
2424
use rustc::middle::cstore::CrateStore;
2525
use rustc::session::Session;
@@ -1901,8 +1901,7 @@ impl<'a> Resolver<'a> {
19011901
module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
19021902

19031903
let mut definitions = Definitions::default();
1904-
DefCollector::new(&mut definitions, Mark::root())
1905-
.collect_root(crate_name, session.local_crate_disambiguator());
1904+
definitions.create_root_def(crate_name, session.local_crate_disambiguator());
19061905

19071906
let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> =
19081907
session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))

src/librustc_resolve/macros.rs

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
88
use crate::resolve_imports::ImportResolver;
99
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
1010
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
11-
use rustc::hir::map::{self, DefCollector};
11+
use rustc::hir::map::DefCollector;
1212
use rustc::middle::stability;
1313
use rustc::{ty, lint, span_bug};
1414
use syntax::ast::{self, Ident};
@@ -32,14 +32,14 @@ use rustc_data_structures::sync::Lrc;
3232

3333
type Res = def::Res<ast::NodeId>;
3434

35+
// FIXME: Merge this with `ParentScope`.
3536
#[derive(Clone, Debug)]
3637
pub struct InvocationData<'a> {
37-
def_index: DefIndex,
3838
/// The module in which the macro was invoked.
39-
crate module: Cell<Module<'a>>,
39+
crate module: Module<'a>,
4040
/// The legacy scope in which the macro was invoked.
4141
/// The invocation path is resolved in this scope.
42-
crate parent_legacy_scope: Cell<LegacyScope<'a>>,
42+
crate parent_legacy_scope: LegacyScope<'a>,
4343
/// The legacy scope *produced* by expanding this macro invocation,
4444
/// includes all the macro_rules items, other invocations, etc generated by it.
4545
/// `None` if the macro is not expanded yet.
@@ -49,10 +49,9 @@ pub struct InvocationData<'a> {
4949
impl<'a> InvocationData<'a> {
5050
pub fn root(graph_root: Module<'a>) -> Self {
5151
InvocationData {
52-
module: Cell::new(graph_root),
53-
def_index: CRATE_DEF_INDEX,
54-
parent_legacy_scope: Cell::new(LegacyScope::Empty),
55-
output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
52+
module: graph_root,
53+
parent_legacy_scope: LegacyScope::Empty,
54+
output_legacy_scope: Cell::new(None),
5655
}
5756
}
5857
}
@@ -74,9 +73,6 @@ pub struct LegacyBinding<'a> {
7473
/// can potentially expand into macro definitions.
7574
#[derive(Copy, Clone, Debug)]
7675
pub enum LegacyScope<'a> {
77-
/// Created when invocation data is allocated in the arena;
78-
/// must be replaced with a proper scope later.
79-
Uninitialized,
8076
/// Empty "root" scope at the crate start containing no names.
8177
Empty,
8278
/// The scope introduced by a `macro_rules!` macro definition.
@@ -139,11 +135,11 @@ impl<'a> base::Resolver for Resolver<'a> {
139135
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
140136
let mark = Mark::fresh(Mark::root());
141137
let module = self.module_map[&self.definitions.local_def_id(id)];
138+
self.definitions.set_invocation_parent(mark, module.def_id().unwrap().index);
142139
self.invocations.insert(mark, self.arenas.alloc_invocation_data(InvocationData {
143-
module: Cell::new(module),
144-
def_index: module.def_id().unwrap().index,
145-
parent_legacy_scope: Cell::new(LegacyScope::Empty),
146-
output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
140+
module,
141+
parent_legacy_scope: LegacyScope::Empty,
142+
output_legacy_scope: Cell::new(None),
147143
}));
148144
mark
149145
}
@@ -160,16 +156,20 @@ impl<'a> base::Resolver for Resolver<'a> {
160156

161157
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
162158
derives: &[Mark]) {
163-
let invocation = self.invocations[&mark];
164-
self.collect_def_ids(mark, invocation, fragment);
159+
fragment.visit_with(&mut DefCollector::new(&mut self.definitions, mark));
165160

166-
self.current_module = invocation.module.get();
161+
let invocation = self.invocations[&mark];
162+
self.current_module = invocation.module;
167163
self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
168164
self.current_module.unresolved_invocations.borrow_mut().extend(derives);
165+
let parent_def = self.definitions.invocation_parent(mark);
166+
for &derive_invoc_id in derives {
167+
self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
168+
}
169169
self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
170170
let mut visitor = BuildReducedGraphVisitor {
171171
resolver: self,
172-
current_legacy_scope: invocation.parent_legacy_scope.get(),
172+
current_legacy_scope: invocation.parent_legacy_scope,
173173
expansion: mark,
174174
};
175175
fragment.visit_with(&mut visitor);
@@ -259,9 +259,9 @@ impl<'a> Resolver<'a> {
259259
fn invoc_parent_scope(&self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
260260
let invoc = self.invocations[&invoc_id];
261261
ParentScope {
262-
module: invoc.module.get().nearest_item_scope(),
262+
module: invoc.module.nearest_item_scope(),
263263
expansion: invoc_id.parent(),
264-
legacy: invoc.parent_legacy_scope.get(),
264+
legacy: invoc.parent_legacy_scope,
265265
derives,
266266
}
267267
}
@@ -829,10 +829,9 @@ impl<'a> Resolver<'a> {
829829
binding.parent_legacy_scope
830830
),
831831
LegacyScope::Invocation(invoc) => WhereToResolve::MacroRules(
832-
invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope.get())
832+
invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope)
833833
),
834834
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
835-
LegacyScope::Uninitialized => unreachable!(),
836835
}
837836
WhereToResolve::CrateRoot => match ns {
838837
TypeNS => {
@@ -1084,31 +1083,6 @@ impl<'a> Resolver<'a> {
10841083
}
10851084
}
10861085

1087-
fn collect_def_ids(&mut self,
1088-
mark: Mark,
1089-
invocation: &'a InvocationData<'a>,
1090-
fragment: &AstFragment) {
1091-
let Resolver { ref mut invocations, arenas, graph_root, .. } = *self;
1092-
let InvocationData { def_index, .. } = *invocation;
1093-
1094-
let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
1095-
invocations.entry(invoc.mark).or_insert_with(|| {
1096-
arenas.alloc_invocation_data(InvocationData {
1097-
def_index: invoc.def_index,
1098-
module: Cell::new(graph_root),
1099-
parent_legacy_scope: Cell::new(LegacyScope::Uninitialized),
1100-
output_legacy_scope: Cell::new(None),
1101-
})
1102-
});
1103-
};
1104-
1105-
let mut def_collector = DefCollector::new(&mut self.definitions, mark);
1106-
def_collector.visit_macro_invoc = Some(visit_macro_invoc);
1107-
def_collector.with_parent(def_index, |def_collector| {
1108-
fragment.visit_with(def_collector)
1109-
});
1110-
}
1111-
11121086
crate fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
11131087
// Reserve some names that are not quite covered by the general check
11141088
// performed on `Resolver::builtin_attrs`.

0 commit comments

Comments
 (0)