__rust_force_expr 到底是做什么的?

at5*_*321 9 macros abstract-syntax-tree rust

我正在查看vec![]Rust 中的宏实现,并注意到它使用了__rust_force_expr!宏。这是后者的实现:

/// Force AST node to an expression to improve diagnostics in pattern position.
#[doc(hidden)]
#[macro_export]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
macro_rules! __rust_force_expr {
    ($e:expr) => {
        $e
    };
}
Run Code Online (Sandbox Code Playgroud)

有人可以更深入地了解它到底是做什么的吗?

loo*_*ops 9

它没有关于如何使用宏的任何结果,它仅用于在宏使用不正确时通过告诉编译器宏的输出始终是单个表达式,而不是项目或项目来提高错误消息的质量。多个表达式。

添加此功能以改进的具体错误是vec![]在模式匹配中使用,这是无效的(您无法在结构上匹配Vec):

let x: Option<Vec<i32>> = Some(vec![]);
match x {
    Some(my_vec![]) => println!("1"),
    _ => println!("2"),
};
Run Code Online (Sandbox Code Playgroud)

结果是

error[E0164]: expected tuple struct or tuple variant, found associated function `Vec::new`
  --> src/main.rs:9:9
   |
9  |         Vec::new()
   |         ^^^^^^^^^^ `fn` calls are not allowed in patterns
...
15 |     Some(my_vec![]) => println!("1"),
   |          --------- in this macro invocation
   |
   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
   = note: this error originates in the macro `mvec` (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)

这是一个相当令人困惑的错误,尤其是在使用vec![1, 2, 3]语法时。看起来调用者中没有任何函数调用。vec!但是通过包装的主体__rust_force_expr,我们得到了一个更好的错误:

error: arbitrary expressions aren't allowed in patterns
  --> src/main.rs:15:10
   |
15 |     Some(vec![]) => println!("1"),
   |          ^^^^^^
   |
   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)

这更有意义:vec![]生成一个表达式,并且没有对宏后面的函数调用的引用。