В вашем правиле для вашего макроса
f($x:expr, $y:expr, $z:expr);
$($c:expr => {
$($m:expr => {
$($s:expr => $b:expr),+
}),+
}),+
$x
, $y
и $z
связывают один expr
.Тем не менее, весь список $c
s связаны.Более того, с каждым $c
связан целый список $m
, поскольку $m
все еще находится внутри блока $(...).+
, связанного с $c
.Для каждого из этих $m
s связан весь список $s
s.
Теперь в вашем выводе
{{
match ($x, $y, $z) {
$(
($c, $m, $s => $b),
)+
}
}};
вы распаковываете только один слой списков с $(...)+
.После одного слоя $m
остается списком выражений («повторяющихся»), поэтому его нельзя использовать напрямую.Помните, что $m
- это действительно список списков (поскольку есть список $m
для каждого $c
), а $s
- это действительно список списков.
Вы либо собираетесьнеобходимо реструктурировать правило так, чтобы для каждого $c
(все в пределах одного $(...),+
) был только один $m
и один $s
, или вам потребуется реструктурировать вывод так, чтобы $m
и $s
распаковывается соответствующее количество раз.
После попытки первого подхода (один $(...),+
в правиле ввода), я бы предложил создать шаблоны $c
, $m
и $s
а не выражения (как в $c: pat
вместо $c: expr
).Это позволяет использовать их в левой части ветви матча.
macro_rules! my_macro {
{
f($x:expr, $y:expr, $z:expr);
$($c:pat => {
$m:pat => {
$s:pat => $b:expr
}
}),+
} => {
match ($x, $y, $z) {
$(
($c, $m, $s) => $b,
)+
}
};
}
Реальное решение во многом зависит от того, что именно вы пытаетесь достичь.