Skip to content

Commit 59dd07a

Browse files
committed
resolve: Eliminate InvocationData
It was very similar to `ParentScope` and mostly could be replaced by it.
1 parent 1a1557c commit 59dd07a

File tree

3 files changed

+53
-91
lines changed

3 files changed

+53
-91
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Here we build the "reduced graph": the graph of the module tree without
44
//! any imports resolved.
55
6-
use crate::macros::{InvocationData, LegacyBinding, LegacyScope};
6+
use crate::macros::{LegacyBinding, LegacyScope};
77
use crate::resolve_imports::ImportDirective;
88
use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
99
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
@@ -1063,20 +1063,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
10631063
false
10641064
}
10651065

1066-
fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> {
1066+
fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> {
10671067
let invoc_id = id.placeholder_to_expn_id();
10681068

1069-
self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
1069+
let parent_scope = self.parent_scope.clone();
1070+
parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
10701071

1071-
let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData {
1072-
module: self.parent_scope.module,
1073-
parent_legacy_scope: self.parent_scope.legacy,
1074-
output_legacy_scope: Cell::new(None),
1075-
});
1076-
let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data);
1077-
assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation");
1072+
let old_parent_scope =
1073+
self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone());
1074+
assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
10781075

1079-
invocation_data
1076+
LegacyScope::Invocation(invoc_id)
10801077
}
10811078

10821079
fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
@@ -1177,7 +1174,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
11771174
return
11781175
}
11791176
ItemKind::Mac(..) => {
1180-
self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id));
1177+
self.parent_scope.legacy = self.visit_invoc(item.id);
11811178
return
11821179
}
11831180
ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
@@ -1196,7 +1193,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
11961193

11971194
fn visit_stmt(&mut self, stmt: &'b ast::Stmt) {
11981195
if let ast::StmtKind::Mac(..) = stmt.node {
1199-
self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id));
1196+
self.parent_scope.legacy = self.visit_invoc(stmt.id);
12001197
} else {
12011198
visit::walk_stmt(self, stmt);
12021199
}

src/librustc_resolve/lib.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use diagnostics::{Suggestion, ImportSuggestion};
5454
use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
5555
use late::{PathSource, Rib, RibKind::*};
5656
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
57-
use macros::{InvocationData, LegacyBinding, LegacyScope};
57+
use macros::{LegacyBinding, LegacyScope};
5858

5959
type Res = def::Res<NodeId>;
6060

@@ -911,9 +911,12 @@ pub struct Resolver<'a> {
911911
/// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]`
912912
/// by marking the produced impls rather than the original items.
913913
special_derives: FxHashMap<ExpnId, SpecialDerives>,
914-
915-
/// Maps the `ExpnId` of an expansion to its containing module or block.
916-
invocations: FxHashMap<ExpnId, &'a InvocationData<'a>>,
914+
/// Parent scopes in which the macros were invoked.
915+
/// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
916+
invocation_parent_scopes: FxHashMap<ExpnId, ParentScope<'a>>,
917+
/// Legacy scopes *produced* by expanding the macro invocations,
918+
/// include all the `macro_rules` items and other invocations generated by them.
919+
output_legacy_scopes: FxHashMap<ExpnId, LegacyScope<'a>>,
917920

918921
/// Avoid duplicated errors for "name already defined".
919922
name_already_seen: FxHashMap<Name, Span>,
@@ -936,7 +939,6 @@ pub struct ResolverArenas<'a> {
936939
name_bindings: arena::TypedArena<NameBinding<'a>>,
937940
import_directives: arena::TypedArena<ImportDirective<'a>>,
938941
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
939-
invocation_data: arena::TypedArena<InvocationData<'a>>,
940942
legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
941943
}
942944

@@ -961,10 +963,6 @@ impl<'a> ResolverArenas<'a> {
961963
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
962964
self.name_resolutions.alloc(Default::default())
963965
}
964-
fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
965-
-> &'a InvocationData<'a> {
966-
self.invocation_data.alloc(expansion_data)
967-
}
968966
fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
969967
self.legacy_bindings.alloc(binding)
970968
}
@@ -1078,9 +1076,8 @@ impl<'a> Resolver<'a> {
10781076
}
10791077
}
10801078

