about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-01-20 14:25:53 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-01-20 14:25:53 -0800
commit15bad8bbfd3125b1e94d04f274910e24d0bb63eb (patch)
tree4533e892a8820a9ee4886d61f000e3f5e1faa6ef
parente387597a8f789ab6e37e6ce1bf67c8c45d4827c3 (diff)
downloadrust-15bad8bbfd3125b1e94d04f274910e24d0bb63eb.tar.gz
rust-15bad8bbfd3125b1e94d04f274910e24d0bb63eb.zip
Extend incorrect float literal recovery to account for suffixes
-rw-r--r--src/libsyntax/parse/parser.rs20
-rw-r--r--src/test/ui/issues/issue-52496.rs1
-rw-r--r--src/test/ui/issues/issue-52496.stderr20
-rw-r--r--src/test/ui/suggestions/recover-invalid-float.rs11
-rw-r--r--src/test/ui/suggestions/recover-invalid-float.stderr42
5 files changed, 74 insertions, 20 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe6fa5e97d7..038d949d24a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1990,15 +1990,23 @@ impl<'a> Parser<'a> {
                 result.unwrap()
             }
             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,
             }) => { // recover from `let x = .4;`
                 let lo = self.span;
                 self.bump();
                 if let token::Literal(
                     parse::token::Lit::Integer(val),
-                    None
+                    suffix,
                 ) = 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();
                     let sp = lo.to(self.prev_span);
                     let mut err = self.diagnostic()
@@ -2006,11 +2014,15 @@ impl<'a> Parser<'a> {
                     err.span_suggestion_with_applicability(
                         sp,
                         "must have an integer part",
-                        format!("0.{}", val),
+                        format!("0.{}{}", val, suffix),
                         Applicability::MachineApplicable,
                     );
                     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 {
                     unreachable!();
                 };
diff --git a/src/test/ui/issues/issue-52496.rs b/src/test/ui/issues/issue-52496.rs
index e734e9bc513..e9ffeaf6c89 100644
--- a/src/test/ui/issues/issue-52496.rs
+++ b/src/test/ui/issues/issue-52496.rs
@@ -4,7 +4,6 @@ fn main() {
     let _ = Foo { bar: .5, baz: 42 };
     //~^ ERROR float literals must have an integer part
     //~| ERROR missing field `bat` in initializer of `Foo`
-    //~| ERROR mismatched types
     let bar = 1.5f32;
     let _ = Foo { bar.into(), bat: -1, . };
     //~^ ERROR expected one of
diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr
index e69b9b7c87f..12fe7e7fc1f 100644
--- a/src/test/ui/issues/issue-52496.stderr
+++ b/src/test/ui/issues/issue-52496.stderr
@@ -5,7 +5,7 @@ LL |     let _ = Foo { bar: .5, baz: 42 };
    |                        ^^ help: must have an integer part: `0.5`
 
 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, . };
    |             ---      ^ expected one of `,` or `}` here
@@ -13,23 +13,13 @@ LL |     let _ = Foo { bar.into(), bat: -1, . };
    |             while parsing this struct
 
 error: expected identifier, found `.`
-  --> $DIR/issue-52496.rs:9:40
+  --> $DIR/issue-52496.rs:8:40
    |
 LL |     let _ = Foo { bar.into(), bat: -1, . };
    |             ---                        ^ expected identifier
    |             |
    |             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`
   --> $DIR/issue-52496.rs:4:13
    |
@@ -37,7 +27,7 @@ LL |     let _ = Foo { bar: .5, baz: 42 };
    |             ^^^ missing `bat`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-52496.rs:9:19
+  --> $DIR/issue-52496.rs:8:19
    |
 LL |     let _ = Foo { bar.into(), bat: -1, . };
    |                   ^^^ 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`
-  --> $DIR/issue-52496.rs:9:13
+  --> $DIR/issue-52496.rs:8:13
    |
 LL |     let _ = Foo { bar.into(), bat: -1, . };
    |             ^^^ missing `baz`
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
 Some errors occurred: E0063, E0308.
 For more information about an error, try `rustc --explain E0063`.
diff --git a/src/test/ui/suggestions/recover-invalid-float.rs b/src/test/ui/suggestions/recover-invalid-float.rs
new file mode 100644
index 00000000000..506ef8900b8
--- /dev/null
+++ b/src/test/ui/suggestions/recover-invalid-float.rs
@@ -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
+}
diff --git a/src/test/ui/suggestions/recover-invalid-float.stderr b/src/test/ui/suggestions/recover-invalid-float.stderr
new file mode 100644
index 00000000000..c464676b444
--- /dev/null
+++ b/src/test/ui/suggestions/recover-invalid-float.stderr
@@ -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`.