diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-04-02 19:44:15 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-02 19:44:15 +0200 |
| commit | 278bc67fdc4667c1b3a8e984a6e43ed77df6fa3d (patch) | |
| tree | 26a89ff907e924d179d710d00597e623b07515d2 | |
| parent | 43f17288e10d5735dbbf19df29f18b0c1c4935aa (diff) | |
| parent | d8d27ca82249555906f5deb687e44813beef0062 (diff) | |
| download | rust-278bc67fdc4667c1b3a8e984a6e43ed77df6fa3d.tar.gz rust-278bc67fdc4667c1b3a8e984a6e43ed77df6fa3d.zip | |
Rollup merge of #139264 - freyacodes:fix/bad-turbofish-hints, r=petrochenkov
Fix two incorrect turbofish suggestions This fixes #121901 This is my contribution to Rust, and my first contribution to a language parser that I didn't write myself. I am a bit outside my depth here, so any constructive criticism is appreciated.
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 32 | ||||
| -rw-r--r-- | tests/ui/fn/bad-turbofish-hints-issue-121901.rs | 8 | ||||
| -rw-r--r-- | tests/ui/fn/bad-turbofish-hints-issue-121901.stderr | 25 |
3 files changed, 58 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index a8208e4717b..9405b58ab3b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2960,13 +2960,30 @@ impl<'a> Parser<'a> { let parser_snapshot_before_ty = this.create_snapshot_for_diagnostic(); this.eat_incorrect_doc_comment_for_param_type(); let mut ty = this.parse_ty_for_param(); - if ty.is_ok() - && this.token != token::Comma - && this.token != token::CloseDelim(Delimiter::Parenthesis) - { - // This wasn't actually a type, but a pattern looking like a type, - // so we are going to rollback and re-parse for recovery. - ty = this.unexpected_any(); + + if let Ok(t) = &ty { + // Check for trailing angle brackets + if let TyKind::Path(_, Path { segments, .. }) = &t.kind { + if let Some(segment) = segments.last() { + if let Some(guar) = + this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)]) + { + return Ok(( + dummy_arg(segment.ident, guar), + Trailing::No, + UsePreAttrPos::No, + )); + } + } + } + + if this.token != token::Comma + && this.token != token::CloseDelim(Delimiter::Parenthesis) + { + // This wasn't actually a type, but a pattern looking like a type, + // so we are going to rollback and re-parse for recovery. + ty = this.unexpected_any(); + } } match ty { Ok(ty) => { @@ -2977,6 +2994,7 @@ impl<'a> Parser<'a> { } // If this is a C-variadic argument and we hit an error, return the error. Err(err) if this.token == token::DotDotDot => return Err(err), + Err(err) if this.unmatched_angle_bracket_count > 0 => return Err(err), // Recover from attempting to parse the argument as a type without pattern. Err(err) => { err.cancel(); diff --git a/tests/ui/fn/bad-turbofish-hints-issue-121901.rs b/tests/ui/fn/bad-turbofish-hints-issue-121901.rs new file mode 100644 index 00000000000..1425e576d75 --- /dev/null +++ b/tests/ui/fn/bad-turbofish-hints-issue-121901.rs @@ -0,0 +1,8 @@ +// Regression test for the parser wrongfully suggesting turbofish syntax in below syntax errors + +type One = for<'a> fn(Box<dyn Send + 'a); +//~^ ERROR: expected one of `+`, `,`, or `>`, found `)` +type Two = for<'a> fn(Box<dyn Send + 'a>>); +//~^ ERROR: unmatched angle bracket + +fn main() {} diff --git a/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr b/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr new file mode 100644 index 00000000000..aacb326f8a2 --- /dev/null +++ b/tests/ui/fn/bad-turbofish-hints-issue-121901.stderr @@ -0,0 +1,25 @@ +error: expected one of `+`, `,`, or `>`, found `)` + --> $DIR/bad-turbofish-hints-issue-121901.rs:3:40 + | +LL | type One = for<'a> fn(Box<dyn Send + 'a); + | ^ expected one of `+`, `,`, or `>` + | +help: you might have meant to end the type parameters here + | +LL | type One = for<'a> fn(Box<dyn Send + 'a>); + | + + +error: unmatched angle bracket + --> $DIR/bad-turbofish-hints-issue-121901.rs:5:41 + | +LL | type Two = for<'a> fn(Box<dyn Send + 'a>>); + | ^ + | +help: remove extra angle bracket + | +LL - type Two = for<'a> fn(Box<dyn Send + 'a>>); +LL + type Two = for<'a> fn(Box<dyn Send + 'a>); + | + +error: aborting due to 2 previous errors + |
