diff options
| author | bors <bors@rust-lang.org> | 2022-03-27 18:55:58 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-27 18:55:58 +0000 |
| commit | ab0c2e18dceb7140626a158affb983ae81039bd0 (patch) | |
| tree | a7f337cd02ff25fbdf7232d6d9d4a3307619ec23 /compiler/rustc_parse/src | |
| parent | d7aca22e7fd9fdfdc60e30117e54ed479fd7bf7a (diff) | |
| parent | 157c67b7a8c47de44b47eed9611e5a97981553eb (diff) | |
| download | rust-ab0c2e18dceb7140626a158affb983ae81039bd0.tar.gz rust-ab0c2e18dceb7140626a158affb983ae81039bd0.zip | |
Auto merge of #94495 - estebank:missing-closing-gt, r=jackh726
Provide suggestion for missing `>` in a type parameter list When encountering an inproperly terminated type parameter list, provide a suggestion to close it after the last non-constraint type parameter that was successfully parsed. Fix #94058.
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 07ce879de8f..93663a349f5 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -272,7 +272,23 @@ impl<'a> Parser<'a> { lo, ty_generics, )?; - self.expect_gt()?; + self.expect_gt().map_err(|mut err| { + // Attempt to find places where a missing `>` might belong. + if let Some(arg) = args + .iter() + .rev() + .skip_while(|arg| matches!(arg, AngleBracketedArg::Constraint(_))) + .next() + { + err.span_suggestion_verbose( + arg.span().shrink_to_hi(), + "you might have meant to end the type parameters here", + ">".to_string(), + Applicability::MaybeIncorrect, + ); + } + err + })?; let span = lo.to(self.prev_token.span); AngleBracketedArgs { args, span }.into() } else { @@ -462,6 +478,23 @@ impl<'a> Parser<'a> { while let Some(arg) = self.parse_angle_arg(ty_generics)? { args.push(arg); if !self.eat(&token::Comma) { + if self.token.kind == token::Semi + && self.look_ahead(1, |t| t.is_ident() || t.is_lifetime()) + { + // Add `>` to the list of expected tokens. + self.check(&token::Gt); + // Handle `,` to `;` substitution + let mut err = self.unexpected::<()>().unwrap_err(); + self.bump(); + err.span_suggestion_verbose( + self.prev_token.span.until(self.token.span), + "use a comma to separate type parameters", + ", ".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + continue; + } if !self.token.kind.should_end_const_arg() { if self.handle_ambiguous_unbraced_const_arg(&mut args)? { // We've managed to (partially) recover, so continue trying to parse |
