Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"no rules expected the token `<`" when passing a type as an ident to macro_rules

Tags:

rust

Toy example:

macro_rules! boo {
    ($T:ident) => {
        let x: $T;
    };
}

fn main() {
    boo!(i32);         // WORKS
    boo!(Option<i32>); // PROBLEM
}

boo!(Option<i32>); causes the error:

error: no rules expected the token `<`
 --> src/main.rs:9:16
  |
9 |     boo!(Option<i32>);
  |                ^

I can work around it with:

type Opti32 = Option<i32>;
boo!(Opti32);

But it is too boring to add an alias for every usage of macros. Is it possible to use macros like boo!(Option<i32>); and hide the difficulty inside macro_rules?

like image 905
user1244932 Avatar asked Aug 31 '25 02:08

user1244932


1 Answers

$T:ident can only match an identifier.

If you want $T to match any type, even if it's not a single identifier, you should use $T:ty instead:

macro_rules! boo {
    ($T:ty) => {
        let x: $T;
    }
}

ident and ty are called "fragment specifiers" because they specify what kind of code fragment the metavariable $T can match. The first edition of the Rust book has a chapter on macros, including a list of possible fragment specifiers; you should definitely familiarize yourself with the contents of this chapter before trying to write a macro.

like image 181
trent Avatar answered Sep 02 '25 16:09

trent