Skip to content

Commit cd8d3d5

Browse files
authored
Merge pull request #2049 from ehuss/underscore-keyword
Change underscore to be a keyword
2 parents a6d3c39 + 0234184 commit cd8d3d5

File tree

4 files changed

+20
-27
lines changed

4 files changed

+20
-27
lines changed

src/identifiers.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@ r[ident]
33

44
r[ident.syntax]
55
```grammar,lexer
6-
IDENTIFIER_OR_KEYWORD ->
7-
XID_Start XID_Continue*
8-
| `_` XID_Continue+
6+
IDENTIFIER_OR_KEYWORD -> ( XID_Start | `_` ) XID_Continue*
97
108
XID_Start -> <`XID_Start` defined by Unicode>
119
1210
XID_Continue -> <`XID_Continue` defined by Unicode>
1311
14-
RAW_IDENTIFIER -> `r#` IDENTIFIER_OR_KEYWORD _except `crate`, `self`, `super`, `Self`_
12+
RAW_IDENTIFIER -> `r#` IDENTIFIER_OR_KEYWORD
1513
1614
NON_KEYWORD_IDENTIFIER -> IDENTIFIER_OR_KEYWORD _except a [strict][lex.keywords.strict] or [reserved][lex.keywords.reserved] keyword_
1715
1816
IDENTIFIER -> NON_KEYWORD_IDENTIFIER | RAW_IDENTIFIER
1917
20-
RESERVED_RAW_IDENTIFIER -> `r#_`
18+
RESERVED_RAW_IDENTIFIER -> `r#` (`_` | `crate` | `self` | `Self` | `super`)
2119
```
2220

2321
<!-- When updating the version, update the UAX links, too. -->
@@ -37,8 +35,6 @@ The profile used from UAX #31 is:
3735
* Continue := [`XID_Continue`]
3836
* Medial := empty
3937

40-
with the additional constraint that a single underscore character is not an identifier.
41-
4238
> [!NOTE]
4339
> Identifiers starting with an underscore are typically used to indicate an identifier that is intentionally unused, and will silence the unused warning in `rustc`.
4440
@@ -76,7 +72,7 @@ Unlike a normal identifier, a raw identifier may be any strict or reserved
7672
keyword except the ones listed above for `RAW_IDENTIFIER`.
7773

7874
r[ident.raw.reserved]
79-
It is an error to use the [RESERVED_RAW_IDENTIFIER] token `r#_` in order to avoid confusion with the [WildcardPattern].
75+
It is an error to use the [RESERVED_RAW_IDENTIFIER] token.
8076

8177
[`extern crate`]: items/extern-crates.md
8278
[`no_mangle`]: abi.md#the-no_mangle-attribute

src/keywords.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ be used as the names of:
2626
r[lex.keywords.strict.list]
2727
The following keywords are in all editions:
2828

29+
- `_`
2930
- `as`
3031
- `async`
3132
- `await`

src/macros-by-example.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ MacroMatcher ->
2525
MacroMatch ->
2626
Token _except `$` and [delimiters][lex.token.delim]_
2727
| MacroMatcher
28-
| `$` ( IDENTIFIER_OR_KEYWORD _except `crate`_ | RAW_IDENTIFIER | `_` ) `:` MacroFragSpec
28+
| `$` ( IDENTIFIER_OR_KEYWORD _except `crate`_ | RAW_IDENTIFIER ) `:` MacroFragSpec
2929
| `$` `(` MacroMatch+ `)` MacroRepSep? MacroRepOp
3030
3131
MacroFragSpec ->
@@ -134,7 +134,7 @@ Valid fragment specifiers are:
134134
* `block`: a [BlockExpression]
135135
* `expr`: an [Expression]
136136
* `expr_2021`: an [Expression] except [UnderscoreExpression] and [ConstBlockExpression] (see [macro.decl.meta.edition2024])
137-
* `ident`: an [IDENTIFIER_OR_KEYWORD], [RAW_IDENTIFIER], or [`$crate`]
137+
* `ident`: an [IDENTIFIER_OR_KEYWORD] except `_`, [RAW_IDENTIFIER], or [`$crate`]
138138
* `item`: an [Item]
139139
* `lifetime`: a [LIFETIME_TOKEN]
140140
* `literal`: matches `-`<sup>?</sup>[LiteralExpression]

src/tokens.md

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ r[lex.token]
44
r[lex.token.syntax]
55
```grammar,lexer
66
Token ->
7-
IDENTIFIER_OR_KEYWORD
7+
RESERVED_TOKEN
88
| RAW_IDENTIFIER
99
| CHAR_LITERAL
1010
| STRING_LITERAL
@@ -18,7 +18,7 @@ Token ->
1818
| FLOAT_LITERAL
1919
| LIFETIME_TOKEN
2020
| PUNCTUATION
21-
| RESERVED_TOKEN
21+
| IDENTIFIER_OR_KEYWORD
2222
```
2323

