diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index eb874a27cece5..3b5eb318c922e 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -183,6 +183,17 @@ fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Sess } } +fn maybe_emit_macro_metavar_dollar_dollar_crate_feature( + features: &Features, + sess: &Session, + span: Span, +) { + if !features.macro_metavar_expr_dollar_dollar_crate() { + let msg = "the `$$crate` meta-variable expression is unstable"; + feature_err(sess, sym::macro_metavar_expr_dollar_dollar_crate, span, msg).emit(); + } +} + /// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a /// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree` /// for use in parsing a macro. @@ -319,6 +330,18 @@ fn parse_tree<'a>( } else { maybe_emit_macro_metavar_expr_feature(features, sess, dollar_span2); } + + // Gate `$$crate`. + if let Some(tokenstream::TokenTree::Token(token, _)) = iter.peek() + && let Some((ident, is_raw)) = token.ident() + && ident.name == kw::Crate + && matches!(is_raw, IdentIsRaw::No) + { + maybe_emit_macro_metavar_dollar_dollar_crate_feature( + features, sess, ident.span, + ); + } + TokenTree::token(token::Dollar, dollar_span2) } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 859a1ad391cb9..c56a59a272508 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -577,6 +577,8 @@ declare_features! ( (unstable, macro_metavar_expr, "1.61.0", Some(83527)), /// Provides a way to concatenate identifiers using metavariable expressions. (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)), + /// Allows using `$$crate`. + (incomplete, macro_metavar_expr_dollar_dollar_crate, "CURRENT_RUSTC_VERSION", Some(155111)), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), /// Enable mgca `type const` syntax before expansion. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 33bc5a578e8b6..b42ce31cb6057 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1201,6 +1201,7 @@ symbols! { macro_literal_matcher, macro_metavar_expr, macro_metavar_expr_concat, + macro_metavar_expr_dollar_dollar_crate, macro_reexport, macro_use, macro_vis_matcher, diff --git a/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.rs b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.rs new file mode 100644 index 0000000000000..77dd3aba700cd --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.rs @@ -0,0 +1,28 @@ +#![feature(macro_metavar_expr)] +pub const IDX: usize = 1; + +macro_rules! _direct_usage_super_2 { + () => { + macro_rules! _direct_usage_sub_2 { + () => { + $$crate + //~^ ERROR the `$$crate` meta-variable expression is unstable + } + } + }; +} + +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/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.stderr b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.stderr new file mode 100644 index 0000000000000..c2fe358eb101a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-macro-metavar-expr-dollar-dollar-crate.stderr @@ -0,0 +1,19 @@ +error[E0658]: the `$$crate` meta-variable expression is unstable + --> $DIR/feature-gate-macro-metavar-expr-dollar-dollar-crate.rs:8:19 + | +LL | $$crate + | ^^^^^ + | + = note: see issue #155111 for more information + = help: add `#![feature(macro_metavar_expr_dollar_dollar_crate)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: expected expression, found `$` + --> $DIR/feature-gate-macro-metavar-expr-dollar-dollar-crate.rs:17:29 + | +LL | const _FOO: usize = $d$d crate::IDX; + | ^^ expected expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`.