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.
This commit is contained in:
Esteban Küber 2023-11-15 00:18:26 +00:00
parent 64d7e0d0b6
commit 4e99db9e54
11 changed files with 65 additions and 46 deletions

View File

@ -674,15 +674,6 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
); );
} }
// 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 { let sp = if self.token == token::Eof {
// This is EOF; don't want to point at the following char, but rather the last token. // This is EOF; don't want to point at the following char, but rather the last token.
self.prev_token.span self.prev_token.span
@ -819,6 +810,7 @@ pub(super) fn attr_on_non_tail_expr(&self, expr: &Expr) {
} }
err.emit(); err.emit();
} }
fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool { fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
let sm = self.sess.source_map(); let sm = self.sess.source_map();
match (&self.prev_token.kind, &self.token.kind) { match (&self.prev_token.kind, &self.token.kind) {
@ -1994,6 +1986,39 @@ pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
} }
} }
/// 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( pub(super) fn recover_seq_parse_error(
&mut self, &mut self,
delim: Delimiter, delim: Delimiter,

View File

@ -279,7 +279,7 @@ pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
let span_lo = self.token.span; let span_lo = self.token.span;
let (params, span) = if self.eat_lt() { let (params, span) = if self.eat_lt() {
let params = self.parse_generic_params()?; 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)) (params, span_lo.to(self.prev_token.span))
} else { } else {
(ThinVec::new(), self.prev_token.span.shrink_to_hi()) (ThinVec::new(), self.prev_token.span.shrink_to_hi())

View File

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

View File

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

View File

@ -8,9 +8,7 @@ error: expected one of `>`, a const expression, lifetime, or type, found `=`
--> $DIR/trait-path-missing-gen_arg.rs:11:30 --> $DIR/trait-path-missing-gen_arg.rs:11:30
| |
LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {} LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
| - ^ expected one of `>`, a const expression, lifetime, or type | ^ expected one of `>`, a const expression, lifetime, or type
| |
| maybe try to close unmatched angle bracket
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -2,9 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
--> $DIR/trait-path-segments.rs:6:36 --> $DIR/trait-path-segments.rs:6:36
| |
LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {} LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
| - ^ expected one of 8 possible tokens | ^ expected one of 8 possible tokens
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here 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 --> $DIR/trait-path-segments.rs:17:35
| |
LL | impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {} LL | impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {}
| - ^ expected one of `,`, `::`, `:`, or `>` | ^ expected one of `,`, `::`, `:`, or `>`
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here 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 --> $DIR/trait-path-segments.rs:28:25
| |
LL | impl<T : X<X::Y<'a> = &'a u32>> Z for T {} LL | impl<T : X<X::Y<'a> = &'a u32>> Z for T {}
| - ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>` | ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>`
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here help: you might have meant to end the type parameters here
| |

View File

@ -2,9 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/trait-path-types.rs:6:37 --> $DIR/trait-path-types.rs:6:37
| |
LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {} LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
| - ^ expected one of `,`, `:`, or `>` | ^ expected one of `,`, `:`, or `>`
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here 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 --> $DIR/trait-path-types.rs:11:37
| |
LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {} LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {}
| - ^ expected one of `,`, `:`, or `>` | ^ expected one of `,`, `:`, or `>`
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here 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 --> $DIR/trait-path-types.rs:16:33
| |
LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {} LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
| -- ^ expected one of `,`, `:`, or `>` | ^ expected one of `,`, `:`, or `>`
| |
| maybe try to close unmatched angle bracket
| |
help: you might have meant to end the type parameters here help: you might have meant to end the type parameters here
| |

View File

@ -0,0 +1,2 @@
impl<S: Into<std::borrow::Cow<'static, str>> From<S> for Canonical {} //~ ERROR expected
fn main() {}

View File

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

View File

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

View File

@ -2,9 +2,8 @@ error: expected one of `,`, `:`, or `>`, found `=`
--> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23 --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:7:23
| |
LL | let v : Vec<(u32,_) = vec![]; LL | let v : Vec<(u32,_) = vec![];
| - - ^ expected one of `,`, `:`, or `>` | - ^ expected one of `,`, `:`, or `>`
| | | | |
| | maybe try to close unmatched angle bracket
| while parsing the type for `v` | while parsing the type for `v`
| |
help: you might have meant to end the type parameters here 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 --> $DIR/missing-closing-angle-bracket-eq-constraint.rs:18:18
| |
LL | let v : Vec<'a = vec![]; LL | let v : Vec<'a = vec![];
| - -- ^ expected one of `,`, `:`, or `>` | - ^ expected one of `,`, `:`, or `>`
| | | | |
| | maybe try to close unmatched angle bracket
| while parsing the type for `v` | while parsing the type for `v`
| |
help: you might have meant to end the type parameters here help: you might have meant to end the type parameters here