Skip to content

Commit 8a2075a

Browse files
committed
Model the pr131656 restriction on e-suffixes
This adds two more reserved forms to reject the things that rustc currently rejects.
1 parent b22b9ba commit 8a2075a

File tree

4 files changed

+64
-4
lines changed

4 files changed

+64
-4
lines changed

src/lex_via_peg/pretokenisation/pest_pretokeniser.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@ fn interpret_pest_pair(pair: Pair<Rule>) -> Result<PretokenData, &'static str> {
192192
suffix: suffix.map(Into::into),
193193
})
194194
}
195-
Rule::Reserved_float_empty_exponent | Rule::Reserved_float_based => {
196-
Ok(PretokenData::Reserved)
197-
}
195+
Rule::Reserved_float_empty_exponent
196+
| Rule::Reserved_float_based
197+
| Rule::Reserved_float_e_suffix_restriction
198+
| Rule::Reserved_integer_e_suffix_restriction => Ok(PretokenData::Reserved),
198199
Rule::Integer_literal => {
199200
let mut base = None;
200201
let mut digits = None;

src/lex_via_peg/pretokenisation/pretokenise.pest

+21
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ PRETOKEN_2015 = {
1010
Unterminated_literal_2015 |
1111
Float_literal_1 |
1212
Reserved_float_empty_exponent |
13+
Reserved_float_e_suffix_restriction |
1314
Float_literal_2 |
1415
Reserved_float_based |
16+
Reserved_integer_e_suffix_restriction |
1517
Integer_literal |
1618
Lifetime_or_label |
1719
Raw_identifier |
@@ -31,8 +33,10 @@ PRETOKEN_2021 = {
3133
Reserved_literal_2021 |
3234
Float_literal_1 |
3335
Reserved_float_empty_exponent |
36+
Reserved_float_e_suffix_restriction |
3437
Float_literal_2 |
3538
Reserved_float_based |
39+
Reserved_integer_e_suffix_restriction |
3640
Integer_literal |
3741
Raw_lifetime_or_label_2021 |
3842
Reserved_lifetime_or_label_prefix_2021 |
@@ -55,8 +59,10 @@ PRETOKEN_2024 = {
5559
Reserved_guard_2024 |
5660
Float_literal_1 |
5761
Reserved_float_empty_exponent |
62+
Reserved_float_e_suffix_restriction |
5863
Float_literal_2 |
5964
Reserved_float_based |
65+
Reserved_integer_e_suffix_restriction |
6066
Integer_literal |
6167
Raw_lifetime_or_label_2021 |
6268
Reserved_lifetime_or_label_prefix_2021 |
@@ -168,6 +174,8 @@ DECIMAL_DIGITS = { ('0'..'9' | "_") * }
168174
HEXADECIMAL_DIGITS = { ('0'..'9' | 'a' .. 'f' | 'A' .. 'F' | "_") * }
169175
LOW_BASE_PRETOKEN_DIGITS = { DECIMAL_DIGITS }
170176
DECIMAL_PART = { '0'..'9' ~ DECIMAL_DIGITS }
177+
178+
RESTRICTED_E_SUFFIX = { ("e"|"E") ~ "_"+ ~ !XID_START ~ XID_CONTINUE }
171179
// ANCHOR_END: numeric_common
172180

173181

@@ -200,6 +208,10 @@ Reserved_float_empty_exponent = {
200208
DECIMAL_PART ~ ("." ~ DECIMAL_PART ) ? ~
201209
("e"|"E") ~ ("+"|"-")
202210
}
211+
Reserved_float_e_suffix_restriction = {
212+
DECIMAL_PART ~ "." ~ DECIMAL_PART ~
213+
RESTRICTED_E_SUFFIX
214+
}
203215
Reserved_float_based = {
204216
(
205217
("0b" | "0o") ~ LOW_BASE_PRETOKEN_DIGITS |
@@ -211,6 +223,15 @@ Reserved_float_based = {
211223
}
212224
// ANCHOR_END: reserved_float
213225

226+
// ANCHOR: reserved_integer
227+
Reserved_integer_e_suffix_restriction = {
228+
( INTEGER_BINARY_LITERAL |
229+
INTEGER_OCTAL_LITERAL |
230+
INTEGER_DECIMAL_LITERAL ) ~
231+
RESTRICTED_E_SUFFIX
232+
}
233+
// ANCHOR_END: reserved_integer
234+
214235
// ANCHOR: integer_literals
215236
Integer_literal = {
216237
( INTEGER_BINARY_LITERAL |

writeup/numeric_literal_pretokens.md

+20
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@ The following nonterminals are common to the definitions below:
4747
> Note: The `Reserved_float_empty_exponent` pretoken nonterminal is placed between `Float_literal_1` and `Float_literal_2` in priority order.
4848
> This ordering makes sure that forms like `123.4e+` are reserved, rather than being accepted by `FLOAT_BODY_WITHOUT_EXPONENT`).
4949
50+
> See [e-suffix-restriction] for discussion of `Reserved_float_e_suffix_restriction`.
51+
52+
53+
#### Reserved integer { .rule }
54+
55+
##### Grammar
56+
```
57+
{{#include pretokenise_anchored.pest:reserved_integer}}
58+
```
59+
60+
##### Pretoken kind
61+
`Reserved`
62+
63+
##### Attributes
64+
(none)
65+
66+
See [e-suffix-restriction] for discussion.
67+
68+
5069
#### Integer literal { .rule }
5170

5271
##### Grammar
@@ -85,3 +104,4 @@ The <var>base</var> attribute is determined from the following table, depending
85104
> - `0x·` (which is rejected, not accepted as `0` with suffix ``)
86105
87106
[rfc0879]: https://github.com/rust-lang/rfcs/pull/0879
107+
[e-suffix-restriction]: rustc_oddities.md#e-suffix-restriction

writeup/rustc_oddities.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,29 @@ The grammar production in the Reference seems to be written to assume that these
3535
I haven't seen any discussion of whether this rustc behaviour is considered desirable.
3636

3737

38+
### Restriction on e-suffixes { #e-suffix-restriction }
39+
40+
With the implementation of [pr131656] as of 2025-04-27,
41+
support for numeric literal suffixes beginning with `e` or `E` is incomplete,
42+
and rejects some (very obscure) cases.
43+
44+
A numeric literal token is rejected if:
45+
- it doesn't have an exponent; and
46+
- it has a suffix of the following form:
47+
- begins with <b>e</b> or <b>E</b>
48+
- immediately followed by one or more <b>_</b> characters
49+
- immediately followed by a character which has the `XID_Continue` property but not `XID_Start`.
50+
51+
For example, `123e_·` is rejected.
52+
53+
The `Reserved_float_e_suffix_restriction` and `Reserved_integer_e_suffix_restriction` nonterminals describe this restriction in the grammar.
54+
55+
3856
[playground-lifetime]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=31fc06e4d678e1a38d8d39f521e8a11c
3957
[playground-ident]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=aad27eb75b2774f16fc6b0981b770d56
4058

4159
[rfc2457]: https://rust-lang.github.io/rfcs/2457-non-ascii-idents.html
4260

4361
[#126759]: https://github.com/rust-lang/rust/issues/126759
44-
62+
[pr131656]: https://github.com/rust-lang/rust/pull/131656
4563

0 commit comments

Comments
 (0)