Rust doesn't expect a macros inside a structure initialization

Hello.

Take a look at the following code:

struct S {
    a: u32,
    b: u32,
    c: u32,
}

fn main() {
    let a = 5;
    let b = 6;

    macro_rules! mymacros {
        ($($name:ident,)+) => {
            $(
                $name: $name,
            )+
        };
    }

    let s = S {
        mymacros!(a, b,)
        c: 5,
    };
}

I expect

    let s = S {
        mymacros!(a, b,)
        c: 5,
    };

To be expended into

    let s = S {
        a: a,
        b: b,
        c: 5,
    };

But instead, the code doesn't compile. The full compiler output:

error: expected one of `,`, `:`, or `}`, found `!`
  --> src/main.rs:19:17
   |
18 |     let s = S {
   |             - while parsing this struct
19 |         mymacros!(a, b,)
   |                 ^ expected one of `,`, `:`, or `}`

error: expected identifier, found `)`
  --> src/main.rs:19:24
   |
18 |     let s = S {
   |             - while parsing this struct
19 |         mymacros!(a, b,)
   |                        ^ expected identifier

warning: unused macro definition: `mymacros`
  --> src/main.rs:10:18
   |
10 |     macro_rules! mymacros {
   |                  ^^^^^^^^
   |
   = note: `#[warn(unused_macros)]` on by default

error[E0063]: missing field `a` in initializer of `S`
  --> src/main.rs:18:13
   |
18 |     let s = S {
   |             ^ missing `a`

For more information about this error, try `rustc --explain E0063`.

What am I doing wrong?

1 Like

TLDR: you can't do this.

Macros can only be used in place where Item or an Expression is expected, and, correspondingly, must produce either a valid Item, or a valid Expression.

a: b is not a valid expression, and struct literal is not a context where expression is expected anyways.

2 Likes