Skip to content

Commit d913071

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

File tree

2 files changed

+51
-13
lines changed

2 files changed

+51
-13
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() {}

0 commit comments

Comments
 (0)