diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b4fc9c2c6fc7c..e2f09affd4fea 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1824,6 +1824,14 @@ impl<'a> Parser<'a> { fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { maybe_whole!(self, NtArg, |x| x); + if let Ok(Some(_)) = self.parse_self_arg() { + let mut err = self.struct_span_err(self.prev_span, + "unexpected `self` argument in function"); + err.span_label(self.prev_span, + "`self` is only valid as the first argument of an associated function"); + return Err(err); + } + let (pat, ty) = if require_name || self.is_named_argument() { debug!("parse_arg_general parse_pat (require_name:{})", require_name); @@ -5385,11 +5393,12 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { + self.expect(&token::OpenDelim(token::Paren))?; + let sp = self.span; let mut variadic = false; let args: Vec> = - self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), + self.parse_seq_to_before_end( &token::CloseDelim(token::Paren), SeqSep::trailing_allowed(token::Comma), |p| { @@ -5436,6 +5445,8 @@ impl<'a> Parser<'a> { } )?; + self.eat(&token::CloseDelim(token::Paren)); + let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); if variadic && args.is_empty() { diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs new file mode 100644 index 0000000000000..741ba5f41ce16 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -0,0 +1,5 @@ +fn a(&self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of an associated function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr new file mode 100644 index 0000000000000..6a878b619d813 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn-start.rs:1:7 + | +LL | fn a(&self) { } + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs new file mode 100644 index 0000000000000..704fa996ca631 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -0,0 +1,5 @@ +fn b(foo: u32, &mut self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of an associated function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr new file mode 100644 index 0000000000000..b13f746a4ec58 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn.rs:1:21 + | +LL | fn b(foo: u32, &mut self) { } + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs new file mode 100644 index 0000000000000..31e867bc7641f --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -0,0 +1,11 @@ +struct Foo {} + +impl Foo { + fn c(foo: u32, self) {} + //~^ ERROR unexpected `self` argument in function + //~| NOTE `self` is only valid as the first argument of an associated function + + fn good(&mut self, foo: u32) {} +} + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr new file mode 100644 index 0000000000000..b3c2cc5b5ebe0 --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/trait-fn.rs:4:20 + | +LL | fn c(foo: u32, self) {} + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error +