summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_expand/src/mbe/metavar_expr.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_expand/src/mbe/metavar_expr.rs
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_expand/src/mbe/metavar_expr.rs')
-rw-r--r--compiler/rustc_expand/src/mbe/metavar_expr.rs53
1 files changed, 36 insertions, 17 deletions
diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs
index 7cb279a98..e3dc73d0d 100644
--- a/compiler/rustc_expand/src/mbe/metavar_expr.rs
+++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs
@@ -10,9 +10,8 @@ use rustc_span::Span;
/// A meta-variable expression, for expansions based on properties of meta-variables.
#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
pub(crate) enum MetaVarExpr {
- /// The number of repetitions of an identifier, optionally limited to a number
- /// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
- Count(Ident, Option<usize>),
+ /// The number of repetitions of an identifier.
+ Count(Ident, usize),
/// Ignore a meta-variable for repetition without expansion.
Ignore(Ident),
@@ -35,20 +34,23 @@ impl MetaVarExpr {
) -> PResult<'sess, MetaVarExpr> {
let mut tts = input.trees();
let ident = parse_ident(&mut tts, sess, outer_span)?;
- let Some(TokenTree::Delimited(_, Delimiter::Parenthesis, args)) = tts.next() else {
+ let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = tts.next() else {
let msg = "meta-variable expression parameter must be wrapped in parentheses";
- return Err(sess.span_diagnostic.struct_span_err(ident.span, msg));
+ return Err(sess.dcx.struct_span_err(ident.span, msg));
};
check_trailing_token(&mut tts, sess)?;
let mut iter = args.trees();
let rslt = match ident.as_str() {
"count" => parse_count(&mut iter, sess, ident.span)?,
- "ignore" => MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?),
+ "ignore" => {
+ eat_dollar(&mut iter, sess, ident.span)?;
+ MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?)
+ }
"index" => MetaVarExpr::Index(parse_depth(&mut iter, sess, ident.span)?),
"length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?),
_ => {
let err_msg = "unrecognized meta-variable expression";
- let mut err = sess.span_diagnostic.struct_span_err(ident.span, err_msg);
+ let mut err = sess.dcx.struct_span_err(ident.span, err_msg);
err.span_suggestion(
ident.span,
"supported expressions are count, ignore, index and length",
@@ -77,7 +79,7 @@ fn check_trailing_token<'sess>(
) -> PResult<'sess, ()> {
if let Some(tt) = iter.next() {
let mut diag = sess
- .span_diagnostic
+ .dcx
.struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt)));
diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens");
Err(diag)
@@ -92,17 +94,18 @@ fn parse_count<'sess>(
sess: &'sess ParseSess,
span: Span,
) -> PResult<'sess, MetaVarExpr> {
+ eat_dollar(iter, sess, span)?;
let ident = parse_ident(iter, sess, span)?;
let depth = if try_eat_comma(iter) {
if iter.look_ahead(0).is_none() {
- return Err(sess.span_diagnostic.struct_span_err(
+ return Err(sess.dcx.struct_span_err(
span,
"`count` followed by a comma must have an associated index indicating its depth",
));
}
- Some(parse_depth(iter, sess, span)?)
+ parse_depth(iter, sess, span)?
} else {
- None
+ 0
};
Ok(MetaVarExpr::Count(ident, depth))
}
@@ -116,7 +119,7 @@ fn parse_depth<'sess>(
let Some(tt) = iter.next() else { return Ok(0) };
let TokenTree::Token(token::Token { kind: token::TokenKind::Literal(lit), .. }, _) = tt else {
return Err(sess
- .span_diagnostic
+ .dcx
.struct_span_err(span, "meta-variable expression depth must be a literal"));
};
if let Ok(lit_kind) = LitKind::from_token_lit(*lit)
@@ -126,7 +129,7 @@ fn parse_depth<'sess>(
Ok(n_usize)
} else {
let msg = "only unsuffixes integer literals are supported in meta-variable expressions";
- Err(sess.span_diagnostic.struct_span_err(span, msg))
+ Err(sess.dcx.struct_span_err(span, msg))
}
}
@@ -143,9 +146,8 @@ fn parse_ident<'sess>(
return Ok(elem);
}
let token_str = pprust::token_to_string(token);
- let mut err = sess
- .span_diagnostic
- .struct_span_err(span, format!("expected identifier, found `{}`", &token_str));
+ let mut err =
+ sess.dcx.struct_span_err(span, format!("expected identifier, found `{}`", &token_str));
err.span_suggestion(
token.span,
format!("try removing `{}`", &token_str),
@@ -154,7 +156,7 @@ fn parse_ident<'sess>(
);
return Err(err);
}
- Err(sess.span_diagnostic.struct_span_err(span, "expected identifier"))
+ Err(sess.dcx.struct_span_err(span, "expected identifier"))
}
/// Tries to move the iterator forward returning `true` if there is a comma. If not, then the
@@ -166,3 +168,20 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
}
false
}
+
+/// Expects that the next item is a dollar sign.
+fn eat_dollar<'sess>(
+ iter: &mut RefTokenTreeCursor<'_>,
+ sess: &'sess ParseSess,
+ span: Span,
+) -> PResult<'sess, ()> {
+ if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0)
+ {
+ let _ = iter.next();
+ return Ok(());
+ }
+ Err(sess.dcx.struct_span_err(
+ span,
+ "meta-variables within meta-variable expressions must be referenced using a dollar sign",
+ ))
+}