mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
syntax: improve parameter without type suggestions
This commit improves the suggestions provided when function parameters do not have types: - A new suggestion is added for arbitrary self types, which suggests adding `self: ` before the type. - Existing suggestions are now provided when a `<` is found where a `:` was expected (previously only `,` and `)` or trait items), this gives suggestions in the case where the unnamed parameter type is generic in a free function. - The suggestion that a type name be provided (e.g. `fn foo(HashMap<u32>)` -> `fn foo(HashMap: TypeName<u32>)`) will no longer occur when a `<` was found instead of `:`. - The ident will not be used for recovery when a `<` was found instead of `:`. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
ff191b54cc
commit
2537a8aa7a
@ -1220,6 +1220,7 @@ impl<'a> Parser<'a> {
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
pat: P<ast::Pat>,
|
||||
require_name: bool,
|
||||
is_self_allowed: bool,
|
||||
is_trait_item: bool,
|
||||
) -> Option<Ident> {
|
||||
// If we find a pattern followed by an identifier, it could be an (incorrect)
|
||||
@ -1241,14 +1242,27 @@ impl<'a> Parser<'a> {
|
||||
if require_name && (
|
||||
is_trait_item ||
|
||||
self.token == token::Comma ||
|
||||
self.token == token::Lt ||
|
||||
self.token == token::CloseDelim(token::Paren)
|
||||
) { // `fn foo(a, b) {}` or `fn foo(usize, usize) {}`
|
||||
) { // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if is_self_allowed {
|
||||
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 was a parameter name, give it a type",
|
||||
format!("{}: TypeName", ident),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a type, explicitly ignore the parameter name",
|
||||
@ -1256,7 +1270,9 @@ impl<'a> Parser<'a> {
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
|
||||
return Some(ident);
|
||||
|
||||
// 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
|
||||
|
@ -1212,6 +1212,7 @@ impl<'a> Parser<'a> {
|
||||
&mut err,
|
||||
pat,
|
||||
is_name_required,
|
||||
is_self_allowed,
|
||||
is_trait_item,
|
||||
) {
|
||||
err.emit();
|
||||
|
@ -5,6 +5,10 @@ LL | fn foo(i32);
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= 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(self: i32);
|
||||
| ^^^^^^^^^
|
||||
help: if this was a parameter name, give it a type
|
||||
|
|
||||
LL | fn foo(i32: TypeName);
|
||||
@ -21,6 +25,10 @@ LL | fn bar_with_default_impl(String, String) {}
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= 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 bar_with_default_impl(self: String, String) {}
|
||||
| ^^^^^^^^^^^^
|
||||
help: if this was a parameter name, give it a type
|
||||
|
|
||||
LL | fn bar_with_default_impl(String: TypeName, String) {}
|
||||
|
@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<`
|
||||
|
|
||||
LL | fn a(B<) {}
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | fn a(_: B<) {}
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,6 +5,10 @@ LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= 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 | trait Trait2015 { fn foo(#[allow(C)] self: i32); }
|
||||
| ^^^^^^^^^
|
||||
help: if this was a parameter name, give it a type
|
||||
|
|
||||
LL | trait Trait2015 { fn foo(#[allow(C)] i32: TypeName); }
|
||||
|
@ -3,6 +3,12 @@ error: expected one of `:`, `@`, or `|`, found `<`
|
||||
|
|
||||
LL | fn foo(Option<i32>, String) {}
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | fn foo(_: Option<i32>, String) {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `)`
|
||||
--> $DIR/issue-34264.rs:1:27
|
||||
|
14
src/test/ui/suggestions/issue-64252-self-type.rs
Normal file
14
src/test/ui/suggestions/issue-64252-self-type.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// This test checks that a suggestion to add a `self: ` parameter name is provided
|
||||
// to functions where this is applicable.
|
||||
|
||||
pub fn foo(Box<Self>) { }
|
||||
//~^ ERROR expected one of `:`, `@`, or `|`, found `<`
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Bar {
|
||||
fn bar(Box<Self>) { }
|
||||
//~^ ERROR expected one of `:`, `@`, or `|`, found `<`
|
||||
}
|
||||
|
||||
fn main() { }
|
30
src/test/ui/suggestions/issue-64252-self-type.stderr
Normal file
30
src/test/ui/suggestions/issue-64252-self-type.stderr
Normal file
@ -0,0 +1,30 @@
|
||||
error: expected one of `:`, `@`, or `|`, found `<`
|
||||
--> $DIR/issue-64252-self-type.rs:4:15
|
||||
|
|
||||
LL | pub fn foo(Box<Self>) { }
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | pub fn foo(_: Box<Self>) { }
|
||||
| ^^^^^^
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found `<`
|
||||
--> $DIR/issue-64252-self-type.rs:10:15
|
||||
|
|
||||
LL | fn bar(Box<Self>) { }
|
||||
| ^ expected one of `:`, `@`, or `|` here
|
||||
|
|
||||
= 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 bar(self: Box<Self>) { }
|
||||
| ^^^^^^^^^
|
||||
help: if this is a type, explicitly ignore the parameter name
|
||||
|
|
||||
LL | fn bar(_: Box<Self>) { }
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user