Skip to content

Commit 66d02fa

Browse files
committed
resolve: Further simplify legacy scopes, add comments
1 parent 0b14414 commit 66d02fa

File tree

2 files changed

+45
-40
lines changed

2 files changed

+45
-40
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> {
944944
let invocation = self.resolver.invocations[&mark];
945945
invocation.module.set(self.resolver.current_module);
946946
invocation.parent_legacy_scope.set(self.current_legacy_scope);
947+
invocation.output_legacy_scope.set(self.current_legacy_scope);
947948
invocation
948949
}
949950
}
@@ -973,7 +974,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> {
973974
return
974975
}
975976
ItemKind::Mac(..) => {
976-
self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
977+
self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(item.id));
977978
return
978979
}
979980
ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs),
@@ -992,7 +993,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> {
992993

993994
fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
994995
if let ast::StmtKind::Mac(..) = stmt.node {
995-
self.current_legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id));
996+
self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(stmt.id));
996997
} else {
997998
visit::walk_stmt(self, stmt);
998999
}

src/librustc_resolve/macros.rs

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,16 @@ crate struct FromPrelude(bool);
5050

5151
#[derive(Clone)]
5252
pub struct InvocationData<'a> {
53-
crate module: Cell<Module<'a>>,
5453
def_index: DefIndex,
55-
// Legacy scope in which the macro was invoked.
56-
// The invocation path is resolved in this scope.
54+
/// Module in which the macro was invoked.
55+
crate module: Cell<Module<'a>>,
56+
/// Legacy scope in which the macro was invoked.
57+
/// The invocation path is resolved in this scope.
5758
crate parent_legacy_scope: Cell<LegacyScope<'a>>,
58-
// Legacy scope *produced* by expanding this macro invocation,
59-
// includes all the macro_rules items, other invocations, etc generated by it.
60-
// `Empty` is used if for invocations that has not been expanded yet.
61-
output_legacy_scope: Cell<LegacyScope<'a>>,
59+
/// Legacy scope *produced* by expanding this macro invocation,
60+
/// includes all the macro_rules items, other invocations, etc generated by it.
61+
/// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing).
62+
crate output_legacy_scope: Cell<LegacyScope<'a>>,
6263
}
6364

6465
impl<'a> InvocationData<'a> {
@@ -72,21 +73,32 @@ impl<'a> InvocationData<'a> {
7273
}
7374
}
7475

75-
// Binding produced by a `macro_rules` item.
76-
// Not modularized, can shadow previous legacy bindings, etc.
76+
/// Binding produced by a `macro_rules` item.
77+
/// Not modularized, can shadow previous legacy bindings, etc.
7778
pub struct LegacyBinding<'a> {
7879
binding: &'a NameBinding<'a>,
79-
// Legacy scope into which the `macro_rules` item was planted.
80-
parent_legacy_scope: Cell<LegacyScope<'a>>,
80+
/// Legacy scope into which the `macro_rules` item was planted.
81+
parent_legacy_scope: LegacyScope<'a>,
8182
ident: Ident,
8283
}
8384

85+
/// Scope introduced by a `macro_rules!` macro.
86+
/// Starts at the macro's definition and ends at the end of the macro's parent module
87+
/// (named or unnamed), or even further if it escapes with `#[macro_use]`.
88+
/// Some macro invocations need to introduce legacy scopes too because they
89+
/// potentially can expand into macro definitions.
8490
#[derive(Copy, Clone)]
8591
pub enum LegacyScope<'a> {
92+
/// Created when invocation data is allocated in the arena,
93+
/// must be replaced with a proper scope later.
94+
Uninitialized,
95+
/// Empty "root" scope at the crate start containing no names.
8696
Empty,
87-
Invocation(&'a InvocationData<'a>), // The scope of the invocation, not including its expansion
88-
Expansion(&'a InvocationData<'a>), // The scope of the invocation, including its expansion
97+
/// Scope introduced by a `macro_rules!` macro definition.
8998
Binding(&'a LegacyBinding<'a>),
99+
/// Scope introduced by a macro invocation that can potentially
100+
/// create a `macro_rules!` macro definition.
101+
Invocation(&'a InvocationData<'a>),
90102
}
91103

92104
pub struct ProcMacError {
@@ -181,7 +193,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
181193
}
182194
let mut visitor = BuildReducedGraphVisitor {
183195
resolver: self,
184-
current_legacy_scope: LegacyScope::Invocation(invocation),
196+
current_legacy_scope: invocation.parent_legacy_scope.get(),
185197
expansion: mark,
186198
};
187199
fragment.visit_with(&mut visitor);
@@ -460,8 +472,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
460472
return def;
461473
}
462474

