diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 971ce96..5856921 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -31,6 +31,7 @@ - [Disjoint capture in closures](rust-2021/disjoint-capture-in-closures.md) - [Panic macro consistency](rust-2021/panic-macro-consistency.md) - [Reserved syntax](rust-2021/reserved-syntax.md) + - [Raw lifetimes](rust-2021/raw-lifetimes.md) - [Warnings promoted to errors](rust-2021/warnings-promoted-to-error.md) - [Or patterns in macro-rules](rust-2021/or-patterns-macro-rules.md) - [C-string literals](rust-2021/c-string-literals.md) diff --git a/src/rust-2021/raw-lifetimes.md b/src/rust-2021/raw-lifetimes.md new file mode 100644 index 0000000..9d00904 --- /dev/null +++ b/src/rust-2021/raw-lifetimes.md @@ -0,0 +1,47 @@ +# Raw lifetimes + +## Summary + +- `'r#ident_or_keyword` is now allowed as a lifetime, which allows using keywords such as `'r#fn`. + +## Details + +Raw lifetimes are introduced in the 2021 edition to support the ability to migrate to newer editions that introduce new keywords. This is analogous to [raw identifiers] which provide the same functionality for identifiers. For example, the 2024 edition introduced the `gen` keyword. Since lifetimes cannot be keywords, this would cause code that use a lifetime `'gen` to fail to compile. Raw lifetimes allow the migration lint to modify those lifetimes to `'r#gen` which do allow keywords. + +In editions prior to 2021, raw lifetimes are parsed as separate tokens. For example `'r#foo` is parsed as three tokens: `'r`, `#`, and `foo`. + +[raw identifiers]: ../../reference/identifiers.html#raw-identifiers + +## Migration + +As a part of the 2021 edition a migration lint, [`rust_2021_prefixes_incompatible_syntax`], has been added in order to aid in automatic migration of Rust 2018 codebases to Rust 2021. + +In order to migrate your code to be Rust 2021 Edition compatible, run: + +```sh +cargo fix --edition +``` + +Should you want or need to manually migrate your code, migration is fairly straight-forward. + +Let's say you have a macro that is defined like so: + +```rust +macro_rules! my_macro { + ($a:tt $b:tt $c:tt) => {}; +} +``` + +In Rust 2015 and 2018 it's legal for this macro to be called like so with no space between the tokens: + +```rust,ignore +my_macro!('r#foo); +``` + +In the 2021 edition, this is now parsed as a single token. In order to call this macro, you must add a space before the identifier like so: + +```rust,ignore +my_macro!('r# foo); +``` + +[`rust_2021_prefixes_incompatible_syntax`]: ../../rustc/lints/listing/allowed-by-default.html#rust-2021-prefixes-incompatible-syntax diff --git a/src/rust-2021/reserved-syntax.md b/src/rust-2021/reserved-syntax.md index 04c2b21..c8df77c 100644 --- a/src/rust-2021/reserved-syntax.md +++ b/src/rust-2021/reserved-syntax.md @@ -2,8 +2,7 @@ ## Summary -- `any_identifier#`, `any_identifier"..."`, and `any_identifier'...'` are now reserved - syntax, and no longer tokenize. +- `any_identifier#`, `any_identifier"..."`, `any_identifier'...'`, and `'any_identifier#` are now reserved syntax, and no longer tokenize. - This is mostly relevant to macros. E.g. `quote!{ #a#b }` is no longer accepted. - It doesn't treat keywords specially, so e.g. `match"..." {}` is no longer accepted. - Insert whitespace between the identifier and the subsequent `#`, `"`, or `'` @@ -13,8 +12,8 @@ ## Details To make space for new syntax in the future, -we've decided to reserve syntax for prefixed identifiers and literals: -`prefix#identifier`, `prefix"string"`, `prefix'c'`, and `prefix#123`, +we've decided to reserve syntax for prefixed identifiers, literals, and lifetimes: +`prefix#identifier`, `prefix"string"`, `prefix'c'`, `prefix#123`, and `'prefix#`, where `prefix` can be any identifier. (Except those prefixes that already have a meaning, such as `b'...'` (byte chars) and `r"..."` (raw strings).) @@ -52,7 +51,7 @@ committed to any of them yet): ## Migration -As a part of the 2021 edition a migration lint, `rust_2021_prefixes_incompatible_syntax`, has been added in order to aid in automatic migration of Rust 2018 codebases to Rust 2021. +As a part of the 2021 edition a migration lint, [`rust_2021_prefixes_incompatible_syntax`], has been added in order to aid in automatic migration of Rust 2018 codebases to Rust 2021. In order to migrate your code to be Rust 2021 Edition compatible, run: @@ -81,3 +80,5 @@ This `z` prefix is no longer allowed in Rust 2021, so in order to call this macr ```rust,ignore my_macro!(z "hey"); ``` + +[`rust_2021_prefixes_incompatible_syntax`]: ../../rustc/lints/listing/allowed-by-default.html#rust-2021-prefixes-incompatible-syntax