Skip to content

Commit 99603e9

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 beec0a5 + 7f89f04 commit 99603e9

File tree

9 files changed

+55
-49
lines changed

9 files changed

+55
-49
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_privacy/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -880,11 +880,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
880880
self.tcx,
881881
self.tcx.hir().local_def_id(md.hir_id)
882882
).unwrap();
883-
let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
884-
if !self.tcx.hir().is_hir_id_module(module_id) {
885-
// `module_id` doesn't correspond to a `mod`, return early (#63164).
886-
return;
887-
}
883+
let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) {
884+
Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
885+
// `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
886+
_ => return,
887+
};
888888
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
889889
let new_level = self.update(md.hir_id, level);
890890
if new_level.is_none() {

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_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/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(crate_visibility_modifier)]
2+
#![feature(decl_macro)]
23
#![feature(proc_macro_diagnostic)]
34
#![feature(proc_macro_internals)]
45
#![feature(proc_macro_span)]

src/libsyntax_expand/placeholders.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::base::ExtCtxt;
22
use crate::expand::{AstFragment, AstFragmentKind};
33

4-
use syntax::ast::{self, NodeId};
4+
use syntax::ast;
55
use syntax::source_map::{DUMMY_SP, dummy_spanned};
66
use syntax::tokenstream::TokenStream;
77
use syntax::mut_visit::*;
@@ -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

src/test/rustdoc/macro-in-closure.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Regression issue for rustdoc ICE encountered in PR #65252.
2+
3+
#![feature(decl_macro)]
4+
5+
fn main() {
6+
|| {
7+
macro m() {}
8+
};
9+
}

0 commit comments

Comments
 (0)