Skip to content

Commit cc888dc

Browse files
committed
[macro_metavar_expr_concat] Allow concat in repetitions
1 parent 6be96e3 commit cc888dc

File tree

5 files changed

+44
-18
lines changed

5 files changed

+44
-18
lines changed

compiler/rustc_expand/src/mbe/macro_check.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,10 @@ fn check_occurrences(
352352
check_ops_is_prefix(psess, node_id, macros, binders, ops, span, name);
353353
}
354354
TokenTree::MetaVarExpr(dl, ref mve) => {
355-
let Some(name) = mve.ident().map(MacroRulesNormalizedIdent::new) else {
356-
return;
357-
};
358-
check_ops_is_prefix(psess, node_id, macros, binders, ops, dl.entire(), name);
355+
mve.idents((), |_, ident| {
356+
let name = MacroRulesNormalizedIdent::new(*ident);
357+
check_ops_is_prefix(psess, node_id, macros, binders, ops, dl.entire(), name);
358+
});
359359
}
360360
TokenTree::Delimited(.., ref del) => {
361361
check_nested_occurrences(psess, node_id, &del.tts, macros, binders, ops, guar);

compiler/rustc_expand/src/mbe/metavar_expr.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,18 @@ impl MetaVarExpr {
111111
Ok(rslt)
112112
}
113113

114-
pub(crate) fn ident(&self) -> Option<Ident> {
115-
match *self {
116-
MetaVarExpr::Count(ident, _) | MetaVarExpr::Ignore(ident) => Some(ident),
117-
MetaVarExpr::Concat { .. } | MetaVarExpr::Index(..) | MetaVarExpr::Len(..) => None,
114+
pub(crate) fn idents<A>(&self, mut aux: A, mut cb: impl FnMut(A, &Ident) -> A) -> A {
115+
match self {
116+
MetaVarExpr::Concat(elems) => {
117+
for elem in elems {
118+
if let MetaVarExprConcatElem::Var(ident) = elem {
119+
aux = cb(aux, ident)
120+
}
121+
}
122+
aux
123+
}
124+
MetaVarExpr::Count(ident, _) | MetaVarExpr::Ignore(ident) => cb(aux, ident),
125+
MetaVarExpr::Index(..) | MetaVarExpr::Len(..) => aux,
118126
}
119127
}
120128
}

compiler/rustc_expand/src/mbe/transcribe.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -556,17 +556,13 @@ fn lockstep_iter_size(
556556
}
557557
}
558558
TokenTree::MetaVarExpr(_, expr) => {
559-
let default_rslt = LockstepIterSize::Unconstrained;
560-
let Some(ident) = expr.ident() else {
561-
return default_rslt;
562-
};
563-
let name = MacroRulesNormalizedIdent::new(ident);
564-
match lookup_cur_matched(name, interpolations, repeats) {
565-
Some(MatchedSeq(ads)) => {
566-
default_rslt.with(LockstepIterSize::Constraint(ads.len(), name))
559+
expr.idents(LockstepIterSize::Unconstrained, |mut lis, ident| {
560+
let name = MacroRulesNormalizedIdent::new(*ident);
561+
if let Some(MatchedSeq(ads)) = lookup_cur_matched(name, interpolations, repeats) {
562+
lis = lis.with(LockstepIterSize::Constraint(ads.len(), name));
567563
}
568-
_ => default_rslt,
569-
}
564+
lis
565+
})
570566
}
571567
TokenTree::Token(..) => LockstepIterSize::Unconstrained,
572568
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(macro_metavar_expr_concat)]
2+
3+
macro_rules! many_idents_multi_metavar {
4+
($($a:ident),*) => {
5+
$(
6+
const ${concat($a, B)}: i32 = 3;
7+
//~^ ERROR: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters
8+
)*
9+
};
10+
}
11+
12+
fn main() {
13+
many_idents_multi_metavar!(A, B, C)
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters
2+
--> $DIR/repetitions.rs:6:29
3+
|
4+
LL | const ${concat($a, B)}: i32 = 3;
5+
| ^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)