about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-02-18 16:59:33 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-02-27 10:46:23 -0800
commitba7039cfd6331fb532c8a68aa79e6af4ef9b62df (patch)
treea126782bd61af10433bf050ca0b35052ea05a18f /src
parent0c9afa87ba8145d09a2c4af7b15a9a23ad470fc8 (diff)
downloadrust-ba7039cfd6331fb532c8a68aa79e6af4ef9b62df.tar.gz
rust-ba7039cfd6331fb532c8a68aa79e6af4ef9b62df.zip
Detect missing `if` blocks
When unnecessarily using a fat arrow after an if condition, suggest the
removal of it.

When finding an if statement with no block, point at the `if` keyword to
provide more context.
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs35
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr2
-rw-r--r--src/test/ui/if-without-block.rs18
-rw-r--r--src/test/ui/if-without-block.stderr11
-rw-r--r--src/test/ui/missing-block-hint.stderr4
5 files changed, 60 insertions, 10 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2046bbfa713..9aba2e9d523 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -652,9 +652,11 @@ impl<'a> Parser<'a> {
             } else {
                 let token_str = Parser::token_to_string(t);
                 let this_token_str = self.this_token_to_string();
-                Err(self.fatal(&format!("expected `{}`, found `{}`",
-                                   token_str,
-                                   this_token_str)))
+                let mut err = self.fatal(&format!("expected `{}`, found `{}`",
+                                                  token_str,
+                                                  this_token_str));
+                err.span_label(self.span, format!("expected `{}`", token_str));
+                Err(err)
             }
         } else {
             self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[])
@@ -1172,7 +1174,7 @@ impl<'a> Parser<'a> {
                                      sep: SeqSep,
                                      f: F)
                                      -> PResult<'a, Vec<T>> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
+        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
         self.expect(bra)?;
         let result = self.parse_seq_to_before_end(ket, sep, f)?;
@@ -1190,7 +1192,7 @@ impl<'a> Parser<'a> {
                            sep: SeqSep,
                            f: F)
                            -> PResult<'a, Spanned<Vec<T>>> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
+        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
         let lo = self.span;
         self.expect(bra)?;
@@ -3212,7 +3214,23 @@ impl<'a> Parser<'a> {
             err.span_label(sp, "expected if condition here");
             return Err(err)
         }
-        let thn = self.parse_block()?;
+        let not_block = self.token != token::OpenDelim(token::Brace);
+        let fat_arrow_sp = if self.token == token::FatArrow {
+            Some(self.span)
+        } else {
+            None
+        };
+        let thn = self.parse_block().map_err(|mut err| {
+            if let Some(sp) = fat_arrow_sp {
+                // if cond => expr
+                err.span_suggestion(sp,
+                                    "only necessary in match arms, not before if blocks",
+                                    "".to_string());
+            } else if not_block {
+                err.span_label(lo, "this `if` statement has a condition, but no block");
+            }
+            err
+        })?;
         let mut els: Option<P<Expr>> = None;
         let mut hi = thn.span;
         if self.eat_keyword(keywords::Else) {
@@ -3629,8 +3647,9 @@ impl<'a> Parser<'a> {
                 self.bump();
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
-                    return Err(self.fatal(&format!("expected `{}`, found `{}`", "}",
-                                       token_str)))
+                    let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str));
+                    err.span_label(self.span, "expected `}`");
+                    return Err(err);
                 }
                 etc = true;
                 break;
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 301441c5622..e576393500f 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -19,7 +19,7 @@ error: expected `[`, found `#`
   --> $DIR/issue-40006.rs:20:17
    |
 LL |     fn xxx() { ### } //~ ERROR missing
-   |                 ^
+   |                 ^ expected `[`
 
 error: missing `fn`, `type`, or `const` for trait-item declaration
   --> $DIR/issue-40006.rs:20:21
diff --git a/src/test/ui/if-without-block.rs b/src/test/ui/if-without-block.rs
new file mode 100644
index 00000000000..ce3de3b302d
--- /dev/null
+++ b/src/test/ui/if-without-block.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let n = 1;
+    if 5 == {
+    //~^ NOTE this `if` statement has a condition, but no block
+        println!("five");
+    }
+}
+//~^ ERROR expected `{`, found `}`
diff --git a/src/test/ui/if-without-block.stderr b/src/test/ui/if-without-block.stderr
new file mode 100644
index 00000000000..8f6e53bd28b
--- /dev/null
+++ b/src/test/ui/if-without-block.stderr
@@ -0,0 +1,11 @@
+error: expected `{`, found `}`
+  --> $DIR/if-without-block.rs:17:1
+   |
+13 |     if 5 == {
+   |     -- this `if` statement has a condition, but no block
+...
+17 | }
+   | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/missing-block-hint.stderr b/src/test/ui/missing-block-hint.stderr
index 54f394a4220..ae583d0d4ba 100644
--- a/src/test/ui/missing-block-hint.stderr
+++ b/src/test/ui/missing-block-hint.stderr
@@ -2,11 +2,13 @@ error: expected `{`, found `=>`
   --> $DIR/missing-block-hint.rs:13:18
    |
 LL |         if (foo) => {} //~ ERROR expected `{`, found `=>`
-   |                  ^^
+   |                  ^^ help: only necessary in match arms, not before if blocks
 
 error: expected `{`, found `bar`
   --> $DIR/missing-block-hint.rs:17:13
    |
+LL |         if (foo)
+   |         -- this `if` statement has a condition, but no block
 LL |             bar; //~ ERROR expected `{`, found `bar`
    |             ^^^-
    |             |