diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f2acb70ac45ba..041eb39194606 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -672,15 +672,6 @@ impl<'a> Parser<'a> { ); } - // Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens - // there are unclosed angle brackets - if self.unmatched_angle_bracket_count > 0 - && self.token.kind == TokenKind::Eq - && expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Gt))) - { - err.span_label(self.prev_token.span, "maybe try to close unmatched angle bracket"); - } - let sp = if self.token == token::Eof { // This is EOF; don't want to point at the following char, but rather the last token. self.prev_token.span diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 242c9d332bb02..5c53f1fe6e2db 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -279,7 +279,27 @@ impl<'a> Parser<'a> { let span_lo = self.token.span; let (params, span) = if self.eat_lt() { let params = self.parse_generic_params()?; - self.expect_gt()?; + if let Err(mut err) = self.expect_gt() { + // Try to recover a `:` into a `::` + // Attempt to find places where a missing `>` might belong. + if let [.., GenericParam { bounds, .. }] = ¶ms[..] + && let Some(poly) = bounds + .iter() + .filter_map(|bound| match bound { + ast::GenericBound::Trait(poly, _) => Some(poly), + _ => None, + }) + .last() + { + err.span_suggestion_verbose( + poly.span.shrink_to_hi(), + "you might have meant to end the type parameters here", + ">", + Applicability::MaybeIncorrect, + ); + } + return Err(err); + } (params, span_lo.to(self.prev_token.span)) } else { (ThinVec::new(), self.prev_token.span.shrink_to_hi()) diff --git a/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr b/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr index 53d5f9de65754..49a29abd8f16d 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr @@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=` --> $DIR/trait-path-expected-token.rs:5:33 | LL | fn f1<'a>(arg : Box>) {} - | - ^ expected one of 7 possible tokens - | | - | maybe try to close unmatched angle bracket + | ^ expected one of 7 possible tokens error: aborting due to previous error diff --git a/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr b/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr index cf2b1763fc9da..06dbf00af633e 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr @@ -10,9 +10,7 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/trait-path-expressions.rs:16:36 | LL | fn f2<'a>(arg : Box>) {} - | - ^ expected one of `,`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `,`, `:`, or `>` | help: you might have meant to end the type parameters here | diff --git a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr index bfddb6dc693ca..4bc57f550963f 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr @@ -8,9 +8,7 @@ error: expected one of `>`, a const expression, lifetime, or type, found `=` --> $DIR/trait-path-missing-gen_arg.rs:11:30 | LL | fn f1<'a>(arg : Box>) {} - | - ^ expected one of `>`, a const expression, lifetime, or type - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `>`, a const expression, lifetime, or type error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/parse/trait-path-segments.stderr b/tests/ui/generic-associated-types/parse/trait-path-segments.stderr index 8bc737d675204..0ab155590e22d 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-segments.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-segments.stderr @@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=` --> $DIR/trait-path-segments.rs:6:36 | LL | fn f1<'a>(arg : Box>) {} - | - ^ expected one of 8 possible tokens - | | - | maybe try to close unmatched angle bracket + | ^ expected one of 8 possible tokens | help: you might have meant to end the type parameters here | @@ -15,9 +13,7 @@ error: expected one of `,`, `::`, `:`, or `>`, found `=` --> $DIR/trait-path-segments.rs:17:35 | LL | impl::Y<'a> = &'a u32>> Z for T {} - | - ^ expected one of `,`, `::`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `,`, `::`, `:`, or `>` | help: you might have meant to end the type parameters here | @@ -28,9 +24,7 @@ error: expected one of `!`, `+`, `,`, `::`, `:`, or `>`, found `=` --> $DIR/trait-path-segments.rs:28:25 | LL | impl = &'a u32>> Z for T {} - | - ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>` | help: you might have meant to end the type parameters here | diff --git a/tests/ui/generic-associated-types/parse/trait-path-types.stderr b/tests/ui/generic-associated-types/parse/trait-path-types.stderr index 8f7a73c95b65f..ec1aa71846d6a 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-types.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-types.stderr @@ -2,9 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/trait-path-types.rs:6:37 | LL | fn f<'a>(arg : Box>) {} - | - ^ expected one of `,`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `,`, `:`, or `>` | help: you might have meant to end the type parameters here | @@ -15,9 +13,7 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/trait-path-types.rs:11:37 | LL | fn f1<'a>(arg : Box) = &'a ()>>) {} - | - ^ expected one of `,`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `,`, `:`, or `>` | help: you might have meant to end the type parameters here | @@ -28,9 +24,7 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/trait-path-types.rs:16:33 | LL | fn f1<'a>(arg : Box>) {} - | -- ^ expected one of `,`, `:`, or `>` - | | - | maybe try to close unmatched angle bracket + | ^ expected one of `,`, `:`, or `>` | help: you might have meant to end the type parameters here | diff --git a/tests/ui/generics/unclosed-generics-in-impl-def.rs b/tests/ui/generics/unclosed-generics-in-impl-def.rs new file mode 100644 index 0000000000000..2ec99b16e552b --- /dev/null +++ b/tests/ui/generics/unclosed-generics-in-impl-def.rs @@ -0,0 +1,2 @@ +impl> From for Canonical {} //~ ERROR expected +fn main() {} diff --git a/tests/ui/generics/unclosed-generics-in-impl-def.stderr b/tests/ui/generics/unclosed-generics-in-impl-def.stderr new file mode 100644 index 0000000000000..1ca8bc0328b2c --- /dev/null +++ b/tests/ui/generics/unclosed-generics-in-impl-def.stderr @@ -0,0 +1,13 @@ +error: expected one of `+`, `,`, `::`, `=`, or `>`, found `From` + --> $DIR/unclosed-generics-in-impl-def.rs:1:46 + | +LL | impl> From for Canonical {} + | ^^^^ expected one of `+`, `,`, `::`, `=`, or `>` + | +help: you might have meant to end the type parameters here + | +LL | impl>> From for Canonical {} + | + + +error: aborting due to previous error + diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index 753942dd1d189..ac2e63eca3ede 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -2,9 +2,8 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/issue-34334.rs:2:29 | LL | let sr: Vec<(u32, _, _) = vec![]; - | -- - ^ expected one of `,`, `:`, or `>` - | | | - | | maybe try to close unmatched angle bracket + | -- ^ expected one of `,`, `:`, or `>` + | | | while parsing the type for `sr` | help: you might have meant to end the type parameters here diff --git a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr index b2448774ae9d3..e40d985826282 100644 --- a/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr +++ b/tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr @@ -2,9 +2,8 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23 | LL | let v : Vec<(u32,_) = vec![]; - | - - ^ expected one of `,`, `:`, or `>` - | | | - | | maybe try to close unmatched angle bracket + | - ^ expected one of `,`, `:`, or `>` + | | | while parsing the type for `v` | help: you might have meant to end the type parameters here @@ -29,9 +28,8 @@ error: expected one of `,`, `:`, or `>`, found `=` --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:18 | LL | let v : Vec<'a = vec![]; - | - -- ^ expected one of `,`, `:`, or `>` - | | | - | | maybe try to close unmatched angle bracket + | - ^ expected one of `,`, `:`, or `>` + | | | while parsing the type for `v` | help: you might have meant to end the type parameters here