More accurate span for unnecessary parens suggestion

This commit is contained in:
Esteban Küber 2023-11-06 21:35:21 +00:00
parent ed084a9343
commit 075c599188
4 changed files with 12 additions and 30 deletions

View File

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

View File

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

View File

@ -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,
};

View File

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