1081-
let mut invocations = FxHashMap::default();
1082-
invocations.insert(ExpnId::root(),
1083-
arenas.alloc_invocation_data(InvocationData::default(graph_root)));
1079+
let mut invocation_parent_scopes = FxHashMap::default();
1080+
invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root));
10841081

10851082
let mut macro_defs = FxHashMap::default();
10861083
macro_defs.insert(ExpnId::root(), root_def_id);
@@ -1152,7 +1149,8 @@ impl<'a> Resolver<'a> {
11521149
dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())),
11531150
dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())),
11541151
non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)],
1155-
invocations,
1152+
invocation_parent_scopes,
1153+
output_legacy_scopes: Default::default(),
11561154
macro_defs,
11571155
local_macro_def_scopes: FxHashMap::default(),
11581156
name_already_seen: FxHashMap::default(),
@@ -1370,8 +1368,9 @@ impl<'a> Resolver<'a> {
13701368
LegacyScope::Binding(binding) => Scope::MacroRules(
13711369
binding.parent_legacy_scope
13721370
),
1373-
LegacyScope::Invocation(invoc) => Scope::MacroRules(
1374-
invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope)
1371+
LegacyScope::Invocation(invoc_id) => Scope::MacroRules(
1372+
self.output_legacy_scopes.get(&invoc_id).cloned()
1373+
.unwrap_or(self.invocation_parent_scopes[&invoc_id].legacy)
13751374
),
13761375
LegacyScope::Empty => Scope::Module(module),
13771376
}

src/librustc_resolve/macros.rs

Lines changed: 29 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
22
use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
3-
use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
3+
use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
44
use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
55
use crate::Namespace::*;
66
use crate::build_reduced_graph::BuildReducedGraphVisitor;
@@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue;
2222
use syntax::symbol::{Symbol, kw, sym};
2323
use syntax_pos::{Span, DUMMY_SP};
2424

25-
use std::cell::Cell;
2625
use std::{mem, ptr};
2726
use rustc_data_structures::sync::Lrc;
2827

2928
type Res = def::Res<ast::NodeId>;
3029

31-
// FIXME: Merge this with `ParentScope`.
32-
#[derive(Clone, Debug)]
33-
pub struct InvocationData<'a> {
34-
/// The module in which the macro was invoked.
35-
crate module: Module<'a>,
36-
/// The legacy scope in which the macro was invoked.
37-
/// The invocation path is resolved in this scope.
38-
crate parent_legacy_scope: LegacyScope<'a>,
39-
/// The legacy scope *produced* by expanding this macro invocation,
40-
/// includes all the macro_rules items, other invocations, etc generated by it.
41-
/// `None` if the macro is not expanded yet.
42-
crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>,
43-
}
44-
45-
impl<'a> InvocationData<'a> {
46-
pub fn default(module: Module<'a>) -> Self {
47-
InvocationData {
48-
module,
49-
parent_legacy_scope: LegacyScope::Empty,
50-
output_legacy_scope: Cell::new(None),
51-
}
52-
}
53-
}
54-
5530
/// Binding produced by a `macro_rules` item.
5631
/// Not modularized, can shadow previous legacy bindings, etc.
5732
#[derive(Debug)]
@@ -75,7 +50,7 @@ pub enum LegacyScope<'a> {
7550
Binding(&'a LegacyBinding<'a>),
7651
/// The scope introduced by a macro invocation that can potentially
7752
/// create a `macro_rules!` macro definition.
78-
Invocation(&'a InvocationData<'a>),
53+
Invocation(ExpnId),
7954
}
8055

8156
// Macro namespace is separated into two sub-namespaces, one for bang macros and
@@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> {
12499
ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
125100
)));
126101
let module = self.module_map[&self.definitions.local_def_id(id)];
127-
let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module));
102+
self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module));
128103
self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
129-
self.invocations.insert(expn_id, invocation_data);
130104
expn_id
131105
}
132106

