Extend incorrect float literal recovery to account for suffixes
This commit is contained in:
parent
e387597a8f
commit
15bad8bbfd
5 changed files with 74 additions and 20 deletions
|
@ -1990,15 +1990,23 @@ impl<'a> Parser<'a> {
|
||||||
result.unwrap()
|
result.unwrap()
|
||||||
}
|
}
|
||||||
token::Dot if self.look_ahead(1, |t| match t {
|
token::Dot if self.look_ahead(1, |t| match t {
|
||||||
token::Literal(parse::token::Lit::Integer(_) , None) => true,
|
token::Literal(parse::token::Lit::Integer(_) , _) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}) => { // recover from `let x = .4;`
|
}) => { // recover from `let x = .4;`
|
||||||
let lo = self.span;
|
let lo = self.span;
|
||||||
self.bump();
|
self.bump();
|
||||||
if let token::Literal(
|
if let token::Literal(
|
||||||
parse::token::Lit::Integer(val),
|
parse::token::Lit::Integer(val),
|
||||||
None
|
suffix,
|
||||||
) = self.token {
|
) = self.token {
|
||||||
|
let suffix = suffix.and_then(|s| {
|
||||||
|
let s = s.as_str().get();
|
||||||
|
if ["f32", "f64"].contains(&s) {
|
||||||
|
Some(s)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}).unwrap_or("");
|
||||||
self.bump();
|
self.bump();
|
||||||
let sp = lo.to(self.prev_span);
|
let sp = lo.to(self.prev_span);
|
||||||
let mut err = self.diagnostic()
|
let mut err = self.diagnostic()
|
||||||
|
@ -2006,11 +2014,15 @@ impl<'a> Parser<'a> {
|
||||||
err.span_suggestion_with_applicability(
|
err.span_suggestion_with_applicability(
|
||||||
sp,
|
sp,
|
||||||
"must have an integer part",
|
"must have an integer part",
|
||||||
format!("0.{}", val),
|
format!("0.{}{}", val, suffix),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
err.emit();
|
err.emit();
|
||||||
return Ok(ast::LitKind::Float(val, ast::FloatTy::F32));
|
return Ok(match suffix {
|
||||||
|
"f32" => ast::LitKind::Float(val, ast::FloatTy::F32),
|
||||||
|
"f64" => ast::LitKind::Float(val, ast::FloatTy::F64),
|
||||||
|
_ => ast::LitKind::FloatUnsuffixed(val),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@ fn main() {
|
||||||
let _ = Foo { bar: .5, baz: 42 };
|
let _ = Foo { bar: .5, baz: 42 };
|
||||||
//~^ ERROR float literals must have an integer part
|
//~^ ERROR float literals must have an integer part
|
||||||
//~| ERROR missing field `bat` in initializer of `Foo`
|
//~| ERROR missing field `bat` in initializer of `Foo`
|
||||||
//~| ERROR mismatched types
|
|
||||||
let bar = 1.5f32;
|
let bar = 1.5f32;
|
||||||
let _ = Foo { bar.into(), bat: -1, . };
|
let _ = Foo { bar.into(), bat: -1, . };
|
||||||
//~^ ERROR expected one of
|
//~^ ERROR expected one of
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | let _ = Foo { bar: .5, baz: 42 };
|
||||||
| ^^ help: must have an integer part: `0.5`
|
| ^^ help: must have an integer part: `0.5`
|
||||||
|
|
||||||
error: expected one of `,` or `}`, found `.`
|
error: expected one of `,` or `}`, found `.`
|
||||||
--> $DIR/issue-52496.rs:9:22
|
--> $DIR/issue-52496.rs:8:22
|
||||||
|
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| --- ^ expected one of `,` or `}` here
|
| --- ^ expected one of `,` or `}` here
|
||||||
|
@ -13,23 +13,13 @@ LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| while parsing this struct
|
| while parsing this struct
|
||||||
|
|
||||||
error: expected identifier, found `.`
|
error: expected identifier, found `.`
|
||||||
--> $DIR/issue-52496.rs:9:40
|
--> $DIR/issue-52496.rs:8:40
|
||||||
|
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| --- ^ expected identifier
|
| --- ^ expected identifier
|
||||||
| |
|
| |
|
||||||
| while parsing this struct
|
| while parsing this struct
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/issue-52496.rs:4:24
|
|
||||||
|
|
|
||||||
LL | let _ = Foo { bar: .5, baz: 42 };
|
|
||||||
| ^^ expected f64, found f32
|
|
||||||
help: change the type of the numeric literal from `f32` to `f64`
|
|
||||||
|
|
|
||||||
LL | let _ = Foo { bar: .5f64, baz: 42 };
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error[E0063]: missing field `bat` in initializer of `Foo`
|
error[E0063]: missing field `bat` in initializer of `Foo`
|
||||||
--> $DIR/issue-52496.rs:4:13
|
--> $DIR/issue-52496.rs:4:13
|
||||||
|
|
|
|
||||||
|
@ -37,7 +27,7 @@ LL | let _ = Foo { bar: .5, baz: 42 };
|
||||||
| ^^^ missing `bat`
|
| ^^^ missing `bat`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-52496.rs:9:19
|
--> $DIR/issue-52496.rs:8:19
|
||||||
|
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| ^^^ expected f64, found f32
|
| ^^^ expected f64, found f32
|
||||||
|
@ -47,12 +37,12 @@ LL | let _ = Foo { bar.into().into(), bat: -1, . };
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0063]: missing field `baz` in initializer of `Foo`
|
error[E0063]: missing field `baz` in initializer of `Foo`
|
||||||
--> $DIR/issue-52496.rs:9:13
|
--> $DIR/issue-52496.rs:8:13
|
||||||
|
|
|
|
||||||
LL | let _ = Foo { bar.into(), bat: -1, . };
|
LL | let _ = Foo { bar.into(), bat: -1, . };
|
||||||
| ^^^ missing `baz`
|
| ^^^ missing `baz`
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors occurred: E0063, E0308.
|
Some errors occurred: E0063, E0308.
|
||||||
For more information about an error, try `rustc --explain E0063`.
|
For more information about an error, try `rustc --explain E0063`.
|
||||||
|
|
11
src/test/ui/suggestions/recover-invalid-float.rs
Normal file
11
src/test/ui/suggestions/recover-invalid-float.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fn main() {
|
||||||
|
let _: usize = .3;
|
||||||
|
//~^ ERROR float literals must have an integer part
|
||||||
|
//~| ERROR mismatched types
|
||||||
|
let _: usize = .42f32;
|
||||||
|
//~^ ERROR float literals must have an integer part
|
||||||
|
//~| ERROR mismatched types
|
||||||
|
let _: usize = .5f64;
|
||||||
|
//~^ ERROR float literals must have an integer part
|
||||||
|
//~| ERROR mismatched types
|
||||||
|
}
|
42
src/test/ui/suggestions/recover-invalid-float.stderr
Normal file
42
src/test/ui/suggestions/recover-invalid-float.stderr
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
error: float literals must have an integer part
|
||||||
|
--> $DIR/recover-invalid-float.rs:2:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .3;
|
||||||
|
| ^^ help: must have an integer part: `0.3`
|
||||||
|
|
||||||
|
error: float literals must have an integer part
|
||||||
|
--> $DIR/recover-invalid-float.rs:5:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .42f32;
|
||||||
|
| ^^^^^^ help: must have an integer part: `0.42f32`
|
||||||
|
|
||||||
|
error: float literals must have an integer part
|
||||||
|
--> $DIR/recover-invalid-float.rs:8:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .5f64;
|
||||||
|
| ^^^^^ help: must have an integer part: `0.5f64`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/recover-invalid-float.rs:2:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .3;
|
||||||
|
| ^^ expected usize, found floating-point number
|
||||||
|
|
|
||||||
|
= note: expected type `usize`
|
||||||
|
found type `{float}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/recover-invalid-float.rs:5:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .42f32;
|
||||||
|
| ^^^^^^ expected usize, found f32
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/recover-invalid-float.rs:8:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = .5f64;
|
||||||
|
| ^^^^^ expected usize, found f64
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue