为什么负整数不是宏中的有效模式?

时间:2017-07-04 16:10:55

标签: macros rust pattern-matching

让我们考虑使用静态方法的简单枚举实现,该方法检查值是否具有关联值(此处不考虑实现的效率):

enum Letter {
    Alpha = -1,
    A = 0,
    B = 1,
    C = 2,
}

impl Letter {
    pub fn in_enum(value: isize) -> bool
    {
        match value {
            -1 => true,
            0 => true,
            1 => true,
            2 => true,
            _ => false,
        }
    }
}

现在,让我们编写一个宏来构建具有等效in_enum方法的枚举。下面的宏是根据enum deserialization as numbers的Serde指南的一些指导写的,其中也会出现枚举变量值的匹配。

macro_rules! my_enum {
    ($name:ident { $($variant:ident = $value:expr, )* }) => {
        #[derive(Clone, Copy, Debug, Eq, PartialEq)]
        pub enum $name {
            $($variant = $value,)*
        }

        impl $name {
            pub fn in_enum(value: isize) -> bool
            {
                match value {
                    $( $value => true, )*
                    _ => false,
                }
            }
        }
    }
}

my_enum!(Letter {
  Alpha = -1,
  A = 0,
  B = 1,
  C = 2,
});

Playground。 现在,编译器不会接受带有负整数的变体。

error: expected pattern, found `-1`
  --> src/main.rs:13:24
   |
13 |                     $( $value => true, )*
   |                        ^^^^^^

无论我如何在宏中编写此模式,或者我是否使用i32isize作为value方法参数,这似乎都会发生。将$value的片段说明符更改为pat也是不可能的:即使没有负变量值,编译器也会拒绝构建枚举。

error: expected expression, found `-1`
 --> src/main.rs:5:26
  |
5 |             $($variant = $value,)*
  |                          ^^^^^^

令人惊讶的是,它在不使用宏的情况下工作,以及当我丢弃Alpha变体时。

为什么会这样?

1 个答案:

答案 0 :(得分:5)

截至今天(2017年7月5日),这是a bug in the compiler并且已经fixed in the nightly version