Suggests turbofish in patterns

This commit is contained in:
Mu001999 2023-08-01 23:30:40 +08:00
parent b969b830aa
commit 049c728c60
18 changed files with 101 additions and 50 deletions

View File

@ -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

View File

@ -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,
}

View File

@ -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.
}
/// Parses `ident` or `ident @ pat`.

View File

@ -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};
@ -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)

View File

@ -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:?}");
},
}
}

View File

@ -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

View File

@ -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
where F: Fn() -> i32
{
let x = f();

View File

@ -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

View File

@ -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() {}

View File

@ -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

View File

@ -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!")
}
}

View File

@ -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

View File

@ -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,
};
}

View File

@ -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

View File

@ -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() {

View File

@ -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
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | fn foo(self: Option<i32>, String) {}
| +++++
help: if this is a type, explicitly ignore the parameter name
|
LL | fn foo(_: Option<i32>, String) {}
| ++
LL | fn foo(Option::<i32>, String) {}
| ++
error: expected one of `:`, `@`, or `|`, found `)`
--> $DIR/issue-34264.rs:1:27

View File

@ -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() { }

View File

@ -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>) { }
| ++
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
help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
|
LL | fn bar(self: Box<Self>) { }
| +++++
help: if this is a type, explicitly ignore the parameter name
|
LL | fn bar(_: Box<Self>) { }
| ++
LL | fn bar(Box::<Self>) { }
| ++
error: aborting due to 2 previous errors