Skip to content

Commit f22a784

Browse files
authored
Rollup merge of rust-lang#65252 - petrochenkov:deriveholders2, r=matthewjasper
expand: Simplify expansion of derives And make it more uniform with other macros. This is done by merging placeholders for future derives' outputs into the derive container's output fragment early (addressing FIXMEs from rust-lang#63667). Also, macros with names starting with `_` are no longer reported as unused, in accordance with the usual behavior of `unused` lints. r? @matthewjasper or @mark-i-m
2 parents e56ba54 + 1270140 commit f22a784

File tree

7 files changed

+41
-44
lines changed

7 files changed

+41
-44
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

+12-13
Original file line numberDiff line numberDiff line change
@@ -162,25 +162,15 @@ impl<'a> Resolver<'a> {
162162
Some(ext)
163163
}
164164

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

@@ -1063,8 +1053,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
10631053
None
10641054
}
10651055

1056+
// Mark the given macro as unused unless its name starts with `_`.
1057+
// Macro uses will remove items from this set, and the remaining
1058+
// items will be reported as `unused_macros`.
1059+
fn insert_unused_macro(&mut self, ident: Ident, node_id: NodeId, span: Span) {
1060+
if !ident.as_str().starts_with("_") {
1061+
self.r.unused_macros.insert(node_id, span);
1062+
}
1063+
}
1064+
10661065
fn define_macro(&mut self, item: &ast::Item) -> LegacyScope<'a> {
1067-
let parent_scope = &self.parent_scope;
1066+
let parent_scope = self.parent_scope;
10681067
let expansion = parent_scope.expansion;
10691068
let (ext, ident, span, is_legacy) = match &item.kind {
10701069
ItemKind::MacroDef(def) => {
@@ -1104,7 +1103,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11041103
(res, vis, span, expansion, IsMacroExport));
11051104
} else {
11061105
self.r.check_reserved_macro_name(ident, res);
1107-
self.r.unused_macros.insert(item.id, span);
1106+
self.insert_unused_macro(ident, item.id, span);
11081107
}
11091108
LegacyScope::Binding(self.r.arenas.alloc_legacy_binding(LegacyBinding {
11101109
parent_legacy_scope: parent_scope.legacy, binding, ident
@@ -1113,7 +1112,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11131112
let module = parent_scope.module;
11141113
let vis = self.resolve_visibility(&item.vis);
11151114
if vis != ty::Visibility::Public {
1116-
self.r.unused_macros.insert(item.id, span);
1115+
self.insert_unused_macro(ident, item.id, span);
11171116
}
11181117
self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
11191118
self.parent_scope.legacy

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

0 commit comments

Comments
 (0)