在宏中调用 rust 宏时如何解决这个 "no rules expected"?

How do I fix this "no rules expected" when calling a rust macro in a macro?

正在尝试学习 Rust 宏。我决定制作一个像 vec! 宏一样操作的宏,但将参数包装在 NonZeroUsize 中。我的尝试是:

macro_rules! nzvec {
    ($T:ty, $($x:expr),* ) => {
        vec![$($T::new($x).unwrap()),*];
    }
}

我想调用 nzvec![NonZeroU32, 1, 2] 生成 vec![NonZeroU32::new(1).unwrap(), NonZeroU32::new(2).unwrap()],然后使用 vec 宏进一步扩展。相反,我得到了一个错误:

error: no rules expected the token `NonZeroU32`
  --> src/main.rs:5:12
   |
5  |     vec![$($T::new($x).unwrap()),*];
   |            ^^ no rules expected this token in macro call
...
10 |   let vec: Vec<NonZeroU32> = nzvec![NonZeroU32, 1, 2, 3];
   |                              --------------------------- in this macro invocation

然后我 运行 cargo rustc -- -Z trace-macros 得到:

note: trace_macro
  --> src/main.rs:10:30
   |
10 |   let vec: Vec<NonZeroU32> = nzvec![NonZeroU32, 1, 2, 3];
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: expanding `nzvec! { NonZeroU32, 1, 2, 3 }`
   = note: to `vec!
           [NonZeroU32 :: new(1).unwrap(), NonZeroU32 :: new(2).unwrap(), NonZeroU32 ::
            new(3).unwrap()] ;`
   = note: expanding `vec! { NonZeroU32 :: new(1).unwrap(), NonZeroU32 :: new(2).unwrap(), NonZeroU32 ::
           new(3).unwrap() }`

在我看来,宏运行正常...是什么原因?

编译器错误可能会更好,但这是因为 $T::new 不是真正有效的。它需要是 <$T>::new,然后它编译 (playground):

macro_rules! nzvec {
    ($T:ty, $($x:expr),* ) => {
        vec![$(<$T>::new($x).unwrap()),*]
    }
}