From 075c599188db71474eb2ad3c8b89287f79ac57e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 6 Nov 2023 21:35:21 +0000 Subject: [PATCH] More accurate span for unnecessary parens suggestion --- compiler/rustc_parse/src/errors.rs | 6 ++-- .../rustc_parse/src/parser/diagnostics.rs | 29 ++++--------------- compiler/rustc_parse/src/parser/expr.rs | 5 +++- ...recover-for-loop-parens-around-head.stderr | 2 +- 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, - begin_paren: Option, + begin_paren: Option<(Span, Span)>, ) -> P { 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