@@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> {
140114
});
141115
}
142116

143-
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
144-
derives: &[ExpnId]) {
145-
fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id));
146-
147-
let invocation = self.invocations[&expn_id];
148-
invocation.module.unresolved_invocations.borrow_mut().remove(&expn_id);
149-
invocation.module.unresolved_invocations.borrow_mut().extend(derives);
150-
let parent_def = self.definitions.invocation_parent(expn_id);
117+
fn visit_ast_fragment_with_placeholders(
118+
&mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
119+
) {
120+
// Fill in some data for derives if the fragment is from a derive container.
121+
let parent_scope = self.invocation_parent_scopes[&expansion].clone();
122+
let parent_def = self.definitions.invocation_parent(expansion);
123+
self.invocation_parent_scopes.extend(
124+
derives.iter().map(|&derive| (derive, parent_scope.clone()))
125+
);
151126
for &derive_invoc_id in derives {
152127
self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
153128
}
154-
self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
155-
let mut visitor = BuildReducedGraphVisitor {
156-
r: self,
157-
parent_scope: ParentScope {
158-
module: invocation.module,
159-
expansion: expn_id,
160-
legacy: invocation.parent_legacy_scope,
161-
derives: Vec::new(),
162-
},
163-
};
129+
parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion);
130+
parent_scope.module.unresolved_invocations.borrow_mut().extend(derives);
131+
132+
// Integrate the new AST fragment into all the definition and module structures.
133+
// We are inside the `expansion` new, but other parent scope components are still the same.
134+
fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion));
135+
let parent_scope = ParentScope { expansion, ..parent_scope };
136+
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
164137
fragment.visit_with(&mut visitor);
165-
invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy));
138+
let output_legacy_scope = visitor.parent_scope.legacy;
139+
self.output_legacy_scopes.insert(expansion, output_legacy_scope);
166140
}
167141

168142
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
@@ -178,7 +152,8 @@ impl<'a> base::Resolver for Resolver<'a> {
178152

179153
fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
180154
-> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
181-
let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
155+
let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone();
156+
let (path, kind, derives, after_derive) = match invoc.kind {
182157
InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
183158
(&attr.path, MacroKind::Attr, derives.clone(), after_derive),
184159
InvocationKind::Bang { ref mac, .. } =>
@@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> {
192167
// will automatically knows about itself.
193168
let mut result = Ok(None);
194169
if derives.len() > 1 {
195-
let parent_scope = &self.invoc_parent_scope(invoc_id, Vec::new());
196170
for path in derives {
197171
match self.resolve_macro_path(path, Some(MacroKind::Derive),
198172
parent_scope, true, force) {
@@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> {
209183
}
210184
};
211185

212-
let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope);
186+
// Derives are not included when `invocations` are collected, so we have to add them here.
187+
let parent_scope = &ParentScope { derives, ..parent_scope.clone() };
213188
let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
214189

215190
let span = invoc.span();
@@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> {
247222
}
248223

249224
impl<'a> Resolver<'a> {
250-
fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> {
251-
let invoc = self.invocations[&invoc_id];
252-
ParentScope {
253-
module: invoc.module,
254-
expansion: invoc_id.parent(),
255-
legacy: invoc.parent_legacy_scope,
256-
derives,
257-
}
258-
}
259-
260225
/// Resolve macro path with error reporting and recovery.
261226
fn smart_resolve_macro_path(
262227
&mut self,
@@ -466,8 +431,9 @@ impl<'a> Resolver<'a> {
466431
Scope::MacroRules(legacy_scope) => match legacy_scope {
467432
LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
468433
Ok((legacy_binding.binding, Flags::MACRO_RULES)),
469-
LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() =>
470-
Err(Determinacy::Undetermined),
434+
LegacyScope::Invocation(invoc_id)
435+
if !this.output_legacy_scopes.contains_key(&invoc_id) =>
436+
Err(Determinacy::Undetermined),
471437
_ => Err(Determinacy::Determined),
472438
}
473439
Scope::CrateRoot => {

0 commit comments

Comments
 (0)