2

My goal is to take as input trait type.

my_test_macro!(Trait1, Trait2<Test1, Test2=Test3>)

What I tried so far was writing parser like this.

$( $ty:ident < $( $N:ident $(: $b0:ident $(+$b:ident)* )? ),*  $($tname:ident=$ttype:ident),* > )+*

But it created local ambiguity.

error: local ambiguity: multiple parsing options: built-in NTs ident ('N') or ident ('tname').
Inline
  • 2,566
  • 1
  • 16
  • 32

1 Answers1

3

You can use the ty or path metavariables, depending on what you want to do:

macro_rules! my_test_macro {
    ($t1:ty, $t2:path) => {};
}

fn main() {
    my_test_macro!(Trait1, Trait2<Test1, Test2 = Test3>);
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • TIL you can use a `ty` variable where a trait is required: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0e16b9b4294bb480961284173247f7fb). I would have expected that to fail, like `impl dyn Trait for i32 {}` does. I wonder if this will change when bare trait syntax is dropped. – trent Nov 05 '19 at 15:41
  • Yeah, I assume that it's the duality of `SomeTraitName` being either a trait *or* a type that allows that. – Shepmaster Nov 05 '19 at 15:46