Tweak `self` arg not as first argument of a method diagnostic
Mention that `self` is only valid on "associated functions" ``` error: unexpected `self` argument in function --> $DIR/self-in-function-arg.rs:1:15 | LL | fn foo(x:i32, self: i32) -> i32 { self } | ^^^^ not valid as function argument | = note: `self` is only valid as the first argument of an associated function ``` When it is a method, mention it must be first ``` error: unexpected `self` argument in function --> $DIR/trait-fn.rs:4:20 | LL | fn c(foo: u32, self) {} | ^^^^ must be the first associated function argument ```
This commit is contained in:
parent
02f5786a32
commit
976541884f
|
@ -594,6 +594,51 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
|
||||||
|
let pat = self.parse_pat(Some("argument name"))?;
|
||||||
|
self.expect(&token::Colon)?;
|
||||||
|
let ty = self.parse_ty()?;
|
||||||
|
|
||||||
|
let mut err = self.diagnostic().struct_span_err_with_code(
|
||||||
|
pat.span,
|
||||||
|
"patterns aren't allowed in methods without bodies",
|
||||||
|
DiagnosticId::Error("E0642".into()),
|
||||||
|
);
|
||||||
|
err.span_suggestion_short(
|
||||||
|
pat.span,
|
||||||
|
"give this argument a name or use an underscore to ignore it",
|
||||||
|
"_".to_owned(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
err.emit();
|
||||||
|
|
||||||
|
// Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
|
||||||
|
let pat = P(Pat {
|
||||||
|
node: PatKind::Wild,
|
||||||
|
span: pat.span,
|
||||||
|
id: ast::DUMMY_NODE_ID
|
||||||
|
});
|
||||||
|
Ok((pat, ty))
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn recover_bad_self_arg(
|
||||||
|
&mut self,
|
||||||
|
mut arg: ast::Arg,
|
||||||
|
is_trait_item: bool,
|
||||||
|
) -> PResult<'a, ast::Arg> {
|
||||||
|
let sp = arg.pat.span;
|
||||||
|
arg.ty.node = TyKind::Err;
|
||||||
|
let mut err = self.struct_span_err(sp, "unexpected `self` argument in function");
|
||||||
|
if is_trait_item {
|
||||||
|
err.span_label(sp, "must be the first associated function argument");
|
||||||
|
} else {
|
||||||
|
err.span_label(sp, "not valid as function argument");
|
||||||
|
err.note("`self` is only valid as the first argument of an associated function");
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
Ok(arg)
|
||||||
|
}
|
||||||
|
|
||||||
crate fn consume_block(&mut self, delim: token::DelimToken) {
|
crate fn consume_block(&mut self, delim: token::DelimToken) {
|
||||||
let mut brace_depth = 0;
|
let mut brace_depth = 0;
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -1805,50 +1805,23 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This version of parse arg doesn't necessarily require identifier names.
|
/// This version of parse arg doesn't necessarily require identifier names.
|
||||||
fn parse_arg_general(&mut self, require_name: bool, is_trait_item: bool,
|
fn parse_arg_general(
|
||||||
allow_c_variadic: bool) -> PResult<'a, Arg> {
|
&mut self,
|
||||||
if let Ok(Some(_)) = self.parse_self_arg() {
|
require_name: bool,
|
||||||
let mut err = self.struct_span_err(self.prev_span,
|
is_trait_item: bool,
|
||||||
"unexpected `self` argument in function");
|
allow_c_variadic: bool,
|
||||||
err.span_label(self.prev_span,
|
) -> PResult<'a, Arg> {
|
||||||
"`self` is only valid as the first argument of an associated function");
|
if let Ok(Some(arg)) = self.parse_self_arg() {
|
||||||
return Err(err);
|
return self.recover_bad_self_arg(arg, is_trait_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (pat, ty) = if require_name || self.is_named_argument() {
|
let (pat, ty) = if require_name || self.is_named_argument() {
|
||||||
debug!("parse_arg_general parse_pat (require_name:{})",
|
debug!("parse_arg_general parse_pat (require_name:{})", require_name);
|
||||||
require_name);
|
|
||||||
self.eat_incorrect_doc_comment("method arguments");
|
self.eat_incorrect_doc_comment("method arguments");
|
||||||
let pat = self.parse_pat(Some("argument name"))?;
|
let pat = self.parse_pat(Some("argument name"))?;
|
||||||
|
|
||||||
if let Err(mut err) = 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)
|
self.argument_without_type(&mut err, pat, require_name, is_trait_item);
|
||||||
// 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(
|
|
||||||
span,
|
|
||||||
"declare the type after the parameter binding",
|
|
||||||
String::from("<identifier>: <type>"),
|
|
||||||
Applicability::HasPlaceholders,
|
|
||||||
);
|
|
||||||
} else if require_name && is_trait_item {
|
|
||||||
if let PatKind::Ident(_, ident, _) = pat.node {
|
|
||||||
err.span_suggestion(
|
|
||||||
pat.span,
|
|
||||||
"explicitly ignore parameter",
|
|
||||||
format!("_: {}", ident),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
fn a(&self) { }
|
fn a(&self) { }
|
||||||
//~^ ERROR unexpected `self` argument in function
|
//~^ ERROR unexpected `self` argument in function
|
||||||
|
//~| NOTE not valid as function argument
|
||||||
//~| NOTE `self` is only valid as the first argument of an associated function
|
//~| NOTE `self` is only valid as the first argument of an associated function
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
error: unexpected `self` argument in function
|
error: unexpected `self` argument in function
|
||||||
--> $DIR/bare-fn-start.rs:1:7
|
--> $DIR/bare-fn-start.rs:1:6
|
||||||
|
|
|
|
||||||
LL | fn a(&self) { }
|
LL | fn a(&self) { }
|
||||||
| ^^^^ `self` is only valid as the first argument of an associated function
|
| ^^^^^ not valid as function argument
|
||||||
|
|
|
||||||
|
= note: `self` is only valid as the first argument of an associated function
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
fn b(foo: u32, &mut self) { }
|
fn b(foo: u32, &mut self) { }
|
||||||
//~^ ERROR unexpected `self` argument in function
|
//~^ ERROR unexpected `self` argument in function
|
||||||
|
//~| NOTE not valid as function argument
|
||||||
//~| NOTE `self` is only valid as the first argument of an associated function
|
//~| NOTE `self` is only valid as the first argument of an associated function
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
error: unexpected `self` argument in function
|
error: unexpected `self` argument in function
|
||||||
--> $DIR/bare-fn.rs:1:21
|
--> $DIR/bare-fn.rs:1:16
|
||||||
|
|
|
|
||||||
LL | fn b(foo: u32, &mut self) { }
|
LL | fn b(foo: u32, &mut self) { }
|
||||||
| ^^^^ `self` is only valid as the first argument of an associated function
|
| ^^^^^^^^^ not valid as function argument
|
||||||
|
|
|
||||||
|
= note: `self` is only valid as the first argument of an associated function
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ struct Foo {}
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn c(foo: u32, self) {}
|
fn c(foo: u32, self) {}
|
||||||
//~^ ERROR unexpected `self` argument in function
|
//~^ ERROR unexpected `self` argument in function
|
||||||
//~| NOTE `self` is only valid as the first argument of an associated function
|
//~| NOTE must be the first associated function argument
|
||||||
|
|
||||||
fn good(&mut self, foo: u32) {}
|
fn good(&mut self, foo: u32) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: unexpected `self` argument in function
|
||||||
--> $DIR/trait-fn.rs:4:20
|
--> $DIR/trait-fn.rs:4:20
|
||||||
|
|
|
|
||||||
LL | fn c(foo: u32, self) {}
|
LL | fn c(foo: u32, self) {}
|
||||||
| ^^^^ `self` is only valid as the first argument of an associated function
|
| ^^^^ must be the first associated function argument
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn foo(x:i32, self: i32) -> i32 { self } //~ ERROR unexpected `self` argument in function
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,10 @@
|
||||||
|
error: unexpected `self` argument in function
|
||||||
|
--> $DIR/self-in-function-arg.rs:1:15
|
||||||
|
|
|
||||||
|
LL | fn foo(x:i32, self: i32) -> i32 { self }
|
||||||
|
| ^^^^ not valid as function argument
|
||||||
|
|
|
||||||
|
= note: `self` is only valid as the first argument of an associated function
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Reference in New Issue