这个Rust宏有什么问题?

时间:2017-12-02 09:00:02

标签: macros rust

我正在尝试编写一个宏,通过将类型包装在某个变体中来为枚举生成From impl。

我想出了这个:

macro_rules! variant_derive_from {
    ($enum:ty:$variant:ident($from:ty)) => {
        impl From<$from> for $enum {
            fn from(thing: $from) -> $enum { return $enum::$variant(thing) }
        }
    };
}

但是,每当我尝试实际使用此宏时,我都会收到以下错误:

error: expected expression, found `B`
|             fn from(thing: $from) -> $enum { $enum::$variant(thing) }
|                                               ^^^^

我无法弄清楚为什么会发生这种情况,所以我运行了一个带有宏跟踪的构建,宏显然扩展为以下(虚拟类型,当然):

impl From < A > for B { fn from ( thing : A ) -> B { B :: AVariant ( thing ) } }

将此直接粘贴到代码中时,它会成功编译。是什么给了??

Here's a full example of the error.

1 个答案:

答案 0 :(得分:2)

ty占位符仅作为类型,而不是名称空间。使用ident代替您的示例应该可以正常工作。

ident不接受path s(&#34; foo::Bar&#34;)虽然(并且使用path也不接受$enum:ident $(:: $enum_path:ident)*似乎在这种情况下工作);您应该能够通过手动构建匹配此类的路径来解决此问题:$enum $(:: $enum_path)*(使用它如下:{{1}})。