Reputation: 11933
I would like to create an array in a macro to transform something like:
let array = create_array!(
fn test() -> i32 { }
fn test1() { }
);
into
let array = [test, test1];
I tried this:
macro_rules! create_array {
() => {
};
(fn $func_name:ident () -> $return_type:ty $block:block $($rest:tt)*) => {
$func_name,
create_array!($($rest)*);
};
(fn $func_name:ident () $block:block $($rest:tt)*) => {
$func_name,
create_array!($($rest)*);
};
}
but it fails with the following error:
error: macro expansion ignores token `,` and any following
--> src/main.rs:11:19
|
11 | $func_name,
| ^
|
note: caused by the macro expansion here; the usage of `create_array!` is likely invalid in expression context
--> src/main.rs:27:18
|
27 | let array = [create_array!(
|
I also tried this:
macro_rules! create_array {
($(fn $func_name:ident () $( -> $return_type:ty )* $block:block)*) => {
[$($func_name),*]
};
}
but it fails with:
error: local ambiguity: multiple parsing options: built-in NTs block ('block') or 1 other option.
--> src/main.rs:22:19
|
22 | fn test() -> i32 { }
|
So how can I create an array in such a case?
Upvotes: 1
Views: 975
Reputation: 11043
The parsing ambiguity of ->
vs $:block
has been resolved as of Rust 1.20, so the second version you tried will now work as intended.
macro_rules! create_array {
($(fn $func_name:ident () $(-> $return_type:ty)* $block:block)*) => {
[$($func_name),*]
};
}
fn main() {
let test = "TEST";
let test1 = "TEST1";
let array = create_array! {
fn test() -> i32 {}
fn test1() {}
};
println!("{:?}", array);
}
Upvotes: 3