Skip to content

Commit d479ff2

Browse files
committed
resolve: Properly integrate derives and macro_rules scopes
1 parent d65e272 commit d479ff2

File tree

5 files changed

+47
-14
lines changed

5 files changed

+47
-14
lines changed

src/librustc/hir/map/def_collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<'a> DefCollector<'a> {
7474
})
7575
}
7676

77-
fn visit_macro_invoc(&mut self, id: NodeId) {
77+
pub fn visit_macro_invoc(&mut self, id: NodeId) {
7878
self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
7979
}
8080
}

src/librustc_resolve/build_reduced_graph.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,24 @@ impl<'a> Resolver<'a> {
161161
}
162162

163163
crate fn build_reduced_graph(
164-
&mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
164+
&mut self,
165+
fragment: &AstFragment,
166+
extra_placeholders: &[ExpnId],
167+
parent_scope: ParentScope<'a>,
165168
) -> LegacyScope<'a> {
166-
fragment.visit_with(&mut DefCollector::new(&mut self.definitions, parent_scope.expansion));
169+
let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
170+
fragment.visit_with(&mut def_collector);
171+
for placeholder in extra_placeholders {
172+
def_collector.visit_macro_invoc(NodeId::placeholder_from_expn_id(*placeholder));
173+
}
174+
167175
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
168176
fragment.visit_with(&mut visitor);
177+
for placeholder in extra_placeholders {
178+
visitor.parent_scope.legacy =
179+
visitor.visit_invoc(NodeId::placeholder_from_expn_id(*placeholder));
180+
}
181+
169182
visitor.parent_scope.legacy
170183
}
171184

src/librustc_resolve/macros.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,18 @@ impl<'a> base::Resolver for Resolver<'a> {
115115
});
116116
}
117117

118+
119+
118120
fn visit_ast_fragment_with_placeholders(
119121
&mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId]
120122
) {
121-
// Fill in some data for derives if the fragment is from a derive container.
123+
// Integrate the new AST fragment into all the definition and module structures.
122124
// We are inside the `expansion` now, but other parent scope components are still the same.
123125
let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
124-
let parent_def = self.definitions.invocation_parent(expansion);
125-
self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope)));
126-
for &derive_invoc_id in derives {
127-
self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
128-
}
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-
let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
126+
let output_legacy_scope = self.build_reduced_graph(fragment, derives, parent_scope);
134127
self.output_legacy_scopes.insert(expansion, output_legacy_scope);
128+
129+
parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion);
135130
}
136131

137132
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
use proc_macro::TokenStream;
8+
9+
#[proc_macro_derive(repro)]
10+
pub fn proc_macro_hack_expr(_input: TokenStream) -> TokenStream {
11+
"macro_rules! m {()=>{}}".parse().unwrap()
12+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Derive macros can generate `macro_rules` items, regression test for issue #63651.
2+
3+
// check-pass
4+
// aux-build:gen-macro-rules.rs
5+
6+
extern crate gen_macro_rules as repro;
7+
8+
#[derive(repro::repro)]
9+
pub struct S;
10+
11+
m!(); // OK
12+
13+
fn main() {}

0 commit comments

Comments
 (0)