Skip to content

Commit 295dab6

Browse files
ehusstraviscross
authored andcommitted
Change underscore to be a keyword
This changes underscore from being a punctuation character to a keyword. This is intended to help better align with proc-macros, which treat it as an [`Ident`](https://doc.rust-lang.org/proc_macro/struct.Ident.html). Note one unusual rule is inline assembly `ParamName` which is `IDENTIFIER_OR_KEYWORD`. From what I can tell, it does accept `_`, but the fmt template does not. Templates are not specified in great detail in the std docs, and don't touch on this fact. Closes #1236 Closes #2020
1 parent a6d3c39 commit 295dab6

File tree

4 files changed

+13
-19
lines changed

4 files changed

+13
-19
lines changed

src/identifiers.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ 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 _except `crate`, `self`, `super`, `Self`, `_`_
1513
1614
NON_KEYWORD_IDENTIFIER -> IDENTIFIER_OR_KEYWORD _except a [strict][lex.keywords.strict] or [reserved][lex.keywords.reserved] keyword_
1715
@@ -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

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: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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,15 +762,14 @@ 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 _except `crate`, `self`, `super`, `Self`, `_` and not immediately followed by `'`_
774773
775774
RESERVED_RAW_LIFETIME -> `'r#_` _not immediately followed by `'`_
776775
```
@@ -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]
@@ -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]

0 commit comments

Comments
 (0)