about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/parse/parser.rs37
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.rs37
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.stderr63
-rw-r--r--src/test/ui/parser/issue-33413.stderr5
-rw-r--r--src/test/ui/parser/lifetime-in-pattern.stderr5
-rw-r--r--src/test/ui/parser/removed-syntax-mode.stderr5
-rw-r--r--src/test/ui/self/self-vs-path-ambiguity.stderr5
7 files changed, 152 insertions, 5 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 589b3e30fcf..3056d1c545c 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1789,6 +1789,35 @@ impl<'a> Parser<'a> {
         self.look_ahead(offset + 1, |t| t == &token::Colon)
     }
 
+    /// Skip unexpected attributes and doc comments in this position and emit an appropriate error.
+    fn eat_incorrect_doc_comment(&mut self, applied_to: &str) {
+        if let token::DocComment(_) = self.token {
+            let mut err = self.diagnostic().struct_span_err(
+                self.span,
+                &format!("documentation comments cannot be applied to {}", applied_to),
+            );
+            err.span_label(self.span, "doc comments are not allowed here");
+            err.emit();
+            self.bump();
+        } else if self.token == token::Pound && self.look_ahead(1, |t| {
+            *t == token::OpenDelim(token::Bracket)
+        }) {
+            let lo = self.span;
+            // Skip every token until next possible arg.
+            while self.token != token::CloseDelim(token::Bracket) {
+                self.bump();
+            }
+            let sp = lo.to(self.span);
+            self.bump();
+            let mut err = self.diagnostic().struct_span_err(
+                sp,
+                &format!("attributes cannot be applied to {}", applied_to),
+            );
+            err.span_label(sp, "attributes are not allowed here");
+            err.emit();
+        }
+    }
+
     /// This version of parse arg doesn't necessarily require
     /// identifier names.
     fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
