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

Suggests turbofish in patterns #114300

Merged
merged 6 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}`
parse_function_body_equals_expr = function body cannot be `= expression;`
.suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`

parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax

parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets
.suggestion = surround the type parameters with angle brackets

Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2731,3 +2731,17 @@ pub(crate) struct WhereClauseBeforeConstBodySugg {
#[suggestion_part(code = "")]
pub right: Span,
}

#[derive(Diagnostic)]
#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
#[primary_span]
pub span: Span,
#[suggestion(
parse_sugg_turbofish_syntax,
style = "verbose",
code = "::",
applicability = "maybe-incorrect"
)]
pub suggest_turbofish: Span,
}
1 change: 1 addition & 0 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ impl<'a> Parser<'a> {
| token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern.
| token::ModSep // A tuple / struct variant pattern.
| token::Not)) // A macro expanding to a pattern.
&& !(self.look_ahead(1, |t| t.kind == token::Lt) && self.look_ahead(2, |t| t.can_begin_type())) // May suggest the turbofish syntax for generics, only valid for recoveries.
mu001999 marked this conversation as resolved.
Show resolved Hide resolved
}

/// Parses `ident` or `ident @ pat`.
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{Parser, Restrictions, TokenType};
use crate::errors::PathSingleColon;
use crate::errors::{GenericArgsInPatRequireTurbofishSyntax, PathSingleColon};
use crate::{errors, maybe_whole};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
Expand Down Expand Up @@ -382,6 +382,14 @@ impl<'a> Parser<'a> {
};

