diff --git a/src/identifiers.md b/src/identifiers.md
index f34ae482e..a10a3f9f3 100644
--- a/src/identifiers.md
+++ b/src/identifiers.md
@@ -14,6 +14,8 @@ r[ident.syntax]
>
> IDENTIFIER :\
> NON_KEYWORD_IDENTIFIER | RAW_IDENTIFIER
+>
+> RESERVED_RAW_IDENTIFIER : `r#_`
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
diff --git a/src/tokens.md b/src/tokens.md
index fe2b5534f..212d678df 100644
--- a/src/tokens.md
+++ b/src/tokens.md
@@ -758,10 +758,19 @@ r[lex.token.life.syntax]
> `'` [IDENTIFIER_OR_KEYWORD][identifier]
> _(not immediately followed by `'`)_\
> | `'_`
-> _(not immediately followed by `'`)_
+> _(not immediately followed by `'`)_\
+> | RAW_LIFETIME
>
> LIFETIME_OR_LABEL :\
> `'` [NON_KEYWORD_IDENTIFIER][identifier]
+> _(not immediately followed by `'`)_\
+> | RAW_LIFETIME
+>
+> RAW_LIFETIME :\
+> `'r#` [IDENTIFIER_OR_KEYWORD][identifier] *Except `crate`, `self`, `super`, `Self`*
+> _(not immediately followed by `'`)_
+>
+> RESERVED_RAW_LIFETIME : `'r#_`
> _(not immediately followed by `'`)_
r[lex.token.life.intro]
@@ -769,6 +778,19 @@ 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]
> **Lexer 2021+**\
> RESERVED_TOKEN_DOUBLE_QUOTE : ( IDENTIFIER_OR_KEYWORD _Except `b` or `c` or `r` or `br` or `cr`_ | `_` ) `"`\
> RESERVED_TOKEN_SINGLE_QUOTE : ( IDENTIFIER_OR_KEYWORD _Except `b`_ | `_` ) `'`\
-> RESERVED_TOKEN_POUND : ( IDENTIFIER_OR_KEYWORD _Except `r` or `br` or `cr`_ | `_` ) `#`
+> RESERVED_TOKEN_POUND : ( IDENTIFIER_OR_KEYWORD _Except `r` or `br` or `cr`_ | `_` ) `#`\
+> RESERVED_TOKEN_LIFETIME : `'` (IDENTIFIER_OR_KEYWORD _Except `r`_ | _) `#`
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