Skip to content

Commit 9326cd4

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 9611993 + 1270140 commit 9326cd4

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
@@ -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

@@ -1064,8 +1054,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
10641054
None
10651055
}
10661056

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

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/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
@@ -24,7 +24,6 @@ use errors::{Applicability, FatalError};
2424
use smallvec::{smallvec, SmallVec};
2525
use syntax_pos::{Span, DUMMY_SP, FileName};
2626

27-
use rustc_data_structures::fx::FxHashMap;
2827
use rustc_data_structures::sync::Lrc;
2928
use std::io::ErrorKind;
3029
use std::{iter, mem, slice};
@@ -73,6 +72,22 @@ macro_rules! ast_fragments {
7372
}
7473

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

421-
let derive_placeholders =
422-
all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
423-
derive_placeholders.reserve(derives.len());
435+
let mut derive_placeholders = Vec::with_capacity(derives.len());
424436
invocations.reserve(derives.len());
425437
for path in derives {
426438
let expn_id = ExpnId::fresh(None);
@@ -436,7 +448,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
436448
}
437449
let fragment = invoc.fragment_kind
438450
.expect_from_annotatables(::std::iter::once(item));
439-
self.collect_invocations(fragment, derive_placeholders)
451+
self.collect_invocations(fragment, &derive_placeholders)
440452
}
441453
};
442454

@@ -455,10 +467,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
455467
let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
456468
while let Some(expanded_fragments) = expanded_fragments.pop() {
457469
for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
458-
let derive_placeholders =
459-
all_derive_placeholders.remove(&expn_id).unwrap_or_else(Vec::new);
460470
placeholder_expander.add(NodeId::placeholder_from_expn_id(expn_id),
461-
expanded_fragment, derive_placeholders);
471+
expanded_fragment);
462472
}
463473
}
464474
fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
@@ -491,13 +501,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
491501
monotonic: self.monotonic,
492502
};
493503
fragment.mut_visit_with(&mut collector);
504+
fragment.add_placeholders(extra_placeholders);
494505
collector.invocations
495506
};
496507

497-
// FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
498508
if self.monotonic {
499509
self.cx.resolver.visit_ast_fragment_with_placeholders(
500-
self.cx.current_expansion.id, &fragment, extra_placeholders);
510+
self.cx.current_expansion.id, &fragment
511+
);
501512
}
502513

503514
(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)