@@ -1797,7 +1826,11 @@ impl<'a> Parser<'a> {
         let (pat, ty) = if require_name || self.is_named_argument() {
             debug!("parse_arg_general parse_pat (require_name:{})",
                    require_name);
-            let pat = self.parse_pat()?;
+            self.eat_incorrect_doc_comment("method arguments");
+            let pat = self.parse_pat().map_err(|mut err| {
+                err.span_label(self.span, "expected argument name");
+                err
+            })?;
 
             if let Err(mut err) = self.expect(&token::Colon) {
                 // If we find a pattern followed by an identifier, it could be an (incorrect)
@@ -1819,10 +1852,12 @@ impl<'a> Parser<'a> {
                 return Err(err);
             }
 
+            self.eat_incorrect_doc_comment("a method argument's type");
             (pat, self.parse_ty()?)
         } else {
             debug!("parse_arg_general ident_to_pat");
             let parser_snapshot_before_ty = self.clone();
+            self.eat_incorrect_doc_comment("a method argument's type");
             let mut ty = self.parse_ty();
             if ty.is_ok() && self.token == token::Colon {
                 // This wasn't actually a type, but a pattern looking like a type,
diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs
new file mode 100644
index 00000000000..22af94b6284
--- /dev/null
+++ b/src/test/ui/parser/fn-arg-doc-comment.rs
@@ -0,0 +1,37 @@
+pub fn f(
+    /// Comment
+    //~^ ERROR documentation comments cannot be applied to method arguments
+    //~| NOTE doc comments are not allowed here
+    id: u8,
+    /// Other
+    //~^ ERROR documentation comments cannot be applied to method arguments
+    //~| NOTE doc comments are not allowed here
+    a: u8,
+) {}
+
+fn foo(#[allow(dead_code)] id: i32) {}
+//~^ ERROR attributes cannot be applied to method arguments
+//~| NOTE attributes are not allowed here
+
+fn bar(id: #[allow(dead_code)] i32) {}
+//~^ ERROR attributes cannot be applied to a method argument's type
+//~| NOTE attributes are not allowed here
+
+fn main() {
+    // verify that the parser recovered and properly typechecked the args
+    f("", "");
+    //~^ ERROR mismatched types
+    //~| NOTE expected u8, found reference
+    //~| NOTE expected
+    //~| ERROR mismatched types
+    //~| NOTE expected u8, found reference
+    //~| NOTE expected
+    foo("");
+    //~^ ERROR mismatched types
+    //~| NOTE expected i32, found reference
+    //~| NOTE expected
+    bar("");
+    //~^ ERROR mismatched types
+    //~| NOTE expected i32, found reference
+    //~| NOTE expected
+}
diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr
new file mode 100644
index 00000000000..73a24eebb3f
--- /dev/null
+++ b/src/test/ui/parser/fn-arg-doc-comment.stderr
@@ -0,0 +1,63 @@
+error: documentation comments cannot be applied to method arguments
+  --> $DIR/fn-arg-doc-comment.rs:2:5
+   |
+LL |     /// Comment
+   |     ^^^^^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to method arguments
+  --> $DIR/fn-arg-doc-comment.rs:6:5
+   |
+LL |     /// Other
+   |     ^^^^^^^^^ doc comments are not allowed here
+
+error: attributes cannot be applied to method arguments
+  --> $DIR/fn-arg-doc-comment.rs:12:8
+   |
+LL | fn foo(#[allow(dead_code)] id: i32) {}
+   |        ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
+
+error: attributes cannot be applied to a method argument's type
+  --> $DIR/fn-arg-doc-comment.rs:16:12
+   |
+LL | fn bar(id: #[allow(dead_code)] i32) {}
+   |            ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
+
+error[E0308]: mismatched types
+  --> $DIR/fn-arg-doc-comment.rs:22:7
+   |
+LL |     f("", "");
+   |       ^^ expected u8, found reference
+   |
+   = note: expected type `u8`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-arg-doc-comment.rs:22:11
+   |
+LL |     f("", "");
+   |           ^^ expected u8, found reference
+   |
+   = note: expected type `u8`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-arg-doc-comment.rs:29:9
+   |
+LL |     foo("");
+   |         ^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-arg-doc-comment.rs:33:9
+   |
+LL |     bar("");
+   |         ^^ expected i32, found reference
+   |
+   = note: expected type `i32`
+              found type `&'static str`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issue-33413.stderr b/src/test/ui/parser/issue-33413.stderr
index 189ace74b9c..4cdd14a3e27 100644
--- a/src/test/ui/parser/issue-33413.stderr
+++ b/src/test/ui/parser/issue-33413.stderr
@@ -2,7 +2,10 @@ error: expected pattern, found `*`
   --> $DIR/issue-33413.rs:14:10
    |
 LL |     fn f(*, a: u8) -> u8 {} //~ ERROR expected pattern, found `*`
-   |          ^ expected pattern
+   |          ^
+   |          |
+   |          expected pattern
+   |          expected argument name
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/lifetime-in-pattern.stderr b/src/test/ui/parser/lifetime-in-pattern.stderr
index 86cc3c5b0cb..83ca1b0ba26 100644
--- a/src/test/ui/parser/lifetime-in-pattern.stderr
+++ b/src/test/ui/parser/lifetime-in-pattern.stderr
@@ -2,7 +2,10 @@ error: unexpected lifetime `'a` in pattern
   --> $DIR/lifetime-in-pattern.rs:13:10
    |
 LL | fn test(&'a str) {
-   |          ^^ unexpected lifetime
+   |          ^^
+   |          |
+   |          unexpected lifetime
+   |          expected argument name
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-mode.stderr b/src/test/ui/parser/removed-syntax-mode.stderr
index 7a274553d57..c5bc92e37b5 100644
--- a/src/test/ui/parser/removed-syntax-mode.stderr
+++ b/src/test/ui/parser/removed-syntax-mode.stderr
@@ -2,7 +2,10 @@ error: expected pattern, found `+`
   --> $DIR/removed-syntax-mode.rs:13:6
    |
 LL | fn f(+x: isize) {} //~ ERROR expected pattern, found `+`
-   |      ^ expected pattern
+   |      ^
+   |      |
+   |      expected pattern
+   |      expected argument name
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/self-vs-path-ambiguity.stderr b/src/test/ui/self/self-vs-path-ambiguity.stderr
index 76517433170..4cad8401f23 100644
--- a/src/test/ui/self/self-vs-path-ambiguity.stderr
+++ b/src/test/ui/self/self-vs-path-ambiguity.stderr
@@ -2,7 +2,10 @@ error: unexpected lifetime `'a` in pattern
   --> $DIR/self-vs-path-ambiguity.rs:19:11
    |
 LL |     fn i(&'a self::S: &S) {} //~ ERROR unexpected lifetime `'a` in pattern
-   |           ^^ unexpected lifetime
+   |           ^^
+   |           |
+   |           unexpected lifetime
+   |           expected argument name
 
 error: aborting due to previous error