Skip to content

Commit

Permalink
[macro_metavar_expr_concat] Add support for literals
Browse files Browse the repository at this point in the history
  • Loading branch information
c410-f3r committed Jul 9, 2024
1 parent 6be96e3 commit fd26d34
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 17 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_expand/src/mbe/metavar_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ impl MetaVarExpr {
}
}

/// Indicates what is placed in a `concat` parameter. For example, literals
/// (`${concat("foo", "bar")}`) or adhoc identifiers (`${concat(foo, bar)}`).
#[derive(Debug, Decodable, Encodable, PartialEq)]
pub(crate) enum MetaVarExprConcatElem {
/// Identifier WITHOUT a preceding dollar sign, which means that this identifier should be
Expand Down
35 changes: 23 additions & 12 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use crate::mbe::macro_parser::{NamedMatch, NamedMatch::*};
use crate::mbe::metavar_expr::{MetaVarExprConcatElem, RAW_IDENT_ERR};
use crate::mbe::{self, KleeneOp, MetaVarExpr};
use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::token::IdentIsRaw;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::token::{self, Delimiter, Nonterminal, Token, TokenKind};
use rustc_ast::token::{IdentIsRaw, Lit, LitKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast::ExprKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult};
use rustc_parse::lexer::nfc_normalize;
Expand Down Expand Up @@ -750,7 +751,7 @@ fn transcribe_metavar_expr<'a>(
Ok(())
}

/// Extracts an identifier that can be originated from a `$var:ident` variable or from a token tree.
/// Extracts an metavariable value that can be an identifier, a token tree or a literal.
fn extract_ident<'a>(
dcx: DiagCtxtHandle<'a>,
ident: Ident,
Expand All @@ -763,19 +764,29 @@ fn extract_ident<'a>(
}
return Ok(nt_ident.to_string());
}
if let ParseNtResult::Tt(TokenTree::Token(
Token { kind: TokenKind::Ident(token_ident, is_raw), .. },
_,
)) = pnr
{
if let IdentIsRaw::Yes = is_raw {
return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR));

if let ParseNtResult::Tt(TokenTree::Token(Token { kind, .. }, _)) = pnr {
if let TokenKind::Ident(symbol, is_raw) = kind {
if let IdentIsRaw::Yes = is_raw {
return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR));
}
return Ok(symbol.to_string());
}
return Ok(token_ident.to_string());

if let TokenKind::Literal(Lit { kind: LitKind::Str, symbol, suffix: None }) = kind {
return Ok(symbol.to_string());
}
}

if let ParseNtResult::Nt(nt) = pnr
&& let Nonterminal::NtLiteral(expr) = &**nt
&& let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) = &expr.kind
{
return Ok(symbol.to_string());
}
}
Err(dcx.struct_span_err(
ident.span,
"`${concat(..)}` currently only accepts identifiers or meta-variables as parameters",
"`${concat(..)}` currently only accepts identifiers, token trees or literals",
))
}
15 changes: 15 additions & 0 deletions tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ macro_rules! unsupported_literals {
}};
}

macro_rules! bad_literal_parameter {
($literal:literal) => {
const ${concat(_foo, $literal)}: () = ();
//~^ ERROR `${concat(..)}` is not generating a valid identifier
//~| ERROR `${concat(..)}` is not generating a valid identifier
//~| ERROR `${concat(..)}` is not generating a valid identifier
//~| ERROR `${concat(..)}` is not generating a valid identifier
}
}

fn main() {
wrong_concat_declarations!(1);

Expand All @@ -113,4 +123,9 @@ fn main() {
unsupported_literals!(_abc);

empty!();

bad_literal_parameter!("\u{00BD}");
bad_literal_parameter!("\x41");
bad_literal_parameter!("🤷");
bad_literal_parameter!("d[-_-]b");
}
48 changes: 46 additions & 2 deletions tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ error: expected identifier or string literal
LL | let ${concat($ident, 1)}: () = ();
| ^

error: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters
error: `${concat(..)}` currently only accepts identifiers, token trees or literals
--> $DIR/syntax-errors.rs:22:19
|
LL | ${concat($ex, aaaa)}
Expand Down Expand Up @@ -131,5 +131,49 @@ LL | empty!();
|
= note: this error originates in the macro `empty` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 18 previous errors
error: `${concat(..)}` is not generating a valid identifier
--> $DIR/syntax-errors.rs:103:16
|
LL | const ${concat(_foo, $literal)}: () = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | bad_literal_parameter!("\u{00BD}");
| ---------------------------------- in this macro invocation
|
= note: this error originates in the macro `bad_literal_parameter` (in Nightly builds, run with -Z macro-backtrace for more info)

error: `${concat(..)}` is not generating a valid identifier
--> $DIR/syntax-errors.rs:103:16
|
LL | const ${concat(_foo, $literal)}: () = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | bad_literal_parameter!("\x41");
| ------------------------------ in this macro invocation
|
= note: this error originates in the macro `bad_literal_parameter` (in Nightly builds, run with -Z macro-backtrace for more info)

error: `${concat(..)}` is not generating a valid identifier
--> $DIR/syntax-errors.rs:103:16
|
LL | const ${concat(_foo, $literal)}: () = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | bad_literal_parameter!("🤷");
| ---------------------------- in this macro invocation
|
= note: this error originates in the macro `bad_literal_parameter` (in Nightly builds, run with -Z macro-backtrace for more info)

error: `${concat(..)}` is not generating a valid identifier
--> $DIR/syntax-errors.rs:103:16
|
LL | const ${concat(_foo, $literal)}: () = ();
| ^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | bad_literal_parameter!("d[-_-]b");
| --------------------------------- in this macro invocation
|
= note: this error originates in the macro `bad_literal_parameter` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 22 previous errors

11 changes: 8 additions & 3 deletions tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
#![feature(macro_metavar_expr_concat)]

macro_rules! turn_to_page {
($ident:ident) => {
($ident:ident, $literal:literal, $tt:tt) => {
const ${concat("Ḧ", $ident)}: i32 = 394;
const ${concat("Ḧ", $literal)}: i32 = 394;
const ${concat("Ḧ", $tt)}: i32 = 394;
};
}

fn main() {
turn_to_page!(P);
assert_eq!(ḦP, 394);
turn_to_page!(P1, "Ṕ2", Ṕ);
assert_eq!(ḦṔ, 394);
assert_eq!(ḦP1, 394);
assert_eq!(ḦṔ2, 394);

}

0 comments on commit fd26d34

Please sign in to comment.