PathSegment { ident, args: Some(args), id: ast::DUMMY_NODE_ID }
} else if style == PathStyle::Pat
&& self.check_noexpect(&token::Lt)
&& self.look_ahead(1, |t| t.can_begin_type())
{
return Err(self.sess.create_err(GenericArgsInPatRequireTurbofishSyntax {
span: self.token.span,
suggest_turbofish: self.token.span.shrink_to_lo(),
}));
} else {
// Generic arguments are not found.
PathSegment::from_ident(ident)
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/did_you_mean/issue-114112.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
enum E<T> {
A(T)
}

fn main() {
match E::<i32>::A(1) {
E<i32>::A(v) => { //~ ERROR generic args in patterns require the turbofish syntax
println!("{v:?}");
},
}
}
13 changes: 13 additions & 0 deletions tests/ui/did_you_mean/issue-114112.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-114112.rs:7:10
|
LL | E<i32>::A(v) => {
| ^
|
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | E::<i32>::A(v) => {
| ++

error: aborting due to previous error

2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-22647.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() {
let caller<F> = |f: F| //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
let caller<F> = |f: F| //~ ERROR generic args in patterns require the turbofish syntax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this error, the suggestion we should be giving is to add a type, but don't know how hard it would be to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like function parameters, maybe we can also suggest name: caller<F> or _: caller<F>? I think it may be more general, because caller<F> is more like a type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think the later is the better suggestion (particularly if the rest can be parsed as a type until ; or = is reached).

where F: Fn() -> i32
{
let x = f();
Expand Down
9 changes: 7 additions & 2 deletions tests/ui/parser/issues/issue-22647.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-22647.rs:2:15
|
LL | let caller<F> = |f: F|
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
| ^
|
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | let caller::<F> = |f: F|
| ++

error: aborting due to previous error

2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-22712.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ struct Foo<B> {
}

fn bar() {
let Foo<Vec<u8>> //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
let Foo<Vec<u8>> //~ ERROR generic args in patterns require the turbofish syntax
}

fn main() {}
9 changes: 7 additions & 2 deletions tests/ui/parser/issues/issue-22712.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-22712.rs:6:12
|
LL | let Foo<Vec<u8>>
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
| ^
|
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | let Foo::<Vec<u8>>
| ++

error: aborting due to previous error

3 changes: 1 addition & 2 deletions tests/ui/parser/pat-lt-bracket-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ struct Foo<T>(T, T);
impl<T> Foo<T> {
fn foo(&self) {
match *self {
Foo<T>(x, y) => {
//~^ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
Foo<T>(x, y) => { //~ ERROR generic args in patterns require the turbofish syntax
println!("Goodbye, World!")
}
}
Expand Down
9 changes: 7 additions & 2 deletions tests/ui/parser/pat-lt-bracket-3.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
error: expected one of `=>`, `@`, `if`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/pat-lt-bracket-3.rs:6:16
|
LL | Foo<T>(x, y) => {
| ^ expected one of `=>`, `@`, `if`, or `|`
| ^
|
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | Foo::<T>(x, y) => {
| ++

error: aborting due to previous error

2 changes: 1 addition & 1 deletion tests/ui/parser/pat-lt-bracket-4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ enum BtNode {

fn main() {
let y = match 10 {
Foo<T>::A(value) => value, //~ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
Foo<T>::A(value) => value, //~ ERROR generic args in patterns require the turbofish syntax
Foo<T>::B => 7,
};
}
9 changes: 7 additions & 2 deletions tests/ui/parser/pat-lt-bracket-4.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
error: expected one of `=>`, `@`, `if`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/pat-lt-bracket-4.rs:8:12
|
LL | Foo<T>::A(value) => value,
| ^ expected one of `=>`, `@`, `if`, or `|`
| ^
|
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | Foo::<T>::A(value) => value,
| ++

error: aborting due to previous error

2 changes: 1 addition & 1 deletion tests/ui/span/issue-34264.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn foo(Option<i32>, String) {} //~ ERROR expected one of
//~^ ERROR expected one of
//~^ ERROR generic args in patterns require the turbofish syntax
fn bar(x, y: usize) {} //~ ERROR expected one of

fn main() {
Expand Down
15 changes: 5 additions & 10 deletions tests/ui/span/issue-34264.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
error: expected one of `:`, `@`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-34264.rs:1:14
|
LL | fn foo(Option<i32>, String) {}
| ^ 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(self: Option<i32>, String) {}
| +++++
help: if this is a type, explicitly ignore the parameter name
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | fn foo(_: Option<i32>, String) {}
| ++
LL | fn foo(Option::<i32>, String) {}
| ++

error: expected one of `:`, `@`, or `|`, found `)`
--> $DIR/issue-34264.rs:1:27
Expand Down
6 changes: 2 additions & 4 deletions tests/ui/suggestions/issue-64252-self-type.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// 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 `<`
pub fn foo(Box<Self>) { } //~ ERROR generic args in patterns require the turbofish syntax

struct Bar;

impl Bar {
fn bar(Box<Self>) { }
//~^ ERROR expected one of `:`, `@`, or `|`, found `<`
fn bar(Box<Self>) { } //~ ERROR generic args in patterns require the turbofish syntax
}

fn main() { }
32 changes: 11 additions & 21 deletions tests/ui/suggestions/issue-64252-self-type.stderr
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
error: expected one of `:`, `@`, or `|`, found `<`
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-64252-self-type.rs:4:15
|
LL | pub fn foo(Box<Self>) { }
| ^ 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
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | pub fn foo(self: Box<Self>) { }
| +++++
help: if this is a type, explicitly ignore the parameter name
|
LL | pub fn foo(_: Box<Self>) { }
| ++
LL | pub fn foo(Box::<Self>) { }
mu001999 marked this conversation as resolved.
Show resolved Hide resolved
| ++

error: expected one of `:`, `@`, or `|`, found `<`
--> $DIR/issue-64252-self-type.rs:10:15
error: generic args in patterns require the turbofish syntax
--> $DIR/issue-64252-self-type.rs:9:15
|
LL | fn bar(Box<Self>) { }
| ^ 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 bar(self: Box<Self>) { }
| +++++
help: if this is a type, explicitly ignore the parameter name
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | fn bar(_: Box<Self>) { }
| ++
LL | fn bar(Box::<Self>) { }
| ++

error: aborting due to 2 previous errors

Loading