To get a deeper understanding of how macros work in Rust I decided to replicate a macro from a C library.
During this, I needed to create an array of integers storing the size of each field.
My initial attempt looked like:
macro_rules! sample {
($($lit:literal, $ty:ty,)+) => {
const COUNT: usize = 0 $(+ {$lit; 1})* + 0;
const SIZES: [usize; COUNT] = {
let sizes = [$(size_of::<$ty>(),)*];
sizes
};
};
}
fn myfunc<'a>() {
sample!(1, u32, 2, &'a str,);
}
This expanded to what I expected it to
const COUNT: usize =
0 + {
1;
1
} + {
2;
1
} + 0;
const SIZES: [usize; COUNT] = {
let sizes = [size_of::<u32>(), size_of::<&'a str>()];
sizes
};
But this gave an error:
error[E0401]: can't use generic parameters from outer item
--> src/lib.rs:12:25
|
11 | fn asd<'a>() {
| -- lifetime parameter from outer item
12 | sample!(1, u32, 2, &'a str,);
| ^^ use of generic parameter from outer item
So I thought that I just have to remove the lifetime from the size_of call and all should be good.
I added another macro to shave off the lifetime from the reference but then I kept getting the same error.
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=9dda7d1117a29ce541acd46536219552
Expanded (which compiles just fine when copied over):
const COUNT: usize =
0 + {
1;
1
} + {
2;
1
} + 0;
const SIZES: [usize; COUNT] = {
let sizes = [size_of::<u32>(), size_of::<&str>()];
sizes
};
This actually isn't exactly what I am trying to do and I have already found other ways to do what I want.
But it this got me curious on why this is causes an error as I can't really see anything wrong with the expanded code and it compiles fine when inlined.
Is there some magic I'm not understanding here?
A browser interface to the Rust compiler to experiment with the language
