Search code examples
rustmacrosmetaprogramming

Why does a trailing comma prevent this macro from compiling?


I am trying to learn macros, to that effect I made this example:

macro_rules! Reflect
{
($name:ident {$($field_name:ident : $field_type:ty), *}) =>
{
  
    struct $name
    {
        $($field_name : $field_type), *
 
    }
 
};
}

Reflect!(
    Test
    {
        field : usize,
        field2 : usize,
    }
);

This exact syntax generates:

    |
183 | macro_rules! Reflect
    | -------------------- when calling this macro
...
202 |     }
    |     ^ no rules expected this token in macro call

But if I take out the last coma after field2 I can compile no problem. That makes no sense to me, the matching pattern has a comma at the end, why is it not always looking for a trailing comma?


Solution

  • The way to write a macro which allows a trailing comma, but does not require it, is:

    $($field_name:ident : $field_type:ty),* $(,)?
    

    That is: a comma-separated repetition, followed by an optional comma.