0

When trying to do

macro_rules! tipey {
    (Vec<$pt: tt>) => { 2 };
    (Vec<Option<$pt: tt>>) => { 3 };
    ($pt: tt) => { 1 };
}

macro_rules! structy {
    (struct $i: ident { 
        $($p: ident: $pt: tt $(<$ppt: tt $(<$gt: tt> )? > )?),+
        $(,)?
    }) => {
        const v: &[usize] = &[ $(tipey!( $pt $(<$ppt $(<$gt>)?>)?)),+ ];
    };
}

structy!(
    struct ContentDetails {
        pattern: String,
        fields: Vec<Option<String>>,
    }
);

I get

no rules expected the token >>

How do I make this parse?

ditoslav
  • 4,563
  • 10
  • 47
  • 79
  • 2
    Converted both `>>` to `> >`: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aa956e5c967b66f6140997e88088f8e9 Not sure if there's a better way. – Dogbert Nov 11 '22 at 10:47
  • omg you are right. this becomes a single token – ditoslav Nov 11 '22 at 11:03

1 Answers1

2

This problem is caused by your indiscriminate use of tt in your macros. This should be a last resort, as it can essentially match anything. The Rust compiler must disambiguate >> as part of a type v.s. expression based on the expected syntax. If you expect anything, then Rust must interpret >> as an operator.

Choose more appropriate metavariables such as ty (type), ident (identifier), path (fully specified path), etc.

orlp
  • 112,504
  • 36
  • 218
  • 315