Fix bad diagnostics for anon params with ref
This commit is contained in:
parent
f5d8117c33
commit
ea355bc6be
@ -1613,42 +1613,65 @@ pub(super) fn parameter_without_type(
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
return Some(ident);
|
||||
} else if let PatKind::Ident(_, ident, _) = pat.kind {
|
||||
if require_name
|
||||
&& (self.token == token::Comma
|
||||
|| self.token == token::Lt
|
||||
|| self.token == token::CloseDelim(token::Paren))
|
||||
{
|
||||
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if first_param {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a `self` type, give it a parameter name",
|
||||
format!("self: {}", ident),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
|
||||
// `fn foo(HashMap: TypeName<u32>)`.
|
||||
if self.token != token::Lt {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a parameter name, give it a type",
|
||||
format!("{}: TypeName", ident),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
} else if require_name
|
||||
&& (self.token == token::Comma
|
||||
|| self.token == token::Lt
|
||||
|| self.token == token::CloseDelim(token::Paren))
|
||||
{
|
||||
let (ident, self_sugg, param_sugg, type_sugg) = match pat.kind {
|
||||
PatKind::Ident(_, ident, _) => (
|
||||
ident,
|
||||
format!("self: {}", ident),
|
||||
format!("{}: TypeName", ident),
|
||||
format!("_: {}", ident),
|
||||
),
|
||||
// Also catches `fn foo(&a)`.
|
||||
PatKind::Ref(ref pat, mutab) => {
|
||||
if let PatKind::Ident(_, ident, _) = pat.clone().into_inner().kind {
|
||||
let mutab = mutab.prefix_str();
|
||||
(
|
||||
ident,
|
||||
format!("self: &{}{}", mutab, ident),
|
||||
format!("{}: &{}TypeName", ident, mutab),
|
||||
format!("_: &{}{}", mutab, ident),
|
||||
)
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
// Ignore other `PatKind`.
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if first_param {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a type, explicitly ignore the parameter name",
|
||||
format!("_: {}", ident),
|
||||
Applicability::MachineApplicable,
|
||||
"if this is a `self` type, give it a parameter name",
|
||||
self_sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
|
||||
|
||||
// Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
|
||||
return if self.token == token::Lt { None } else { Some(ident) };
|
||||
}
|
||||
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
|
||||
// `fn foo(HashMap: TypeName<u32>)`.
|
||||
if self.token != token::Lt {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a parameter name, give it a type",
|
||||
param_sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a type, explicitly ignore the parameter name",
|
||||
type_sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
|
||||
|
||||
// Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
|
||||
return if self.token == token::Lt { None } else { Some(ident) };
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -5,6 +5,10 @@
|
||||
trait T {
|
||||
fn foo(i32); //~ expected one of `:`, `@`, or `|`, found `)`
|
||||
|
||||
// Also checks with `&`
|
||||
fn foo_with_ref(&mut i32);
|
||||
//~^ ERROR expected one of `:`, `@`, or `|`, found `)`
|
||||
|
||||
fn bar_with_default_impl(String, String) {}
|
||||
//~^ ERROR expected one of `:`
|
||||
//~| ERROR expected one of `:`
|
||||
|
@ -18,8 +18,28 @@ help: if this is a type, explicitly ignore the parameter name
|
||||
LL | fn foo(_: i32);
|
||||
| ^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `)`
|
||||
--> $DIR/anon-params-denied-2018.rs:9:29
|
||||
|
|
||||
LL | fn foo_with_ref(&mut i32);
|
||||
| ^ expected one of `:`, `@`, or `|`
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this is a `self` type, give it a parameter name
|
||||
|
|
||||
LL | fn foo_with_ref(self: &mut i32);
|
||||
| ^^^^^^^^^^^^^^
|
||||
help: if this is a parameter name, give it a type
|
||||
|
|
||||
LL | fn foo_with_ref(i32: &mut TypeName);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | fn foo_with_ref(_: &mut i32);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `,`
|
||||
--> $DIR/anon-params-denied-2018.rs:8:36
|
||||
--> $DIR/anon-params-denied-2018.rs:12:36
|
||||
|
|
||||
LL | fn bar_with_default_impl(String, String) {}
|
||||
| ^ expected one of `:`, `@`, or `|`
|
||||
@ -39,7 +59,7 @@ LL | fn bar_with_default_impl(_: String, String) {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `)`
|
||||
--> $DIR/anon-params-denied-2018.rs:8:44
|
||||
--> $DIR/anon-params-denied-2018.rs:12:44
|
||||
|
|
||||
LL | fn bar_with_default_impl(String, String) {}
|
||||
| ^ expected one of `:`, `@`, or `|`
|
||||
@ -55,7 +75,7 @@ LL | fn bar_with_default_impl(String, _: String) {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `,`
|
||||
--> $DIR/anon-params-denied-2018.rs:13:22
|
||||
--> $DIR/anon-params-denied-2018.rs:17:22
|
||||
|
|
||||
LL | fn baz(a:usize, b, c: usize) -> usize {
|
||||
| ^ expected one of `:`, `@`, or `|`
|
||||
@ -70,5 +90,5 @@ help: if this is a type, explicitly ignore the parameter name
|
||||
LL | fn baz(a:usize, _: b, c: usize) -> usize {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -9,6 +9,20 @@ error: expected one of `:`, `@`, or `|`, found `)`
|
||||
|
|
||||
LL | fn test(&'a str) {
|
||||
| ^ expected one of `:`, `@`, or `|`
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this is a `self` type, give it a parameter name
|
||||
|
|
||||
LL | fn test(self: &str) {
|
||||
| ^^^^^^^^^^
|
||||
help: if this is a parameter name, give it a type
|
||||
|
|
||||
LL | fn test(str: &TypeName) {
|
||||
| ^^^^^^^^^^^^^^
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | fn test(_: &str) {
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user