about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-12-05 16:08:34 +0100
committerGitHub <noreply@github.com>2023-12-05 16:08:34 +0100
commit2d01eeeeacd889d232aa1d805e8727367a65718b (patch)
tree83368c75a8fef9801d1e6ab882b259f83d6c46a9 /compiler/rustc_parse/src
parent154f645d76a9752bd7ea58d7382b2e90e83557fb (diff)
parent4e99db9e54a2f684ed22deee48317bd147f1c360 (diff)
downloadrust-2d01eeeeacd889d232aa1d805e8727367a65718b.tar.gz
rust-2d01eeeeacd889d232aa1d805e8727367a65718b.zip
Rollup merge of #117922 - estebank:unclosed-generics, r=b-naber
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.
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs43
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs2
2 files changed, 35 insertions, 10 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 98e68e682ab..7ab0d3f35ea 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -673,15 +673,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
@@ -811,6 +802,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) {
@@ -1986,6 +1978,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,
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 242c9d332bb..20f67b284b2 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -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())