Skip to content

Commit 1270140

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 e8af4c1 commit 1270140

File tree

7 files changed

+29
-41
lines changed

7 files changed

+29
-41
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
@@ -161,25 +161,15 @@ impl<'a> Resolver<'a> {
161161
Some(ext)
162162
}
163163

164-
// FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
165164
crate fn build_reduced_graph(
166165
&mut self,
167166
fragment: &AstFragment,
168-
extra_placeholders: &[NodeId],
169167
parent_scope: ParentScope<'a>,
170168
) -> LegacyScope<'a> {
171169
let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
172170
fragment.visit_with(&mut def_collector);
173-
for placeholder in extra_placeholders {
174-
def_collector.visit_macro_invoc(*placeholder);
175-
}
176-
177171
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
178172
fragment.visit_with(&mut visitor);
179-
for placeholder in extra_placeholders {
180-
visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
181-
}
182-
183173
visitor.parent_scope.legacy
184174
}
185175

src/librustc_resolve/macros.rs

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

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

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

src/libsyntax/ext/base.rs

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

851851
fn resolve_dollar_crates(&mut self);
852-
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
853-
extra_placeholders: &[NodeId]);
852+
fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment);
854853
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
855854

856855
fn expansion_for_ast_pass(

src/libsyntax/ext/expand.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use errors::{Applicability, FatalError};
2323
use smallvec::{smallvec, SmallVec};
2424
use syntax_pos::{Span, DUMMY_SP, FileName};
2525

26-
use rustc_data_structures::fx::FxHashMap;
2726
use rustc_data_structures::sync::Lrc;
2827
use std::io::ErrorKind;
2928
use std::{iter, mem, slice};
@@ -72,6 +71,22 @@ macro_rules! ast_fragments {
7271
}
7372

7473
impl AstFragment {
74+
pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
75+
if placeholders.is_empty() {
76+
return;
77+
}
78+
match self {
79+
$($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
80+
// We are repeating through arguments with `many`, to do that we have to
81+
// mention some macro variable from those arguments even if it's not used.
82+
#[cfg_attr(bootstrap, allow(unused_macros))]
83+
macro _repeating($flat_map_ast_elt) {}
84+
placeholder(AstFragmentKind::$Kind, *id).$make_ast()
85+
})),)?)*
86+
_ => panic!("unexpected AST fragment kind")
87+
}
88+
}
89+
7590
pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
7691
match self {
7792
AstFragment::OptExpr(expr) => expr,
@@ -339,7 +354,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
339354
// Unresolved macros produce dummy outputs as a recovery measure.
340355
invocations.reverse();
341356
let mut expanded_fragments = Vec::new();
342-
let mut all_derive_placeholders: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
343357
let mut undetermined_invocations = Vec::new();
344358
let (mut progress, mut force) = (false, !self.monotonic);
345359
loop {
@@ -416,9 +430,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
416430
self.cx.resolver.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
417431
}
418432

419-
let derive_placeholders =
420-
all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
421-
derive_placeholders.reserve(derives.len());
433+
let mut derive_placeholders = Vec::with_capacity(derives.len());
422434
invocations.reserve(derives.len());
423435
for path in derives {
424436
let expn_id = ExpnId::fresh(None);
@@ -434,7 +446,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
434446
}
435447
let fragment = invoc.fragment_kind
436448
.expect_from_annotatables(::std::iter::once(item));
437-
self.collect_invocations(fragment, derive_placeholders)
449+
self.collect_invocations(fragment, &derive_placeholders)
438450
}
439451
};
440452

@@ -453,10 +465,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
453465
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
454466
while let Some(expanded_fragments) = expanded_fragments.pop() {
455467
for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
456-
let derive_placeholders =
457-
all_derive_placeholders.remove(&expn_id).unwrap_or_else(Vec::new);
458468
placeholder_expander.add(NodeId::placeholder_from_expn_id(expn_id),
459-
expanded_fragment, derive_placeholders);
469+
expanded_fragment);
460470
}
461471
}
462472
fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
@@ -489,13 +499,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
489499
monotonic: self.monotonic,
490500
};
491501
fragment.mut_visit_with(&mut collector);
502+
fragment.add_placeholders(extra_placeholders);
492503
collector.invocations
493504
};
494505

495-
// FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
496506
if self.monotonic {
497507
self.cx.resolver.visit_ast_fragment_with_placeholders(
498-
self.cx.current_expansion.id, &fragment, extra_placeholders);
508+
self.cx.current_expansion.id, &fragment
509+
);
499510
}
500511

501512
(fragment, invocations)

src/libsyntax/ext/placeholders.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ast::{self, NodeId};
1+
use crate::ast;
22
use crate::source_map::{DUMMY_SP, dummy_spanned};
33
use crate::ext::base::ExtCtxt;
44
use crate::ext::expand::{AstFragment, AstFragmentKind};
@@ -170,17 +170,8 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
170170
}
171171
}
172172

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

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(mem_take)]
1617
#![feature(nll)]

0 commit comments

Comments
 (0)