Tail recursive macros

Holy crap, someone read that shit. :smiley:

Yeah, that's pretty badly out of date by now. Some really inconsiderate people went in and broke some of my favourite macro_rules tricks, including that one. Bastards.

Anyway, in this particular case, you have to do something like this, now:

#[macro_export]
macro_rules! count_exprs {
    () => { 0 };
    ($e:expr) => { 1 };
    ($e:expr, $($es:expr),+) => { 1 + count_exprs!($($es),*) };
}

Specifically, you have to put one of a small, fixed set of tokens after the $e:expr matcher. One of those is the comma.

Yes, it's redundant and annoying, but sadly there's no way around it and it is by design. Even more annoyingly, it's for a good reason: if the set of things that can come after a given construct are unrestricted, then the Rust grammar almost cannot be extended without causing macro invocations to parse differently under new versions of the compiler. That said, this particular case is, I think, just a case of macro_rules! being a bit stupider than we'd like.