宏片段指定符

概要

  • 现在 expr 片段指定符 也支持 const_ 表达式。
  • 为了向后兼容,添加了 expr_2021 片段指定符。

详情

随着 Rust 添加新语法,为了保持向后兼容性,有时不允许现有的 macro_rules 片段指定符匹配新语法。 在旧的片段指定符中支持新语法有时会推迟到下一个版本,这为更新它们提供了机会。

事实上,const 表达式 在 1.79 版本中添加,而 _ 表达式 在 1.59 版本中添加时,就发生了这种情况。 在 2021 版本及更早版本中,expr 片段指定符匹配这些表达式。 这是因为您可能会遇到如下场景:

macro_rules! example {
    ($e:expr) => { println!("first rule"); };
    (const $e:expr) => { println!("second rule"); };
}

fn main() {
    example!(const { 1 + 1 });
}

在这里,在 2021 版本中,宏将匹配第二个规则。 如果早期版本更改了 expr 以匹配新引入的 const 表达式,那么它将匹配第一个规则,这将是一个破坏性更改。

在 2024 版本中,expr 指定符现在也匹配 const_ 表达式。 为了支持旧的行为,添加了 expr_2021 片段指定符,它匹配新的表达式。

迁移

edition_2024_expr_fragment_specifier lint 将把所有 expr 指定符的使用更改为 expr_2021,以确保现有宏的行为不会改变。 该 lint 是 rust-2024-compatibility lint 组的一部分,该组包含在自动版本迁移中。 为了迁移您的代码以兼容 Rust 2024 版本,请运行

cargo fix --edition

大多数情况下,您可能希望保留 expr 指定符,以便支持新的表达式。 您需要审查您的宏,以确定是否还有其他规则会与 const_ 匹配,并确定是否存在冲突。 如果您想要新的行为,只需撤消 lint 所做的任何更改。

或者,您可以手动启用 lint,以查找可能需要更新 expr 指定符的宏。

#![allow(unused)]
fn main() {
// Add this to the root of your crate to do a manual migration.
#![warn(edition_2024_expr_fragment_specifier)]
}