Skip to content

Commit 0f793cc

Browse files
committed
Fix macro_metavar_expr_concat behavior with nested repetitions
1 parent 693f365 commit 0f793cc

File tree

6 files changed

+67
-30
lines changed

6 files changed

+67
-30
lines changed

compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -558,26 +558,29 @@ fn metavar_expr_concat<'tx>(
558558
MetaVarExprConcatElem::Ident(elem) => elem.name,
559559
MetaVarExprConcatElem::Literal(elem) => *elem,
560560
MetaVarExprConcatElem::Var(ident) => {
561-
match matched_from_ident(dcx, *ident, tscx.interp)? {
562-
NamedMatch::MatchedSeq(named_matches) => {
563-
let Some((curr_idx, _)) = tscx.repeats.last() else {
564-
return Err(dcx.struct_span_err(dspan.entire(), "invalid syntax"));
565-
};
566-
match &named_matches[*curr_idx] {
567-
// FIXME(c410-f3r) Nested repetitions are unimplemented
568-
MatchedSeq(_) => {
561+
let mut matched = matched_from_ident(dcx, *ident, tscx.interp)?;
562+
let mut repeats_iter = tscx.repeats.iter();
563+
564+
loop {
565+
match matched {
566+
NamedMatch::MatchedSingle(pnr) => {
567+
let symbol = extract_symbol_from_pnr(dcx, pnr, ident.span)?;
568+
concatenated.push_str(symbol.as_str());
569+
break;
570+
}
571+
NamedMatch::MatchedSeq(named_matches) => {
572+
if let Some((idx, _)) = repeats_iter.next() {
573+
matched = &named_matches[*idx];
574+
} else {
569575
return Err(dcx.struct_span_err(
570576
ident.span,
571-
"nested repetitions with `${concat(...)}` metavariable expressions are not yet supported",
577+
"`${concat(...)}` variable is still repeating at this depth",
572578
));
573579
}
574-
MatchedSingle(pnr) => extract_symbol_from_pnr(dcx, pnr, ident.span)?,
575580
}
576581
}
577-
NamedMatch::MatchedSingle(pnr) => {
578-
extract_symbol_from_pnr(dcx, pnr, ident.span)?
579-
}
580582
}
583+
continue;
581584
}
582585
};
583586
concatenated.push_str(symbol.as_str());
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//@ check-pass
2+
#![feature(macro_metavar_expr_concat)]
3+
4+
struct A;
5+
struct B;
6+
const AA: A = A;
7+
const BB: B = B;
8+
9+
macro_rules! define_ioctl_data {
10+
(struct $s:ident {
11+
$($field:ident: $ty:ident $([$opt:ident])?,)*
12+
}) => {
13+
pub struct $s {
14+
$($field: $ty,)*
15+
}
16+
17+
impl $s {
18+
$($(
19+
fn ${concat(get_, $field)}(&self) -> $ty {
20+
let _ = $opt;
21+
todo!()
22+
}
23+
)?)*
24+
}
25+
};
26+
}
27+
28+
define_ioctl_data! {
29+
struct Foo {
30+
a: A [AA],
31+
b: B [BB],
32+
}
33+
}
34+
35+
fn main() {}

tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ macro_rules! InRepetition {
1111
) => {
1212
$(
1313
$(
14-
${concat(_, $arg)} //~ ERROR nested repetitions with `${concat(...)}` metavariable expressions are not yet supported
14+
${concat(_, $arg)} //~ ERROR macro expansion ends with an incomplete expression: expected one of `!` or `::`
1515
)*
1616
)*
1717
};
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: nested repetitions with `${concat(...)}` metavariable expressions are not yet supported
2-
--> $DIR/in-repetition.rs:14:30
1+
error: macro expansion ends with an incomplete expression: expected one of `!` or `::`
2+
--> $DIR/in-repetition.rs:14:35
33
|
44
LL | ${concat(_, $arg)}
5-
| ^^^
5+
| ^ expected one of `!` or `::`
66

77
error: aborting due to 1 previous error
88

tests/ui/macros/metavar-expressions/concat-repetitions.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@ macro_rules! one_rep {
1111
macro_rules! issue_128346 {
1212
( $($a:ident)* ) => {
1313
A(
14-
const ${concat($a, Z)}: i32 = 3;
15-
//~^ ERROR invalid syntax
14+
const ${concat($a, Z)}: i32 = 3; //~ ERROR `${concat(...)}` variable is still repeating at this depth
1615
)*
1716
};
1817
}
1918

2019
macro_rules! issue_131393 {
2120
($t:ident $($en:ident)?) => {
2221
read::<${concat($t, $en)}>()
23-
//~^ ERROR invalid syntax
24-
//~| ERROR invalid syntax
22+
//~^ ERROR `${concat(...)}` variable is still repeating at this depth
23+
//~| ERROR `${concat(...)}` variable is still repeating at this depth
2524
}
2625
}
2726

tests/ui/macros/metavar-expressions/concat-repetitions.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error: invalid syntax
2-
--> $DIR/concat-repetitions.rs:14:20
1+
error: `${concat(...)}` variable is still repeating at this depth
2+
--> $DIR/concat-repetitions.rs:14:29
33
|
44
LL | const ${concat($a, Z)}: i32 = 3;
5-
| ^^^^^^^^^^^^^^^
5+
| ^
66

7-
error: invalid syntax
8-
--> $DIR/concat-repetitions.rs:22:17
7+
error: `${concat(...)}` variable is still repeating at this depth
8+
--> $DIR/concat-repetitions.rs:21:30
99
|
1010
LL | read::<${concat($t, $en)}>()
11-
| ^^^^^^^^^^^^^^^^^
11+
| ^^
1212

13-
error: invalid syntax
14-
--> $DIR/concat-repetitions.rs:22:17
13+
error: `${concat(...)}` variable is still repeating at this depth
14+
--> $DIR/concat-repetitions.rs:21:30
1515
|
1616
LL | read::<${concat($t, $en)}>()
17-
| ^^^^^^^^^^^^^^^^^
17+
| ^^
1818
|
1919
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2020

0 commit comments

Comments
 (0)