From fd1e19ef8b450d0f87e4051dd58e5041790100c9 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 18 May 2021 14:14:20 -0400 Subject: [PATCH] Fix incorrect gating of nonterminals in key-value attributes Fixes #85432 When processing a `#[derive]` or `#[cfg_eval]` attribute, we need to re-parse our attribute target, which requires flattenting all `Nonterminals`. However, this caused us to incorrectly gate on a (flattented) nonterminal in a key-value attribute, which is supposed to be allowed. Since we already perform this gating during the initial parse, we suppress it in `capture_cfg` mode. --- compiler/rustc_parse/src/parser/mod.rs | 5 +++- .../macros/issue-85432-ungated-attr-macro.rs | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/macros/issue-85432-ungated-attr-macro.rs diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 35cfaae13a4a0..5f66f9b176db9 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1078,7 +1078,10 @@ impl<'a> Parser<'a> { match &expr.kind { // Not gated to support things like `doc = $expr` that work on stable. - _ if is_interpolated_expr => {} + // Do not gate in `capture_cfg` mode, since we flatten all nontemrinals + // before parsing. `capture_cfg` mode is only used to reparse existing + // tokens, so the gating will be performed by the initial parse + _ if is_interpolated_expr || self.capture_cfg => {} ExprKind::Lit(lit) if lit.kind.is_unsuffixed() => {} _ => self.sess.gated_spans.gate(sym::extended_key_value_attributes, span), } diff --git a/src/test/ui/macros/issue-85432-ungated-attr-macro.rs b/src/test/ui/macros/issue-85432-ungated-attr-macro.rs new file mode 100644 index 0000000000000..bac124c6f4c3c --- /dev/null +++ b/src/test/ui/macros/issue-85432-ungated-attr-macro.rs @@ -0,0 +1,30 @@ +// check-pass +// Regression test for issue #85432 +// Ensures that we don't incorrectly gate nonterminals +// in key-value macros when we need to reparse due to +// the presence of `#[derive]` + +macro_rules! with_doc_comment { + ($comment:expr, $item:item) => { + #[doc = $comment] + $item + }; +} + +macro_rules! database_table_doc { + () => { + "" + }; +} + +with_doc_comment! { + database_table_doc!(), + #[derive(Debug)] + struct Image { + #[cfg(FALSE)] + _f: (), + } + +} + +fn main() {}