Help with macros

I look at this tutorial :


and I hit problem while using example code which is bad in my experience. I think the example is made with old compiler or nightly ... anyway.
#[macro_export]
macro_rules! recurrence {
    ( a[n] = $($inits:expr),+ , ... , $recur:expr ) => {
        // struct Recurance {
        //     elements : std::Vec<u32>
        // }

    }
}
...
let fib = recurrence![a[n] = 0, 1, ..., a[n-1] + a[n-2]];

Gave me that

error: local ambiguity: multiple parsing options: built-in NTs expr ('inits') or 1 other option.
 --> macros/src/main.rs:5:44
  |
5 |     let mut rec = recurrence![a[n] = 0, 1, ..., a[n-1] + a[n-2]];

I don't understand why macro_rules mistaking "...," for expression I also tried other patterns like ";" separator but still have problems. Is there someone that can explain to me why this is wrong and how I can fix it. Also is it possible to get the type of $expr. I want to construct vector of that type

It's a mistake from the book itself, I think.

To be fair, I don't get exactly why Rust thinks it could parse ... as an expression, since macro_rules! m{($e:expr)=>()} m!(...); fails. Still, such sigil may be seen as a valid expression prefix, which is how Rust resolves ambiguities: it peeks and chooses accordingly. So, here, it may have peeked, seen ..., and if that, in some convoluted way, is a valid expression prefix, then Rust will not know which parsing to favor, and thus errors.

One solution is to use a special separator when about to reach ...:

#[macro_export]
macro_rules! recurrence {
    (
        a[n] = $($inits:expr),+ ; ... ; $recur:expr
    ) => ({
        // struct Recurance {
        //     elements : std::Vec<u32>
        // }

    });
}
// ...
let fib = recurrence![a[n] = 0, 1; ...; a[n-1] + a[n-2]];
1 Like

The latest commit to the book’s repository was in 2016. This predates RFC 2137, which added variadic FFI support using the ... syntax.

1 Like

I did try to run that code using godbolt on Rust 1.0.0, and even there it fails with the same error message :sweat_smile:

1 Like