about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-11-06 21:35:21 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-11-29 18:47:31 +0000
commit075c599188db71474eb2ad3c8b89287f79ac57e3 (patch)
tree70fd51978eff567eed49f15613378f9f665f0db6
parented084a93433d214edae3ee739444cbd442baf6fc (diff)
downloadrust-075c599188db71474eb2ad3c8b89287f79ac57e3.tar.gz
rust-075c599188db71474eb2ad3c8b89287f79ac57e3.zip
More accurate span for unnecessary parens suggestion
-rw-r--r--compiler/rustc_parse/src/errors.rs6
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs29
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs5
-rw-r--r--tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr2
4 files changed, 12 insertions, 30 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index e5d4cb6f4da..714ec7f2742 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1275,12 +1275,10 @@ pub(crate) struct ParenthesesInForHead {
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
 pub(crate) struct ParenthesesInForHeadSugg {
-    #[suggestion_part(code = "{left_snippet}")]
+    #[suggestion_part(code = " ")]
     pub left: Span,
-    pub left_snippet: String,
-    #[suggestion_part(code = "{right_snippet}")]
+    #[suggestion_part(code = " ")]
     pub right: Span,
-    pub right_snippet: String,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index ecb840f067e..0d42035e74b 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2001,37 +2001,18 @@ impl<'a> Parser<'a> {
     pub(super) fn recover_parens_around_for_head(
         &mut self,
         pat: P<Pat>,
-        begin_paren: Option<Span>,
+        begin_paren: Option<(Span, Span)>,
     ) -> P<Pat> {
         match (&self.token.kind, begin_paren) {
-            (token::CloseDelim(Delimiter::Parenthesis), Some(begin_par_sp)) => {
+            (token::CloseDelim(Delimiter::Parenthesis), Some((begin_par_sp, left))) => {
+                let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
                 self.bump();
-
-                let sm = self.sess.source_map();
-                let left = begin_par_sp;
-                let right = self.prev_token.span;
-                let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left)
-                    && !snip.ends_with(' ')
-                {
-                    " ".to_string()
-                } else {
-                    "".to_string()
-                };
-
-                let right_snippet = if let Ok(snip) = sm.span_to_next_source(right)
-                    && !snip.starts_with(' ')
-                {
-                    " ".to_string()
-                } else {
-                    "".to_string()
-                };
-
                 self.sess.emit_err(ParenthesesInForHead {
-                    span: vec![left, right],
+                    span: vec![begin_par_sp, self.prev_token.span],
                     // With e.g. `for (x) in y)` this would replace `(x) in y)`
                     // with `x) in y)` which is syntactically invalid.
                     // However, this is prevented before we get here.
-                    sugg: ParenthesesInForHeadSugg { left, right, left_snippet, right_snippet },
+                    sugg: ParenthesesInForHeadSugg { left, right },
                 });
 
                 // Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e334837c1d4..8d04769a568 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2615,7 +2615,10 @@ impl<'a> Parser<'a> {
         // This is used below for recovery in case of `for ( $stuff ) $block`
         // in which case we will suggest `for $stuff $block`.
         let begin_paren = match self.token.kind {
-            token::OpenDelim(Delimiter::Parenthesis) => Some(self.token.span),
+            token::OpenDelim(Delimiter::Parenthesis) => Some((
+                self.token.span,
+                self.prev_token.span.between(self.look_ahead(1, |t| t.span)),
+            )),
             _ => None,
         };
 
diff --git a/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr b/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr
index 3bad29f20af..58c83b65680 100644
--- a/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr
+++ b/tests/ui/parser/recover/recover-for-loop-parens-around-head.stderr
@@ -13,7 +13,7 @@ LL |     for ( elem in vec ) {
 help: remove parentheses in `for` loop
    |
 LL -     for ( elem in vec ) {
-LL +     for  elem in vec  {
+LL +     for elem in vec {
    |
 
 error[E0308]: mismatched types