I use a declarative macro nested invocation other procedural macro, from arr![1_u32;2]
to arr_proc([1_u32;2])
.
I don't want to call arr_proc!
directly.
But I may got something wrong, when I compile the rust code.
It seems like the compiler can not expanded all the macro at some time.
My proc macro:
#[proc_macro]
pub fn arr_proc(input: TokenStream) -> TokenStream {
let repeat_expr: ExprRepeat = parse(input)
.expect("Like arr!([Test::default(); 16])");
let mut len = 0;
// get length from repeat_expr
if let Expr::Lit(expr_lit) = repeat_expr.len.deref() {
if let Lit::Int(int_lit) = &expr_lit.lit {
len = int_lit.base10_parse::<usize>().expect("Failed to parse integer literal");
}
}
// parse and concat
let _expr = repeat_expr.expr;
// 1. generate the arr
let mut _all = quote!();
for _i in 0..len {
// 2. append element into arr
_all = quote! { #_all #_expr, };
}
// 3. add []
let arr = quote! { [ #_all ] };
return arr.into();
}
My declarative macro:
#[macro_export]
macro_rules! arr {
($ele:expr; $repeat:literal) => {
custom_proc_macro::arr_proc!([$ele; $repeat])
};
}
My test case:
#[test]
fn test_arr_() {
let a: [u32; 2] = arr![1_u32;2];
dbg!(a);
}
The error is:
error[E0308]: mismatched types
--> tests/custom_proc_macro_test.rs:48:23
|
48 | let a: [u32; 2] = arr![1_u32;2];
| -------- ^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 0 elements
| | |
| | help: consider specifying the actual array length: `0`
| expected due to this
|
= note: expected array `[u32; 2]`
found array `[_; 0]`
= note: this error originates in the macro `custom_proc_macro::arr_proc` which comes from the expansion of the macro `arr` (in Nightly builds, run with -Z macro-backtrace for more info)
The meaning probably the compiler expanded the declarative macro and did not expand the proc macro.
How can I use like this? Can it works?