From f4f39135b869de5fcc33c45448fc305d73463fd0 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 18 Jul 2022 15:58:06 -0300 Subject: [PATCH] Forbid $$crate --- compiler/rustc_expand/src/mbe/quoted.rs | 26 +++++++++++----- .../dollar_dollar_crate.rs | 30 +++++++++++++++++++ .../dollar_dollar_crate.stderr | 16 ++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.rs create mode 100644 src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.stderr diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index d4b8563a03666..a736eb26d7c8b 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -2,6 +2,7 @@ use crate::mbe::macro_parser::count_metavar_decls; use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree}; use rustc_ast::token::{self, Delimiter, Token}; +use rustc_ast::tokenstream::Cursor; use rustc_ast::{tokenstream, NodeId}; use rustc_ast_pretty::pprust; use rustc_feature::Features; @@ -136,7 +137,7 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess, /// - `features`: language features so we can do feature gating. fn parse_tree( tree: tokenstream::TokenTree, - outer_trees: &mut impl Iterator, + outer_trees: &mut Cursor, parsing_patterns: bool, sess: &ParseSess, node_id: NodeId, @@ -150,13 +151,13 @@ fn parse_tree( // FIXME: Handle `Invisible`-delimited groups in a more systematic way // during parsing. let mut next = outer_trees.next(); - let mut trees: Box>; + let mut trees_owned = None; if let Some(tokenstream::TokenTree::Delimited(_, Delimiter::Invisible, tts)) = next { - trees = Box::new(tts.into_trees()); - next = trees.next(); - } else { - trees = Box::new(outer_trees); + let mut local_trees = tts.into_trees(); + next = local_trees.next(); + trees_owned = Some(local_trees); } + let trees = if let Some(ref mut elem) = trees_owned { elem } else { outer_trees }; match next { // `tree` is followed by a delimited set of token trees. @@ -205,7 +206,7 @@ fn parse_tree( let sequence = parse(tts, parsing_patterns, sess, node_id, features, edition); // Get the Kleene operator and optional separator let (separator, kleene) = - parse_sep_and_kleene_op(&mut trees, delim_span.entire(), sess); + parse_sep_and_kleene_op(trees, delim_span.entire(), sess); // Count the number of captured "names" (i.e., named metavars) let num_captures = if parsing_patterns { count_metavar_decls(&sequence) } else { 0 }; @@ -235,9 +236,18 @@ fn parse_tree( &Token { kind: token::Dollar, span }, ); } + if let Some(tokenstream::TokenTree::Token(ref token)) = trees.look_ahead(0) + && let Some((ident, is_raw)) = token.ident() + && ident.name == kw::Crate && !is_raw + { + sess.span_diagnostic.span_err( + token.span, + &format!("unexpected token: {}", pprust::token_to_string(token)) + ); + sess.span_diagnostic.note_without_error("`$$crate` is not allowed in any context"); + } TokenTree::token(token::Dollar, span) } - // `tree` is followed by some other token. This is an error. Some(tokenstream::TokenTree::Token(token)) => { let msg = format!( diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.rs b/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.rs new file mode 100644 index 0000000000000..c767e4521201e --- /dev/null +++ b/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.rs @@ -0,0 +1,30 @@ +// All possible usages of $$crate are currently forbidden + +pub const IDX: usize = 1; + +macro_rules! _direct_usage_super { + () => { + macro_rules! _direct_usage_sub { + () => {{ + $$crate + //~^ ERROR unexpected token: crate + }}; + } + }; +} + +macro_rules! indirect_usage_crate { + ($d:tt) => { + const _FOO: usize = $d$d crate::IDX; + //~^ ERROR expected expression, found `$` + }; +} +macro_rules! indirect_usage_use { + ($d:tt) => { + indirect_usage_crate!($d); + } +} +indirect_usage_use!($); + +fn main() { +} diff --git a/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.stderr b/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.stderr new file mode 100644 index 0000000000000..42b7d4ba7b772 --- /dev/null +++ b/src/test/ui/macros/rfc-3086-metavar-expr/dollar_dollar_crate.stderr @@ -0,0 +1,16 @@ +error: unexpected token: crate + --> $DIR/dollar_dollar_crate.rs:9:19 + | +LL | $$crate + | ^^^^^ + +note: `$$crate` is not allowed in any context + +error: expected expression, found `$` + --> $DIR/dollar_dollar_crate.rs:18:29 + | +LL | const _FOO: usize = $d$d crate::IDX; + | ^^ expected expression + +error: aborting due to 2 previous errors +