代码之家  ›  专栏  ›  技术社区  ›  at54321

__rust_force_expr到底做什么?

  •  2
  • at54321  · 技术社区  · 4 年前

    我在看 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
        };
    }
    

    有人能进一步了解它的确切作用吗?

    0 回复  |  直到 4 年前
        1
  •  5
  •   smitop    4 年前

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

    添加此项以改进的特定错误是用于 vec![] 在模式匹配中,这是无效的(不能在 Vec ):

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

    结果在

    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)
    

    这是一个相当令人困惑的错误,尤其是在使用 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)
    

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