Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syntax: improve parameter without type suggestions #64959

Merged
merged 1 commit into from Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 24 additions & 8 deletions src/libsyntax/parse/diagnostics.rs
Expand Up @@ -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)
Expand All @@ -1241,22 +1242,37 @@ 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) {}`
err.span_suggestion(
pat.span,
"if this was a parameter name, give it a type",
format!("{}: TypeName", ident),
Applicability::HasPlaceholders,
);
) { // `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",
format!("_: {}", ident),
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
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -1212,6 +1212,7 @@ impl<'a> Parser<'a> {
&mut err,
pat,
is_name_required,
is_self_allowed,
is_trait_item,
) {
err.emit();
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/anon-params-denied-2018.stderr
Expand Up @@ -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);
Expand All @@ -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) {}
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/parser/pat-lt-bracket-2.stderr
Expand Up @@ -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

4 changes: 4 additions & 0 deletions src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
Expand Up @@ -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); }
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/span/issue-34264.stderr
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/issue-64252-self-type.rs
@@ -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 changes: 30 additions & 0 deletions src/test/ui/suggestions/issue-64252-self-type.stderr
@@ -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