Skip to content

Commit 7ce85f2

Browse files
committed
expand: Simplify expansion of derives
And make it more uniform with other macros. By merging placeholders for future derives' outputs into the derive container's output fragment early.
1 parent 2d3c17a commit 7ce85f2

File tree

7 files changed

+28
-40
lines changed

7 files changed

+28
-40
lines changed

src/librustc/hir/map/def_collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'a> DefCollector<'a> {
9090
}
9191
}
9292

93-
pub fn visit_macro_invoc(&mut self, id: NodeId) {
93+
fn visit_macro_invoc(&mut self, id: NodeId) {
9494
self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
9595
}
9696
}

src/librustc_resolve/build_reduced_graph.rs

-10
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,15 @@ impl<'a> Resolver<'a> {
163163
Some(ext)
164164
}
165165

166-
// FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
167166
crate fn build_reduced_graph(
168167
&mut self,
169168
fragment: &AstFragment,
170-
extra_placeholders: &[NodeId],
171169
parent_scope: ParentScope<'a>,
172170
) -> LegacyScope<'a> {
173171
let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
174172
fragment.visit_with(&mut def_collector);
175-
for placeholder in extra_placeholders {
176-
def_collector.visit_macro_invoc(*placeholder);
177-
}
178-
179173
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
180174
fragment.visit_with(&mut visitor);
181-
for placeholder in extra_placeholders {
182-
visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
183-
}
184-
185175
visitor.parent_scope.legacy
186176
}
187177

src/librustc_resolve/macros.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,11 @@ impl<'a> base::Resolver for Resolver<'a> {
108108
});
109109
}
110110

111-
// FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
112-
fn visit_ast_fragment_with_placeholders(
113-
&mut self, expansion: ExpnId, fragment: &AstFragment, extra_placeholders: &[NodeId]
114-
) {
111+
fn visit_ast_fragment_with_placeholders(&mut self, expansion: ExpnId, fragment: &AstFragment) {
115112
// Integrate the new AST fragment into all the definition and module structures.
116113
// We are inside the `expansion` now, but other parent scope components are still the same.
117114
let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
118-
let output_legacy_scope =
119-
self.build_reduced_graph(fragment, extra_placeholders, parent_scope);
115+
let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope);
120116
self.output_legacy_scopes.insert(expansion, output_legacy_scope);
121117

122118
parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);

src/libsyntax/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(const_fn)]
1212
#![feature(const_transmute)]
1313
#![feature(crate_visibility_modifier)]
14+
#![feature(decl_macro)]
1415
#![feature(label_break_value)]
1516
#![feature(nll)]
1617
#![feature(try_trait)]

src/libsyntax_expand/base.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,7 @@ pub trait Resolver {
851851
fn next_node_id(&mut self) -> NodeId;
852852

853853
fn resolve_dollar_crates(&mut self);
854-
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
855-
extra_placeholders: &[NodeId]);
854+
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment);
856855
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
857856

858857
fn expansion_for_ast_pass(

src/libsyntax_expand/expand.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use errors::{Applicability, FatalError};
2626
use smallvec::{smallvec, SmallVec};
2727
use syntax_pos::{Span, DUMMY_SP, FileName};
2828

29-
use rustc_data_structures::fx::FxHashMap;
3029
use rustc_data_structures::sync::Lrc;
3130
use std::io::ErrorKind;
3231
use std::{iter, mem, slice};
@@ -75,6 +74,22 @@ macro_rules! ast_fragments {
7574
}
7675

7776
impl AstFragment {
77+
pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
78+
if placeholders.is_empty() {
79+
return;
80+
}
81+
match self {
82+
$($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
83+
// We are repeating through arguments with `many`, to do that we have to
84+
// mention some macro variable from those arguments even if it's not used.
85+
#[cfg_attr(bootstrap, allow(unused_macros))]
86+
macro _repeating($flat_map_ast_elt) {}
87+
placeholder(AstFragmentKind::$Kind, *id).$make_ast()
88+
})),)?)*
89+
_ => panic!("unexpected AST fragment kind")
90+
}
91+
}
92+
7893
pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
7994
match self {
8095
AstFragment::OptExpr(expr) => expr,
@@ -342,7 +357,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
342357
// Unresolved macros produce dummy outputs as a recovery measure.
343358
invocations.reverse();
344359
let mut expanded_fragments = Vec::new();
345-
let mut all_derive_placeholders: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
346360
let mut undetermined_invocations = Vec::new();
347361
let (mut progress, mut force) = (false, !self.monotonic);
348362
loop {
@@ -420,9 +434,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
420434
self.cx.resolver.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
421435
}
422436

423-
let derive_placeholders =
424-
all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
425-
derive_placeholders.reserve(derives.len());
437+
let mut derive_placeholders = Vec::with_capacity(derives.len());
426438
invocations.reserve(derives.len());
427439
for path in derives {
428440
let expn_id = ExpnId::fresh(None);
@@ -438,7 +450,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
438450
}
439451
let fragment = invoc.fragment_kind
440452
.expect_from_annotatables(::std::iter::once(item));
441-
self.collect_invocations(fragment, derive_placeholders)
453+
self.collect_invocations(fragment, &derive_placeholders)
442454
}
443455
};
444456

@@ -457,10 +469,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
457469
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
458470
while let Some(expanded_fragments) = expanded_fragments.pop() {
459471
for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
460-
let derive_placeholders =
461-
all_derive_placeholders.remove(&expn_id).unwrap_or_else(Vec::new);
462472
placeholder_expander.add(NodeId::placeholder_from_expn_id(expn_id),
463-
expanded_fragment, derive_placeholders);
473+
expanded_fragment);
464474
}
465475
}
466476
fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
@@ -493,13 +503,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
493503
monotonic: self.monotonic,
494504
};
495505
fragment.mut_visit_with(&mut collector);
506+
fragment.add_placeholders(extra_placeholders);
496507
collector.invocations
497508
};
498509

499-
// FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
500510
if self.monotonic {
501511
self.cx.resolver.visit_ast_fragment_with_placeholders(
502-
self.cx.current_expansion.id, &fragment, extra_placeholders);
512+
self.cx.current_expansion.id, &fragment
513+
);
503514
}
504515

505516
(fragment, invocations)

src/libsyntax_expand/placeholders.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,8 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
171171
}
172172
}
173173

174-
pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, placeholders: Vec<NodeId>) {
174+
pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment) {
175175
fragment.mut_visit_with(self);
176-
if let AstFragment::Items(mut items) = fragment {
177-
for placeholder in placeholders {
178-
match self.remove(placeholder) {
179-
AstFragment::Items(derived_items) => items.extend(derived_items),
180-
_ => unreachable!(),
181-
}
182-
}
183-
fragment = AstFragment::Items(items);
184-
}
185176
self.expanded_fragments.insert(id, fragment);
186177
}
187178

0 commit comments

Comments
 (0)