about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-10-05 22:33:15 +0200
committerGitHub <noreply@github.com>2018-10-05 22:33:15 +0200
commitee745d6abfe1b5cb3f03505800db2cb94b6d42f9 (patch)
tree84195d420eb09e90d109f3b9576195a843decacf
parent3810657ae3712e7714e3eb16b4102af318bef3b6 (diff)
parentf5db4114102861acd004c8104dde7372010b156e (diff)
Rollup merge of #54804 - euclio:inverted-parameters, r=estebank
add suggestion for inverted function parameters

Fixes #54065.
-rw-r--r--src/libsyntax/parse/parser.rs21
-rw-r--r--src/test/ui/parser/inverted-parameters.rs39
-rw-r--r--src/test/ui/parser/inverted-parameters.stderr47
3 files changed, 106 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 5571a18b596..1825ee6eab8 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1777,7 +1777,26 @@ impl<'a> Parser<'a> {
                    require_name);
             let pat = self.parse_pat()?;
 
-            self.expect(&token::Colon)?;
+            if let Err(mut err) = self.expect(&token::Colon) {
+                // If we find a pattern followed by an identifier, it could be an (incorrect)
+                // C-style parameter declaration.
+                if self.check_ident() && self.look_ahead(1, |t| {
+                    *t == token::Comma || *t == token::CloseDelim(token::Paren)
+                }) {
+                    let ident = self.parse_ident().unwrap();
+                    let span = pat.span.with_hi(ident.span.hi());
+
+                    err.span_suggestion_with_applicability(
+                        span,
+                        "declare the type after the parameter binding",
+                        String::from("<identifier>: <type>"),
+                        Applicability::HasPlaceholders,
+                    );
+                }
+
+                return Err(err);
+            }
+
             (pat, self.parse_ty()?)
         } else {
             debug!("parse_arg_general ident_to_pat");
diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs
new file mode 100644
index 00000000000..a100debbf12
--- /dev/null
+++ b/src/test/ui/parser/inverted-parameters.rs
@@ -0,0 +1,39 @@
+// 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.
+
+struct S;
+
+impl S {
+    fn foo(&self, &str bar) {}
+    //~^ ERROR expected one of `:` or `@`
+    //~| HELP declare the type after the parameter binding
+    //~| SUGGESTION <identifier>: <type>
+}
+
+fn baz(S quux, xyzzy: i32) {}
+//~^ ERROR expected one of `:` or `@`
+//~| HELP declare the type after the parameter binding
+//~| SUGGESTION <identifier>: <type>
+
+fn one(i32 a b) {}
+//~^ ERROR expected one of `:` or `@`
+
+fn pattern((i32, i32) (a, b)) {}
+//~^ ERROR expected `:`
+
+fn fizz(i32) {}
+//~^ ERROR expected one of `:` or `@`
+
+fn missing_colon(quux S) {}
+//~^ ERROR expected one of `:` or `@`
+//~| HELP declare the type after the parameter binding
+//~| SUGGESTION <identifier>: <type>
+
+fn main() {}
diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr
new file mode 100644
index 00000000000..3f4f0615bc8
--- /dev/null
+++ b/src/test/ui/parser/inverted-parameters.stderr
@@ -0,0 +1,47 @@
+error: expected one of `:` or `@`, found `bar`
+  --> $DIR/inverted-parameters.rs:14:24
+   |
+LL |     fn foo(&self, &str bar) {}
+   |                   -----^^^
+   |                   |    |
+   |                   |    expected one of `:` or `@` here
+   |                   help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:` or `@`, found `quux`
+  --> $DIR/inverted-parameters.rs:20:10
+   |
+LL | fn baz(S quux, xyzzy: i32) {}
+   |        --^^^^
+   |        | |
+   |        | expected one of `:` or `@` here
+   |        help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: expected one of `:` or `@`, found `a`
+  --> $DIR/inverted-parameters.rs:25:12
+   |
+LL | fn one(i32 a b) {}
+   |            ^ expected one of `:` or `@` here
+
+error: expected `:`, found `(`
+  --> $DIR/inverted-parameters.rs:28:23
+   |
+LL | fn pattern((i32, i32) (a, b)) {}
+   |                       ^ expected `:`
+
+error: expected one of `:` or `@`, found `)`
+  --> $DIR/inverted-parameters.rs:31:12
+   |
+LL | fn fizz(i32) {}
+   |            ^ expected one of `:` or `@` here
+
+error: expected one of `:` or `@`, found `S`
+  --> $DIR/inverted-parameters.rs:34:23
+   |
+LL | fn missing_colon(quux S) {}
+   |                  -----^
+   |                  |    |
+   |                  |    expected one of `:` or `@` here
+   |                  help: declare the type after the parameter binding: `<identifier>: <type>`
+
+error: aborting due to 6 previous errors
+