宏片段指定符
概要
- 现在
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)] }