Skip to content

Commit 15bad8b

Browse files
committed
Extend incorrect float literal recovery to account for suffixes
1 parent e387597 commit 15bad8b

File tree

5 files changed

+74
-20
lines changed

5 files changed

+74
-20
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,27 +1990,39 @@ impl<'a> Parser<'a> {
19901990
result.unwrap()
19911991
}
19921992
token::Dot if self.look_ahead(1, |t| match t {
1993-
token::Literal(parse::token::Lit::Integer(_) , None) => true,
1993+
token::Literal(parse::token::Lit::Integer(_) , _) => true,
19941994
_ => false,
19951995
}) => { // recover from `let x = .4;`
19961996
let lo = self.span;
19971997
self.bump();
19981998
if let token::Literal(
19991999
parse::token::Lit::Integer(val),
2000-
None
2000+
suffix,
20012001
) = self.token {
2002+
let suffix = suffix.and_then(|s| {
2003+
let s = s.as_str().get();
2004+
if ["f32", "f64"].contains(&s) {
2005+
Some(s)
2006+
} else {
2007+
None
2008+
}
2009+
}).unwrap_or("");
20022010
self.bump();
20032011
let sp = lo.to(self.prev_span);
20042012
let mut err = self.diagnostic()
20052013
.struct_span_err(sp, "float literals must have an integer part");
20062014
err.span_suggestion_with_applicability(
20072015
sp,
20082016
"must have an integer part",
2009-
format!("0.{}", val),
2017+
format!("0.{}{}", val, suffix),
20102018
Applicability::MachineApplicable,
20112019
);
20122020
err.emit();
2013-
return Ok(ast::LitKind::Float(val, ast::FloatTy::F32));
2021+
return Ok(match suffix {
2022+
"f32" => ast::LitKind::Float(val, ast::FloatTy::F32),
2023+
"f64" => ast::LitKind::Float(val, ast::FloatTy::F64),
2024+
_ => ast::LitKind::FloatUnsuffixed(val),
2025+
});
20142026
} else {
20152027
unreachable!();
20162028
};

src/test/ui/issues/issue-52496.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ fn main() {
44
let _ = Foo { bar: .5, baz: 42 };
55
//~^ ERROR float literals must have an integer part
66
//~| ERROR missing field `bat` in initializer of `Foo`
7-
//~| ERROR mismatched types
87
let bar = 1.5f32;
98
let _ = Foo { bar.into(), bat: -1, . };
109
//~^ ERROR expected one of

src/test/ui/issues/issue-52496.stderr

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,29 @@ LL | let _ = Foo { bar: .5, baz: 42 };
55
| ^^ help: must have an integer part: `0.5`
66

77
error: expected one of `,` or `}`, found `.`
8-
--> $DIR/issue-52496.rs:9:22
8+
--> $DIR/issue-52496.rs:8:22
99
|
1010
LL | let _ = Foo { bar.into(), bat: -1, . };
1111
| --- ^ expected one of `,` or `}` here
1212
| |
1313
| while parsing this struct
1414

1515
error: expected identifier, found `.`
16-
--> $DIR/issue-52496.rs:9:40
16+
--> $DIR/issue-52496.rs:8:40
1717
|
1818
LL | let _ = Foo { bar.into(), bat: -1, . };
1919
| --- ^ expected identifier
2020
| |
2121
| while parsing this struct
2222

23-
error[E0308]: mismatched types
24-
--> $DIR/issue-52496.rs:4:24
25-
|
26-
LL | let _ = Foo { bar: .5, baz: 42 };
27-
| ^^ expected f64, found f32
28-
help: change the type of the numeric literal from `f32` to `f64`
29-
|
30-
LL | let _ = Foo { bar: .5f64, baz: 42 };
31-
| ^^^^^
32-
3323
error[E0063]: missing field `bat` in initializer of `Foo`
3424
--> $DIR/issue-52496.rs:4:13
3525
|
3626
LL | let _ = Foo { bar: .5, baz: 42 };
3727
| ^^^ missing `bat`
3828

3929
error[E0308]: mismatched types
40-
--> $DIR/issue-52496.rs:9:19
30+
--> $DIR/issue-52496.rs:8:19
4131
|
4232
LL | let _ = Foo { bar.into(), bat: -1, . };
4333
| ^^^ expected f64, found f32
@@ -47,12 +37,12 @@ LL | let _ = Foo { bar.into().into(), bat: -1, . };
4737
| ^^^^^^^^^^
4838

4939
error[E0063]: missing field `baz` in initializer of `Foo`
50-
--> $DIR/issue-52496.rs:9:13
40+
--> $DIR/issue-52496.rs:8:13
5141
|
5242
LL | let _ = Foo { bar.into(), bat: -1, . };
5343
| ^^^ missing `baz`
5444

55-
error: aborting due to 7 previous errors
45+
error: aborting due to 6 previous errors
5646

5747
Some errors occurred: E0063, E0308.
5848
For more information about an error, try `rustc --explain E0063`.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn main() {
2+
let _: usize = .3;
3+
//~^ ERROR float literals must have an integer part
4+
//~| ERROR mismatched types
5+
let _: usize = .42f32;
6+
//~^ ERROR float literals must have an integer part
7+
//~| ERROR mismatched types
8+
let _: usize = .5f64;
9+
//~^ ERROR float literals must have an integer part
10+
//~| ERROR mismatched types
11+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error: float literals must have an integer part
2+
--> $DIR/recover-invalid-float.rs:2:20
3+
|
4+
LL | let _: usize = .3;
5+
| ^^ help: must have an integer part: `0.3`
6+
7+
error: float literals must have an integer part
8+
--> $DIR/recover-invalid-float.rs:5:20
9+
|
10+
LL | let _: usize = .42f32;
11+
| ^^^^^^ help: must have an integer part: `0.42f32`
12+
13+
error: float literals must have an integer part
14+
--> $DIR/recover-invalid-float.rs:8:20
15+
|
16+
LL | let _: usize = .5f64;
17+
| ^^^^^ help: must have an integer part: `0.5f64`
18+
19+
error[E0308]: mismatched types
20+
--> $DIR/recover-invalid-float.rs:2:20
21+
|
22+
LL | let _: usize = .3;
23+
| ^^ expected usize, found floating-point number
24+
|
25+
= note: expected type `usize`
26+
found type `{float}`
27+
28+
error[E0308]: mismatched types
29+
--> $DIR/recover-invalid-float.rs:5:20
30+
|
31+
LL | let _: usize = .42f32;
32+
| ^^^^^^ expected usize, found f32
33+
34+
error[E0308]: mismatched types
35+
--> $DIR/recover-invalid-float.rs:8:20
36+
|
37+
LL | let _: usize = .5f64;
38+
| ^^^^^ expected usize, found f64
39+
40+
error: aborting due to 6 previous errors
41+
42+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)