Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak unclosed generics errors #117922

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 34 additions & 9 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Expand Up @@ -674,15 +674,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
Expand Down Expand Up @@ -819,6 +810,7 @@ impl<'a> Parser<'a> {
}
err.emit();
}

fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
let sm = self.sess.source_map();
match (&self.prev_token.kind, &self.token.kind) {
Expand Down Expand Up @@ -1994,6 +1986,39 @@ impl<'a> Parser<'a> {
}
}

/// When trying to close a generics list and encountering code like
/// ```text
/// impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {}
/// // ^ missing > here
/// ```
/// we provide a structured suggestion on the error from `expect_gt`.
pub(super) fn expect_gt_or_maybe_suggest_closing_generics(
&mut self,
params: &[ast::GenericParam],
) -> PResult<'a, ()> {
let Err(mut err) = self.expect_gt() else {
return Ok(());
};
// Attempt to find places where a missing `>` might belong.
if let [.., ast::GenericParam { bounds, .. }] = params
&& 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,
);
}
Err(err)
}

pub(super) fn recover_seq_parse_error(
&mut self,
delim: Delimiter,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/generics.rs
Expand Up @@ -279,7 +279,7 @@ 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()?;
self.expect_gt_or_maybe_suggest_closing_generics(&params)?;
(params, span_lo.to(self.prev_token.span))
} else {
(ThinVec::new(), self.prev_token.span.shrink_to_hi())
Expand Down
Expand Up @@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
--> $DIR/trait-path-expected-token.rs:5:33
|
LL | fn f1<'a>(arg : Box<dyn X<Y = B = &'a ()>>) {}
| - ^ expected one of 7 possible tokens
| |
| maybe try to close unmatched angle bracket
| ^ expected one of 7 possible tokens

error: aborting due to 1 previous error

Expand Up @@ -10,9 +10,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/trait-path-expressions.rs:16:36
|
LL | fn f2<'a>(arg : Box<dyn X< { 1 } = 32 >>) {}
| - ^ 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
|
Expand Down
Expand Up @@ -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<dyn X< = 32 >>) {}
| - ^ 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

Expand Up @@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
--> $DIR/trait-path-segments.rs:6:36
|
LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
| - ^ 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
|
Expand All @@ -15,9 +13,7 @@ error: expected one of `,`, `::`, `:`, or `>`, found `=`
--> $DIR/trait-path-segments.rs:17:35
|
LL | impl<T : X<<Self as X>::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
|
Expand All @@ -28,9 +24,7 @@ error: expected one of `!`, `+`, `,`, `::`, `:`, or `>`, found `=`
--> $DIR/trait-path-segments.rs:28:25
|
LL | impl<T : X<X::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
|
Expand Down
12 changes: 3 additions & 9 deletions tests/ui/generic-associated-types/parse/trait-path-types.stderr
Expand Up @@ -2,9 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/trait-path-types.rs:6:37
|
LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
| - ^ 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
|
Expand All @@ -15,9 +13,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/trait-path-types.rs:11:37
|
LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'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
|
Expand All @@ -28,9 +24,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/trait-path-types.rs:16:33
|
LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
| -- ^ 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
|
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/generics/unclosed-generics-in-impl-def.rs
@@ -0,0 +1,2 @@
impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {} //~ ERROR expected
fn main() {}
13 changes: 13 additions & 0 deletions 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<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {}
| ^^^^ expected one of `+`, `,`, `::`, `=`, or `>`
|
help: you might have meant to end the type parameters here
|
LL | impl<S: Into<std::borrow::Cow<'static, str>>> From<S> for Canonical {}
| +

error: aborting due to 1 previous error

5 changes: 2 additions & 3 deletions tests/ui/issues/issue-34334.stderr
Expand Up @@ -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
Expand Down
Expand Up @@ -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
Expand All @@ -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
Expand Down