From 243524884edcc7b10e53f3f11964212d56e86e9e Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Fri, 23 Apr 2021 04:52:16 +0800 Subject: [PATCH] Fix edition for `pat` fragments --- compiler/rustc_ast/src/token.rs | 9 ++------- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 ++ compiler/rustc_expand/src/mbe/quoted.rs | 19 +++++++++---------- src/test/ui/macros/auxiliary/issue-84429.rs | 4 ++++ src/test/ui/macros/issue-84429.rs | 9 +++++++++ 5 files changed, 26 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/macros/auxiliary/issue-84429.rs create mode 100644 src/test/ui/macros/issue-84429.rs diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 10d48a55bb54e..23da09ae4fd69 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -710,17 +710,12 @@ pub enum NonterminalKind { } impl NonterminalKind { - /// The `edition` closure is used to get the edition for the given symbol. Doing - /// `span.edition()` is expensive, so we do it lazily. - pub fn from_symbol( - symbol: Symbol, - edition: impl FnOnce() -> Edition, - ) -> Option { + pub fn from_symbol(symbol: Symbol, edition: Edition) -> Option { Some(match symbol { sym::item => NonterminalKind::Item, sym::block => NonterminalKind::Block, sym::stmt => NonterminalKind::Stmt, - sym::pat => match edition() { + sym::pat => match edition { Edition::Edition2015 | Edition::Edition2018 => { NonterminalKind::Pat2015 { inferred: true } } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index bc45c57596e15..82825b5db3a50 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -467,6 +467,7 @@ pub fn compile_declarative_macro( &sess.parse_sess, def.id, features, + edition, ) .pop() .unwrap(); @@ -492,6 +493,7 @@ pub fn compile_declarative_macro( &sess.parse_sess, def.id, features, + edition, ) .pop() .unwrap(); diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index e205cb65d0229..f29c0ab8a1cce 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -7,6 +7,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_feature::Features; use rustc_session::parse::{feature_err, ParseSess}; +use rustc_span::edition::Edition; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; @@ -42,6 +43,7 @@ pub(super) fn parse( sess: &ParseSess, node_id: NodeId, features: &Features, + edition: Edition, ) -> Vec { // Will contain the final collection of `self::TokenTree` let mut result = Vec::new(); @@ -52,7 +54,7 @@ pub(super) fn parse( while let Some(tree) = trees.next() { // Given the parsed tree, if there is a metavar and we are expecting matchers, actually // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`). - let tree = parse_tree(tree, &mut trees, expect_matchers, sess, node_id, features); + let tree = parse_tree(tree, &mut trees, expect_matchers, sess, node_id, features, edition); match tree { TokenTree::MetaVar(start_sp, ident) if expect_matchers => { let span = match trees.next() { @@ -78,11 +80,8 @@ pub(super) fn parse( } let kind = - token::NonterminalKind::from_symbol(frag.name, || { - span.edition() - }) - .unwrap_or_else( - || { + token::NonterminalKind::from_symbol(frag.name, edition) + .unwrap_or_else(|| { let msg = format!( "invalid fragment specifier `{}`", frag.name @@ -92,8 +91,7 @@ pub(super) fn parse( .help(VALID_FRAGMENT_NAMES_MSG) .emit(); token::NonterminalKind::Ident - }, - ); + }); result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); continue; } @@ -139,6 +137,7 @@ fn parse_tree( sess: &ParseSess, node_id: NodeId, features: &Features, + edition: Edition, ) -> TokenTree { // Depending on what `tree` is, we could be parsing different parts of a macro match tree { @@ -166,7 +165,7 @@ fn parse_tree( sess.span_diagnostic.span_err(span.entire(), &msg); } // Parse the contents of the sequence itself - let sequence = parse(tts, expect_matchers, sess, node_id, features); + let sequence = parse(tts, expect_matchers, sess, node_id, features, edition); // Get the Kleene operator and optional separator let (separator, kleene) = parse_sep_and_kleene_op(&mut trees, span.entire(), sess); @@ -219,7 +218,7 @@ fn parse_tree( span, Lrc::new(Delimited { delim, - tts: parse(tts, expect_matchers, sess, node_id, features), + tts: parse(tts, expect_matchers, sess, node_id, features, edition), }), ), } diff --git a/src/test/ui/macros/auxiliary/issue-84429.rs b/src/test/ui/macros/auxiliary/issue-84429.rs new file mode 100644 index 0000000000000..9497841b7cf4c --- /dev/null +++ b/src/test/ui/macros/auxiliary/issue-84429.rs @@ -0,0 +1,4 @@ +#[macro_export] +macro_rules! foo { + ($x:pat | $y:pat) => {} +} diff --git a/src/test/ui/macros/issue-84429.rs b/src/test/ui/macros/issue-84429.rs new file mode 100644 index 0000000000000..47a4e09e97d9b --- /dev/null +++ b/src/test/ui/macros/issue-84429.rs @@ -0,0 +1,9 @@ +// aux-build:issue-84429.rs +// edition:2021 +// check-pass + +extern crate issue_84429; + +fn main() { + issue_84429::foo!(1 | 2); +}