Skip to content

Commit 4e99db9

Browse files
committed
Tweak unclosed generics errors
Remove unnecessary span label for parse errors that already have a suggestion. Provide structured suggestion to close generics in more cases.
1 parent 64d7e0d commit 4e99db9

11 files changed

+65
-46
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -674,15 +674,6 @@ impl<'a> Parser<'a> {
674674
);
675675
}
676676

677-
// Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens
678-
// there are unclosed angle brackets
679-
if self.unmatched_angle_bracket_count > 0
680-
&& self.token.kind == TokenKind::Eq
681-
&& expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Gt)))
682-
{
683-
err.span_label(self.prev_token.span, "maybe try to close unmatched angle bracket");
684-
}
685-
686677
let sp = if self.token == token::Eof {
687678
// This is EOF; don't want to point at the following char, but rather the last token.
688679
self.prev_token.span
@@ -819,6 +810,7 @@ impl<'a> Parser<'a> {
819810
}
820811
err.emit();
821812
}
813+
822814
fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
823815
let sm = self.sess.source_map();
824816
match (&self.prev_token.kind, &self.token.kind) {
@@ -1994,6 +1986,39 @@ impl<'a> Parser<'a> {
19941986
}
19951987
}
19961988

1989+
/// When trying to close a generics list and encountering code like
1990+
/// ```text
1991+
/// impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {}
1992+
/// // ^ missing > here
1993+
/// ```
1994+
/// we provide a structured suggestion on the error from `expect_gt`.
1995+
pub(super) fn expect_gt_or_maybe_suggest_closing_generics(
1996+
&mut self,
1997+
params: &[ast::GenericParam],
1998+
) -> PResult<'a, ()> {
1999+
let Err(mut err) = self.expect_gt() else {
2000+
return Ok(());
2001+
};
2002+
// Attempt to find places where a missing `>` might belong.
2003+
if let [.., ast::GenericParam { bounds, .. }] = params
2004+
&& let Some(poly) = bounds
2005+
.iter()
2006+
.filter_map(|bound| match bound {
2007+
ast::GenericBound::Trait(poly, _) => Some(poly),
2008+
_ => None,
2009+
})
2010+
.last()
2011+
{
2012+
err.span_suggestion_verbose(
2013+
poly.span.shrink_to_hi(),
2014+
"you might have meant to end the type parameters here",
2015+
">",
2016+
Applicability::MaybeIncorrect,
2017+
);
2018+
}
2019+
Err(err)
2020+
}
2021+
19972022
pub(super) fn recover_seq_parse_error(
19982023
&mut self,
19992024
delim: Delimiter,

compiler/rustc_parse/src/parser/generics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ impl<'a> Parser<'a> {
279279
let span_lo = self.token.span;
280280
let (params, span) = if self.eat_lt() {
281281
let params = self.parse_generic_params()?;
282-
self.expect_gt()?;
282+
self.expect_gt_or_maybe_suggest_closing_generics(&params)?;
283283
(params, span_lo.to(self.prev_token.span))
284284
} else {
285285
(ThinVec::new(), self.prev_token.span.shrink_to_hi())

tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
22
--> $DIR/trait-path-expected-token.rs:5:33
33
|
44
LL | fn f1<'a>(arg : Box<dyn X<Y = B = &'a ()>>) {}
5-
| - ^ expected one of 7 possible tokens
6-
| |
7-
| maybe try to close unmatched angle bracket
5+
| ^ expected one of 7 possible tokens
86

97
error: aborting due to 1 previous error
108

tests/ui/generic-associated-types/parse/trait-path-expressions.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
1010
--> $DIR/trait-path-expressions.rs:16:36
1111
|
1212
LL | fn f2<'a>(arg : Box<dyn X< { 1 } = 32 >>) {}
13-
| - ^ expected one of `,`, `:`, or `>`
14-
| |
15-
| maybe try to close unmatched angle bracket
13+
| ^ expected one of `,`, `:`, or `>`
1614
|
1715
help: you might have meant to end the type parameters here
1816
|

tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ error: expected one of `>`, a const expression, lifetime, or type, found `=`
88
--> $DIR/trait-path-missing-gen_arg.rs:11:30
99
|
1010
LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
11-
| - ^ expected one of `>`, a const expression, lifetime, or type
12-
| |
13-
| maybe try to close unmatched angle bracket
11+
| ^ expected one of `>`, a const expression, lifetime, or type
1412

1513
error: aborting due to 2 previous errors
1614

tests/ui/generic-associated-types/parse/trait-path-segments.stderr

+3-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
22
--> $DIR/trait-path-segments.rs:6:36
33
|
44
LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
5-
| - ^ expected one of 8 possible tokens
6-
| |
7-
| maybe try to close unmatched angle bracket
5+
| ^ expected one of 8 possible tokens
86
|
97
help: you might have meant to end the type parameters here
108
|
@@ -15,9 +13,7 @@ error: expected one of `,`, `::`, `:`, or `>`, found `=`
1513
--> $DIR/trait-path-segments.rs:17:35
1614
|
1715
LL | impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {}
18-
| - ^ expected one of `,`, `::`, `:`, or `>`
19-
| |
20-
| maybe try to close unmatched angle bracket
16+
| ^ expected one of `,`, `::`, `:`, or `>`
2117
|
2218
help: you might have meant to end the type parameters here
2319
|
@@ -28,9 +24,7 @@ error: expected one of `!`, `+`, `,`, `::`, `:`, or `>`, found `=`
2824
--> $DIR/trait-path-segments.rs:28:25
2925
|
3026
LL | impl<T : X<X::Y<'a> = &'a u32>> Z for T {}
31-
| - ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>`
32-
| |
33-
| maybe try to close unmatched angle bracket
27+
| ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>`
3428
|
3529
help: you might have meant to end the type parameters here
3630
|

tests/ui/generic-associated-types/parse/trait-path-types.stderr

+3-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
22
--> $DIR/trait-path-types.rs:6:37
33
|
44
LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
5-
| - ^ expected one of `,`, `:`, or `>`
6-
| |
7-
| maybe try to close unmatched angle bracket
5+
| ^ expected one of `,`, `:`, or `>`
86
|
97
help: you might have meant to end the type parameters here
108
|
@@ -15,9 +13,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
1513
--> $DIR/trait-path-types.rs:11:37
1614
|
1715
LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {}
18-
| - ^ expected one of `,`, `:`, or `>`
19-
| |
20-
| maybe try to close unmatched angle bracket
16+
| ^ expected one of `,`, `:`, or `>`
2117
|
2218
help: you might have meant to end the type parameters here
2319
|
@@ -28,9 +24,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
2824
--> $DIR/trait-path-types.rs:16:33
2925
|
3026
LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
31-
| -- ^ expected one of `,`, `:`, or `>`
32-
| |
33-
| maybe try to close unmatched angle bracket
27+
| ^ expected one of `,`, `:`, or `>`
3428
|
3529
help: you might have meant to end the type parameters here
3630
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {} //~ ERROR expected
2+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: expected one of `+`, `,`, `::`, `=`, or `>`, found `From`
2+
--> $DIR/unclosed-generics-in-impl-def.rs:1:46
3+
|
4+
LL | impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {}
5+
| ^^^^ expected one of `+`, `,`, `::`, `=`, or `>`
6+
|
7+
help: you might have meant to end the type parameters here
8+
|
9+
LL | impl<S: Into<std::borrow::Cow<'static, str>>> From<S> for Canonical {}
10+
| +
11+
12+
error: aborting due to 1 previous error
13+

tests/ui/issues/issue-34334.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ error: expected one of `,`, `:`, or `>`, found `=`
22
--> $DIR/issue-34334.rs:2:29
33
|
44
LL | let sr: Vec<(u32, _, _) = vec![];
5-
| -- - ^ expected one of `,`, `:`, or `>`
6-
| | |
7-
| | maybe try to close unmatched angle bracket
5+
| -- ^ expected one of `,`, `:`, or `>`
6+
| |
87
| while parsing the type for `sr`
98
|
109
help: you might have meant to end the type parameters here

tests/ui/parser/missing-closing-angle-bracket-eq-constraint.stderr

+4-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ error: expected one of `,`, `:`, or `>`, found `=`
22
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23
33
|
44
LL | let v : Vec<(u32,_) = vec![];
5-
| - - ^ expected one of `,`, `:`, or `>`
6-
| | |
7-
| | maybe try to close unmatched angle bracket
5+
| - ^ expected one of `,`, `:`, or `>`
6+
| |
87
| while parsing the type for `v`
98
|
109
help: you might have meant to end the type parameters here
@@ -29,9 +28,8 @@ error: expected one of `,`, `:`, or `>`, found `=`
2928
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:18
3029
|
3130
LL | let v : Vec<'a = vec![];
32-
| - -- ^ expected one of `,`, `:`, or `>`
33-
| | |
34-
| | maybe try to close unmatched angle bracket
31+
| - ^ expected one of `,`, `:`, or `>`
32+
| |
3533
| while parsing the type for `v`
3634
|
3735
help: you might have meant to end the type parameters here

0 commit comments

Comments
 (0)