Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raw lifetimes #1603

Merged
merged 6 commits into from
Nov 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/identifiers.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ r[ident.syntax]
>
> IDENTIFIER :\
> NON_KEYWORD_IDENTIFIER | RAW_IDENTIFIER
>
> RESERVED_RAW_IDENTIFIER : `r#_`

<!-- When updating the version, update the UAX links, too. -->
r[ident.unicode]
@@ -71,6 +73,10 @@ r[ident.raw.allowed]
Unlike a normal identifier, a raw identifier may be any strict or reserved
keyword except the ones listed above for `RAW_IDENTIFIER`.

r[ident.raw.reserved]
It is an error to use the RESERVED_RAW_IDENTIFIER token `r#_` in order to avoid confusion with the [_WildcardPattern_].

[_WildcardPattern_]: patterns.md#wildcard-pattern
[`extern crate`]: items/extern-crates.md
[`no_mangle`]: abi.md#the-no_mangle-attribute
[`path` attribute]: items/modules.md#the-path-attribute
33 changes: 31 additions & 2 deletions src/tokens.md
Original file line number Diff line number Diff line change
@@ -758,17 +758,39 @@ r[lex.token.life.syntax]
> &nbsp;&nbsp; &nbsp;&nbsp; `'` [IDENTIFIER_OR_KEYWORD][identifier]
> _(not immediately followed by `'`)_\
> &nbsp;&nbsp; | `'_`
> _(not immediately followed by `'`)_
> _(not immediately followed by `'`)_\
> &nbsp;&nbsp; | RAW_LIFETIME
>
> LIFETIME_OR_LABEL :\
> &nbsp;&nbsp; &nbsp;&nbsp; `'` [NON_KEYWORD_IDENTIFIER][identifier]
> _(not immediately followed by `'`)_\
> &nbsp;&nbsp; | RAW_LIFETIME
>
> RAW_LIFETIME :\
> &nbsp;&nbsp; `'r#` [IDENTIFIER_OR_KEYWORD][identifier] <sub>*Except `crate`, `self`, `super`, `Self`*</sub>
> _(not immediately followed by `'`)_
>
> RESERVED_RAW_LIFETIME : `'r#_`
> _(not immediately followed by `'`)_

r[lex.token.life.intro]
Lifetime parameters and [loop labels] use LIFETIME_OR_LABEL tokens. Any
LIFETIME_TOKEN will be accepted by the lexer, and for example, can be used in
macros.

r[lex.token.life.raw.intro]
A raw lifetime is like a normal lifetime, but its identifier is prefixed by `r#`. (Note that the `r#` prefix is not included as part of the actual lifetime.)

r[lex.token.life.raw.allowed]
Unlike a normal lifetime, a raw lifetime may be any strict or reserved keyword except the ones listed above for `RAW_LIFETIME`.

r[lex.token.life.raw.reserved]
It is an error to use the RESERVED_RAW_LIFETIME token `'r#_` in order to avoid confusion with the [placeholder lifetime].

r[lex.token.life.raw.edition2021]
> **Edition differences**: Raw lifetimes are accepted in the 2021
> edition or later. In earlier additions the token `'r#lt` is lexed as `'r # lt`.

## Punctuation

r[lex.token.punct]
@@ -849,7 +871,8 @@ r[lex.token.reserved-prefix.syntax]
> **<sup>Lexer 2021+</sup>**\
> RESERVED_TOKEN_DOUBLE_QUOTE : ( IDENTIFIER_OR_KEYWORD <sub>_Except `b` or `c` or `r` or `br` or `cr`_</sub> | `_` ) `"`\
> RESERVED_TOKEN_SINGLE_QUOTE : ( IDENTIFIER_OR_KEYWORD <sub>_Except `b`_</sub> | `_` ) `'`\
> RESERVED_TOKEN_POUND : ( IDENTIFIER_OR_KEYWORD <sub>_Except `r` or `br` or `cr`_</sub> | `_` ) `#`
> RESERVED_TOKEN_POUND : ( IDENTIFIER_OR_KEYWORD <sub>_Except `r` or `br` or `cr`_</sub> | `_` ) `#`\
> RESERVED_TOKEN_LIFETIME : `'` (IDENTIFIER_OR_KEYWORD <sub>_Except `r`_</sub> | _) `#`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is isn't reserving 'r# on its own, which rustc rejects but could lex as 'r followed by #.

But I'm not sure it's worth trying to get all the RESERVED_ rules exactly right at this stage.


r[lex.token.reserved-prefix.intro]
Some lexical forms known as _reserved prefixes_ are reserved for future use.
@@ -863,6 +886,9 @@ Note that raw identifiers, raw string literals, and raw byte string literals may
r[lex.token.reserved-prefix.strings]
Similarly the `r`, `b`, `br`, `c`, and `cr` prefixes used in raw string literals, byte literals, byte string literals, raw byte string literals, C string literals, and raw C string literals are not interpreted as reserved prefixes.

r[lex.token.reserved-prefix.life]
Source input which would otherwise be lexically interpreted as a non-raw lifetime (or a keyword or `_`) which is immediately followed by a `#` character (without intervening whitespace) is identified as a reserved lifetime prefix.

r[lex.token.reserved-prefix.edition2021]
> **Edition differences**: Starting with the 2021 edition, reserved prefixes are reported as an error by the lexer (in particular, they cannot be passed to macros).
>
@@ -875,6 +901,7 @@ r[lex.token.reserved-prefix.edition2021]
> lexes!{continue 'foo}
> lexes!{match "..." {}}
> lexes!{r#let#foo} // three tokens: r#let # foo
> lexes!{'prefix #lt}
> ```
>
> Examples accepted before the 2021 edition but rejected later:
@@ -883,6 +910,7 @@ r[lex.token.reserved-prefix.edition2021]
> lexes!{a#foo}
> lexes!{continue'foo}
> lexes!{match"..." {}}
> lexes!{'prefix#lt}
> ```

[Inferred types]: types/inferred.md
@@ -924,6 +952,7 @@ r[lex.token.reserved-prefix.edition2021]
[numeric types]: types/numeric.md
[paths]: paths.md
[patterns]: patterns.md
[placeholder lifetime]: lifetime-elision.md
[question]: expressions/operator-expr.md#the-question-mark-operator
[range]: expressions/range-expr.md
[rangepat]: patterns.md#range-patterns