2424
r[lex.token.intro]
@@ -116,7 +116,7 @@ A suffix is a sequence of characters following the primary part of a literal (wi
116116

117117
r[lex.token.literal.suffix.syntax]
118118
```grammar,lexer
119-
SUFFIX -> IDENTIFIER_OR_KEYWORD
119+
SUFFIX -> IDENTIFIER_OR_KEYWORD _except `_`_
120120
121121
SUFFIX_NO_E -> SUFFIX _not beginning with `e` or `E`_
122122
```
@@ -762,17 +762,16 @@ r[lex.token.life.syntax]
762762
```grammar,lexer
763763
LIFETIME_TOKEN ->
764764
`'` IDENTIFIER_OR_KEYWORD _not immediately followed by `'`_
765-
| `'_` _not immediately followed by `'`_
766765
| RAW_LIFETIME
767766
768767
LIFETIME_OR_LABEL ->
769768
`'` NON_KEYWORD_IDENTIFIER _not immediately followed by `'`_
770769
| RAW_LIFETIME
771770
772771
RAW_LIFETIME ->
773-
`'r#` IDENTIFIER_OR_KEYWORD _except `crate`, `self`, `super`, `Self` and not immediately followed by `'`_
772+
`'r#` IDENTIFIER_OR_KEYWORD _not immediately followed by `'`_
774773
775-
RESERVED_RAW_LIFETIME -> `'r#_` _not immediately followed by `'`_
774+
RESERVED_RAW_LIFETIME -> `'r#` (`_` | `crate` | `self` | `Self` | `super`) _not immediately followed by `'`_
776775
```
777776

778777
r[lex.token.life.intro]
@@ -787,7 +786,7 @@ r[lex.token.life.raw.allowed]
787786
Unlike a normal lifetime, a raw lifetime may be any strict or reserved keyword except the ones listed above for `RAW_LIFETIME`.
788787

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

792791
r[lex.token.life.raw.edition2021]
793792
> [!EDITION-2021]
@@ -845,7 +844,6 @@ PUNCTUATION ->
845844
| `#`
846845
| `$`
847846
| `?`
848-
| `_`
849847
| `{`
850848
| `}`
851849
| `[`
@@ -891,7 +889,6 @@ usages and meanings are defined in the linked pages.
891889
| `>=` | Ge | [Greater than or equal to][comparison], [Generics]
892890
| `<=` | Le | [Less than or equal to][comparison]
893891
| `@` | At | [Subpattern binding]
894-
| `_` | Underscore | [Wildcard patterns], [Inferred types], Unnamed items in [constants], [extern crates], [use declarations], and [destructuring assignment]
895892
| `.` | Dot | [Field access][field], [Tuple index]
896893
| `..` | DotDot | [Range][range], [Struct expressions], [Patterns], [Range Patterns][rangepat]
897894
| `...` | DotDotDot | [Variadic functions][extern], [Range patterns]
@@ -925,7 +922,7 @@ r[lex.token.reserved]
925922
## Reserved tokens
926923

927924
r[lex.token.reserved.intro]
928-
Several token forms are reserved for future use. It is an error for the source input to match one of these forms.
925+
Several token forms are reserved for future use or to avoid confusion. It is an error for the source input to match one of these forms.
929926

930927
r[lex.token.reserved.syntax]
931928
```grammar,lexer
@@ -947,23 +944,23 @@ r[lex.token.reserved-prefix]
947944
r[lex.token.reserved-prefix.syntax]
948945
```grammar,lexer
949946
RESERVED_TOKEN_DOUBLE_QUOTE ->
950-
( IDENTIFIER_OR_KEYWORD _except `b` or `c` or `r` or `br` or `cr`_ | `_` ) `"`
947+
IDENTIFIER_OR_KEYWORD _except `b` or `c` or `r` or `br` or `cr`_ `"`
951948
952949
RESERVED_TOKEN_SINGLE_QUOTE ->
953-
( IDENTIFIER_OR_KEYWORD _except `b`_ | `_` ) `'`
950+
IDENTIFIER_OR_KEYWORD _except `b`_ `'`
954951
955952
RESERVED_TOKEN_POUND ->
956-
( IDENTIFIER_OR_KEYWORD _except `r` or `br` or `cr`_ | `_` ) `#`
953+
IDENTIFIER_OR_KEYWORD _except `r` or `br` or `cr`_ `#`
957954
958955
RESERVED_TOKEN_LIFETIME ->
959-
`'` ( IDENTIFIER_OR_KEYWORD _except `r`_ | `_` ) `#`
956+
`'` IDENTIFIER_OR_KEYWORD _except `r`_ `#`
960957
```
961958

962959
r[lex.token.reserved-prefix.intro]
963960
Some lexical forms known as _reserved prefixes_ are reserved for future use.
964961

965962
r[lex.token.reserved-prefix.id]
966-
Source input which would otherwise be lexically interpreted as a non-raw identifier (or a keyword or `_`) which is immediately followed by a `#`, `'`, or `"` character (without intervening whitespace) is identified as a reserved prefix.
963+
Source input which would otherwise be lexically interpreted as a non-raw identifier (or a keyword) which is immediately followed by a `#`, `'`, or `"` character (without intervening whitespace) is identified as a reserved prefix.
967964

968965
r[lex.token.reserved-prefix.raw-token]
969966
Note that raw identifiers, raw string literals, and raw byte string literals may contain a `#` character but are not interpreted as containing a reserved prefix.
@@ -972,7 +969,7 @@ r[lex.token.reserved-prefix.strings]
972969
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.
973970

974971
r[lex.token.reserved-prefix.life]
975-
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.
972+
Source input which would otherwise be lexically interpreted as a non-raw lifetime (or a keyword) which is immediately followed by a `#` character (without intervening whitespace) is identified as a reserved lifetime prefix.
976973

977974
r[lex.token.reserved-prefix.edition2021]
978975
> [!EDITION-2021]
@@ -1061,7 +1058,6 @@ r[lex.token.reserved-guards.edition2024]
10611058
[numeric types]: types/numeric.md
10621059
[paths]: paths.md
10631060
[patterns]: patterns.md
1064-
[placeholder lifetime]: lifetime-elision.md
10651061
[question]: expressions/operator-expr.md#the-try-propagation-expression
10661062
[range]: expressions/range-expr.md
10671063
[rangepat]: patterns.md#range-patterns

0 commit comments

Comments
 (0)