Skip to content

Commit 8ed0384

Browse files
authored
Rollup merge of rust-lang#105161 - cassaundra:numeric-literal-error, r=nnethercote
Refine when invalid prefix case error arises Fix cases where the "invalid base prefix for number literal" error arises with suffixes that look erroneously capitalized but which are actually invalid.
2 parents a270aee + 52a9280 commit 8ed0384

File tree

3 files changed

+107
-10
lines changed

3 files changed

+107
-10
lines changed

compiler/rustc_session/src/errors.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,20 +291,33 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
291291
s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
292292
}
293293

294-
// Try to lowercase the prefix if it's a valid base prefix.
295-
fn fix_base_capitalisation(s: &str) -> Option<String> {
296-
if let Some(stripped) = s.strip_prefix('B') {
297-
Some(format!("0b{stripped}"))
298-
} else if let Some(stripped) = s.strip_prefix('O') {
299-
Some(format!("0o{stripped}"))
300-
} else if let Some(stripped) = s.strip_prefix('X') {
301-
Some(format!("0x{stripped}"))
294+
// Try to lowercase the prefix if the prefix and suffix are valid.
295+
fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option<String> {
296+
let mut chars = suffix.chars();
297+
298+
let base_char = chars.next().unwrap();
299+
let base = match base_char {
300+
'B' => 2,
301+
'O' => 8,
302+
'X' => 16,
303+
_ => return None,
304+
};
305+
306+
// check that the suffix contains only base-appropriate characters
307+
let valid = prefix == "0"
308+
&& chars
309+
.filter(|c| *c != '_')
310+
.take_while(|c| *c != 'i' && *c != 'u')
311+
.all(|c| c.to_digit(base).is_some());
312+
313+
if valid {
314+
Some(format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
302315
} else {
303316
None
304317
}
305318
}
306319

307-
let token::Lit { kind, suffix, .. } = lit;
320+
let token::Lit { kind, symbol, suffix, .. } = lit;
308321
match err {
309322
// `LexerError` is an error, but it was already reported
310323
// by lexer, so here we don't report it the second time.
@@ -320,7 +333,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
320333
if looks_like_width_suffix(&['i', 'u'], suf) {
321334
// If it looks like a width, try to be helpful.
322335
sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
323-
} else if let Some(fixed) = fix_base_capitalisation(suf) {
336+
} else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
324337
sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
325338
} else {
326339
sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Checks that integers with seeming uppercase base prefixes do not get bogus capitalization
2+
// suggestions.
3+
4+
fn main() {
5+
_ = 123X1a3;
6+
//~^ ERROR invalid suffix `X1a3` for number literal
7+
//~| NOTE invalid suffix `X1a3`
8+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
9+
10+
_ = 456O123;
11+
//~^ ERROR invalid suffix `O123` for number literal
12+
//~| NOTE invalid suffix `O123`
13+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
14+
15+
_ = 789B101;
16+
//~^ ERROR invalid suffix `B101` for number literal
17+
//~| NOTE invalid suffix `B101`
18+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
19+
20+
_ = 0XYZ;
21+
//~^ ERROR invalid suffix `XYZ` for number literal
22+
//~| NOTE invalid suffix `XYZ`
23+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
24+
25+
_ = 0OPQ;
26+
//~^ ERROR invalid suffix `OPQ` for number literal
27+
//~| NOTE invalid suffix `OPQ`
28+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
29+
30+
_ = 0BCD;
31+
//~^ ERROR invalid suffix `BCD` for number literal
32+
//~| NOTE invalid suffix `BCD`
33+
//~| HELP the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
34+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: invalid suffix `X1a3` for number literal
2+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:5:9
3+
|
4+
LL | _ = 123X1a3;
5+
| ^^^^^^^ invalid suffix `X1a3`
6+
|
7+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
8+
9+
error: invalid suffix `O123` for number literal
10+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:10:9
11+
|
12+
LL | _ = 456O123;
13+
| ^^^^^^^ invalid suffix `O123`
14+
|
15+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
16+
17+
error: invalid suffix `B101` for number literal
18+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:15:9
19+
|
20+
LL | _ = 789B101;
21+
| ^^^^^^^ invalid suffix `B101`
22+
|
23+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
24+
25+
error: invalid suffix `XYZ` for number literal
26+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:20:9
27+
|
28+
LL | _ = 0XYZ;
29+
| ^^^^ invalid suffix `XYZ`
30+
|
31+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
32+
33+
error: invalid suffix `OPQ` for number literal
34+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:25:9
35+
|
36+
LL | _ = 0OPQ;
37+
| ^^^^ invalid suffix `OPQ`
38+
|
39+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
40+
41+
error: invalid suffix `BCD` for number literal
42+
--> $DIR/uppercase-base-prefix-invalid-no-fix.rs:30:9
43+
|
44+
LL | _ = 0BCD;
45+
| ^^^^ invalid suffix `BCD`
46+
|
47+
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
48+
49+
error: aborting due to 6 previous errors
50+

0 commit comments

Comments
 (0)