463-
let legacy_resolution =
464-
self.resolve_legacy_scope(path[0], invoc_id, &invocation.parent_legacy_scope, false);
475+
let legacy_resolution = self.resolve_legacy_scope(
476+
path[0], invoc_id, invocation.parent_legacy_scope.get(), false
477+
);
465478
let result = if let Some(legacy_binding) = legacy_resolution {
466479
Ok(legacy_binding.def())
467480
} else {
@@ -765,7 +778,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
765778
fn resolve_legacy_scope(&mut self,
766779
ident: Ident,
767780
invoc_id: Mark,
768-
invoc_parent_legacy_scope: &'a Cell<LegacyScope<'a>>,
781+
invoc_parent_legacy_scope: LegacyScope<'a>,
769782
record_used: bool)
770783
-> Option<&'a NameBinding<'a>> {
771784
let ident = ident.modern();
@@ -786,28 +799,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
786799
// Go through all the scopes and try to resolve the name.
787800
let mut where_to_resolve = invoc_parent_legacy_scope;
788801
loop {
789-
let result = match where_to_resolve.get() {
802+
let result = match where_to_resolve {
790803
LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
791804
Some(legacy_binding.binding),
792805
_ => None,
793806
};
794807

795808
macro_rules! continue_search { () => {
796-
where_to_resolve = match where_to_resolve.get() {
809+
where_to_resolve = match where_to_resolve {
797810
LegacyScope::Empty => break, // nowhere else to search
798-
LegacyScope::Binding(binding) => &binding.parent_legacy_scope,
799-
LegacyScope::Invocation(invocation) => &invocation.parent_legacy_scope,
800-
LegacyScope::Expansion(invocation) => {
801-
match invocation.output_legacy_scope.get() {
802-
LegacyScope::Empty => &invocation.parent_legacy_scope,
803-
LegacyScope::Binding(..) |
804-
LegacyScope::Expansion(..) => &invocation.output_legacy_scope,
805-
LegacyScope::Invocation(..) => {
806-
where_to_resolve.set(invocation.parent_legacy_scope.get());
807-
where_to_resolve
808-
}
809-
}
810-
}
811+
LegacyScope::Binding(binding) => binding.parent_legacy_scope,
812+
LegacyScope::Invocation(invocation) => invocation.output_legacy_scope.get(),
813+
LegacyScope::Uninitialized => unreachable!(),
811814
};
812815

813816
continue;
@@ -862,9 +865,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
862865

863866
for &(invoc_id, ident, kind, def) in module.legacy_macro_resolutions.borrow().iter() {
864867
let span = ident.span;
865-
let invoc_parent_legacy_scope = &self.invocations[&invoc_id].parent_legacy_scope;
866-
let legacy_resolution =
867-
self.resolve_legacy_scope(ident, invoc_id, invoc_parent_legacy_scope, true);
868+
let invocation = self.invocations[&invoc_id];
869+
let legacy_resolution = self.resolve_legacy_scope(
870+
ident, invoc_id, invocation.parent_legacy_scope.get(), true
871+
);
868872
let resolution = self.resolve_lexical_macro_path_segment(
869873
ident, MacroNS, invoc_id, true, true, kind == MacroKind::Attr, span
870874
);
@@ -990,8 +994,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
990994
arenas.alloc_invocation_data(InvocationData {
991995
def_index: invoc.def_index,
992996
module: Cell::new(graph_root),
993-
parent_legacy_scope: Cell::new(LegacyScope::Empty),
994-
output_legacy_scope: Cell::new(LegacyScope::Empty),
997+
parent_legacy_scope: Cell::new(LegacyScope::Uninitialized),
998+
output_legacy_scope: Cell::new(LegacyScope::Uninitialized),
995999
})
9961000
});
9971001
};
@@ -1027,7 +1031,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10271031
let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings
10281032
let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas);
10291033
let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding {
1030-
parent_legacy_scope: Cell::new(*current_legacy_scope), binding, ident
1034+
parent_legacy_scope: *current_legacy_scope, binding, ident
10311035
});
10321036
*current_legacy_scope = LegacyScope::Binding(legacy_binding);
10331037
self.all_macros.insert(ident.name, def);

0 commit comments

Comments
 (0)