Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 049c728

Browse files
committed
Suggests turbofish in patterns
1 parent b969b83 commit 049c728

18 files changed

+101
-50
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}`
270270
parse_function_body_equals_expr = function body cannot be `= expression;`
271271
.suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`
272272
273+
parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax
274+
273275
parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets
274276
.suggestion = surround the type parameters with angle brackets
275277

compiler/rustc_parse/src/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,3 +2731,17 @@ pub(crate) struct WhereClauseBeforeConstBodySugg {
27312731
#[suggestion_part(code = "")]
27322732
pub right: Span,
27332733
}
2734+
2735+
#[derive(Diagnostic)]
2736+
#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
2737+
pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
2738+
#[primary_span]
2739+
pub span: Span,
2740+
#[suggestion(
2741+
parse_sugg_turbofish_syntax,
2742+
style = "verbose",
2743+
code = "::",
2744+
applicability = "maybe-incorrect"
2745+
)]
2746+
pub suggest_turbofish: Span,
2747+
}

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ impl<'a> Parser<'a> {
805805
| token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern.
806806
| token::ModSep // A tuple / struct variant pattern.
807807
| token::Not)) // A macro expanding to a pattern.
808+
&& !(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.
808809
}
809810

810811
/// Parses `ident` or `ident @ pat`.

compiler/rustc_parse/src/parser/path.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
22
use super::{Parser, Restrictions, TokenType};
3-
use crate::errors::PathSingleColon;
3+
use crate::errors::{GenericArgsInPatRequireTurbofishSyntax, PathSingleColon};
44
use crate::{errors, maybe_whole};
55
use rustc_ast::ptr::P;
66
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
@@ -382,6 +382,14 @@ impl<'a> Parser<'a> {
382382
};
383383

384384
PathSegment { ident, args: Some(args), id: ast::DUMMY_NODE_ID }
385+
} else if style == PathStyle::Pat
386+
&& self.check_noexpect(&token::Lt)
387+
&& self.look_ahead(1, |t| t.can_begin_type())
388+
{
389+
return Err(self.sess.create_err(GenericArgsInPatRequireTurbofishSyntax {
390+
span: self.token.span,
391+
suggest_turbofish: self.token.span.shrink_to_lo(),
392+
}));
385393
} else {
386394
// Generic arguments are not found.
387395
PathSegment::from_ident(ident)

tests/ui/did_you_mean/issue-114112.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
enum E<T> {
2+
A(T)
3+
}
4+
5+
fn main() {
6+
match E::<i32>::A(1) {
7+
E<i32>::A(v) => { //~ ERROR generic args in patterns require the turbofish syntax
8+
println!("{v:?}");
9+
},
10+
}
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: generic args in patterns require the turbofish syntax
2+
--> $DIR/issue-114112.rs:7:10
3+
|
4+
LL | E<i32>::A(v) => {
5+
| ^
6+
|
7+
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
8+
|
9+
LL | E::<i32>::A(v) => {
10+
| ++
11+
12+
error: aborting due to previous error
13+

tests/ui/parser/issues/issue-22647.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn main() {
2-
let caller<F> = |f: F| //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
2+
let caller<F> = |f: F| //~ ERROR generic args in patterns require the turbofish syntax
33
where F: Fn() -> i32
44
{
55
let x = f();
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
1+
error: generic args in patterns require the turbofish syntax
22
--> $DIR/issue-22647.rs:2:15
33
|
44
LL | let caller<F> = |f: F|
5-
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
5+
| ^
6+
|
7+
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
8+
|
9+
LL | let caller::<F> = |f: F|
10+
| ++
611

712
error: aborting due to previous error
813

tests/ui/parser/issues/issue-22712.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ struct Foo<B> {
33
}
44

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

99
fn main() {}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
1+
error: generic args in patterns require the turbofish syntax
22
--> $DIR/issue-22712.rs:6:12
33
|
44
LL | let Foo<Vec<u8>>
5-
| ^ expected one of `:`, `;`, `=`, `@`, or `|`
5+
| ^
6+
|
7+
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
8+
|
9+
LL | let Foo::<Vec<u8>>
10+
| ++
611

712
error: aborting due to previous error
813

0 commit comments

Comments
 (0)