6

I'm trying to write a Rust macro that fills up an array with repeating elements, in this case with zeros. This is what I came up with:

macro_rules! pad4  {
    () => {
        println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
    }
}

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];

But I'm getting the following error:

expected `u8`, found `()`
pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
Andor Polgar
  • 483
  • 3
  • 13

1 Answers1

3

Rust macros aren't simple string replacements, they pattern match over parsed tokens and must return Rust syntax that is valid in the context the macro is invoked in.

Your current macro:

macro_rules! pad4  {
    () => {
        println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
    }
}

Called in this context:

const arr: [u8; 8] = [pad4!(), 0b01111100, 0b10000010, 0b00000010, 0b01111110];

Expands to this:

const arr: [u8; 8] = [
    {
        println!("0b00000000, 0b00000000, 0b00000000, 0b00000000");
    },
    0b01111100,
    0b10000010,
    0b00000010,
    0b01111110,
];

Which is why you're getting an error, as the first expression block in the array returns () instead of the expected u8.

You can use e.g. cargo expand to easily inspect the result of macro expansion.


Here's pad4 but written in a way that works:

macro_rules! pad4 {
    [$($e:expr),*] => {
        [0b00000000, 0b00000000, 0b00000000, 0b00000000, $($e,)*]
    }
}

const arr: [u8; 8] = pad4![0b01111100, 0b10000010, 0b00000010, 0b01111110];

playground

If you're brand new to Rust's declarative macros the go-to resource to learn them in-depth is The Little Book of Rust Macros.

vallentin
  • 23,478
  • 6
  • 59
  • 81
pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
  • Thank you, yes, I'm quite new to Rust. So there is absolutely no way to insert code like with C macros? – Andor Polgar Jan 24 '21 at 16:25
  • 1
    I'm not a macros expert in either C or Rust, so I can't say for certain. Aside from the book I recommend in my answer you may also find this resource helpful: [Porting C Macros to Rust](https://locka99.gitbooks.io/a-guide-to-porting-c-to-rust/content/features_of_rust/macros.html). – pretzelhammer Jan 24 '21 at 16:38