保留语法
概要
any_identifier#
,any_identifier"..."
,any_identifier'...'
和'any_identifier#
现在是保留语法,不再进行词法分析。- 这主要与宏相关。例如,
quote!{ #a#b }
不再被接受。 - 它不会特殊对待关键字,因此,例如,
match"..." {}
不再被接受。 - 在标识符和随后的
#
、"
或'
之间插入空格以避免错误。 - 版本迁移将帮助您在这些情况下插入空格。
详情
为了在未来为新语法腾出空间,我们决定保留前缀标识符、字面量和生命周期的语法:prefix#identifier
,prefix"string"
,prefix'c'
,prefix#123
和 'prefix#
,其中 prefix
可以是任何标识符。(除了那些已经有含义的前缀,例如 b'...'
(字节字符)和 r"..."
(原始字符串)。)
这提供了我们未来可以扩展的语法,而无需版本边界。我们可能会在下一个版本之前将此用于临时语法,或者在适当的情况下用于永久语法。
如果没有版本,这将是一个重大更改,因为宏当前可以接受诸如 hello"world"
之类的语法,它们会将其视为两个单独的标记:hello
和 "world"
。不过,(自动)修复很简单:只需插入一个空格:hello "world"
。同样,prefix#ident
应该变成 prefix #ident
。版本迁移将帮助进行此修复。
除了将这些变成词法分析错误之外,RFC 尚未为任何前缀附加含义。将含义分配给特定前缀留给未来的提案,这些提案现在 - 由于保留了这些前缀 - 不会是重大更改。
您未来可能会看到的一些新前缀(尽管我们尚未承诺使用任何前缀)
-
k#keyword
允许编写当前版本中尚不存在的关键字。例如,虽然async
在 2015 版本中不是关键字,但此前缀将允许我们在 2015 版本中接受k#async
,而无需等待 2018 版本将async
保留为关键字。 -
f""
作为格式化字符串的简写。例如,f"hello {name}"
作为等效的format!()
调用的简写。 -
s""
用于String
字面量。
迁移
作为 2021 版本的一部分,添加了一个迁移 lint,rust_2021_prefixes_incompatible_syntax
,以帮助将 Rust 2018 代码库自动迁移到 Rust 2021。
为了将您的代码迁移为与 Rust 2021 版本兼容,请运行
cargo fix --edition
如果您想或需要手动迁移代码,迁移非常简单。
假设您有一个像这样定义的宏
#![allow(unused)] fn main() { macro_rules! my_macro { ($a:tt $b:tt) => {}; } }
在 Rust 2015 和 2018 中,此宏可以这样调用,第一个标记树和第二个标记树之间没有空格,这是合法的
my_macro!(z"hey");
Rust 2021 中不再允许此 z
前缀,因此为了调用此宏,您必须在前缀后添加一个空格,如下所示
my_macro!(z "hey");