fix: merge multiple suggestions into a single multi-span suggestion in needless_late_init

This commit is contained in:
roife 2024-05-08 13:38:00 +08:00
parent befb659145
commit 362ef42b68
2 changed files with 104 additions and 142 deletions

View File

@ -273,24 +273,16 @@ fn check<'tcx>(
msg_span, msg_span,
"unneeded late initialization", "unneeded late initialization",
|diag| { |diag| {
diag.tool_only_span_suggestion( diag.multipart_suggestion(
local_stmt.span, format!("move the declaration `{binding_name}` here"),
"remove the local", vec![(local_stmt.span, String::new()), (assign.lhs_span, let_snippet)],
"",
Applicability::MachineApplicable,
);
diag.span_suggestion(
assign.lhs_span,
format!("declare `{binding_name}` here"),
let_snippet,
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
}, },
); );
}, },
ExprKind::If(cond, then_expr, Some(else_expr)) if !contains_let(cond) => { ExprKind::If(cond, then_expr, Some(else_expr)) if !contains_let(cond) => {
let (applicability, suggestions) = assignment_suggestions(cx, binding_id, [then_expr, else_expr])?; let (applicability, mut suggestions) = assignment_suggestions(cx, binding_id, [then_expr, else_expr])?;
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -298,30 +290,26 @@ fn check<'tcx>(
local_stmt.span, local_stmt.span,
"unneeded late initialization", "unneeded late initialization",
|diag| { |diag| {
diag.tool_only_span_suggestion(local_stmt.span, "remove the local", String::new(), applicability); suggestions.push((local_stmt.span, String::new()));
suggestions.push((usage.stmt.span.shrink_to_lo(), format!("{let_snippet} = ")));
diag.span_suggestion_verbose(
usage.stmt.span.shrink_to_lo(),
format!("declare `{binding_name}` here"),
format!("{let_snippet} = "),
applicability,
);
diag.multipart_suggestion("remove the assignments from the branches", suggestions, applicability);
if usage.needs_semi { if usage.needs_semi {
diag.span_suggestion( suggestions.push((usage.stmt.span.shrink_to_hi(), ";".to_owned()));
usage.stmt.span.shrink_to_hi(), }
"add a semicolon after the `if` expression",
";", diag.multipart_suggestion(
format!(
"move the declaration `{binding_name}` here and remove the assignments from the branches"
),
suggestions,
applicability, applicability,
); );
}
}, },
); );
}, },
ExprKind::Match(_, arms, MatchSource::Normal) => { ExprKind::Match(_, arms, MatchSource::Normal) => {
let (applicability, suggestions) = assignment_suggestions(cx, binding_id, arms.iter().map(|arm| arm.body))?; let (applicability, mut suggestions) =
assignment_suggestions(cx, binding_id, arms.iter().map(|arm| arm.body))?;
span_lint_and_then( span_lint_and_then(
cx, cx,
@ -329,29 +317,18 @@ fn check<'tcx>(
local_stmt.span, local_stmt.span,
"unneeded late initialization", "unneeded late initialization",
|diag| { |diag| {
diag.tool_only_span_suggestion(local_stmt.span, "remove the local", String::new(), applicability); suggestions.push((local_stmt.span, String::new()));
suggestions.push((usage.stmt.span.shrink_to_lo(), format!("{let_snippet} = ")));
diag.span_suggestion_verbose( if usage.needs_semi {
usage.stmt.span.shrink_to_lo(), suggestions.push((usage.stmt.span.shrink_to_hi(), ";".to_owned()));
format!("declare `{binding_name}` here"), }
format!("{let_snippet} = "),
applicability,
);
diag.multipart_suggestion( diag.multipart_suggestion(
"remove the assignments from the `match` arms", format!("move the declaration `{binding_name}` here and remove the assignments from the `match` arms"),
suggestions, suggestions,
applicability, applicability,
); );
if usage.needs_semi {
diag.span_suggestion(
usage.stmt.span.shrink_to_hi(),
"add a semicolon after the `match` expression",
";",
applicability,
);
}
}, },
); );
}, },

View File

@ -8,10 +8,11 @@ LL | a = "zero";
| |
= note: `-D clippy::needless-late-init` implied by `-D warnings` = note: `-D clippy::needless-late-init` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::needless_late_init)]` = help: to override `-D warnings` add `#[allow(clippy::needless_late_init)]`
help: declare `a` here help: move the declaration `a` here
|
LL ~
LL ~ let a = "zero";
| |
LL | let a = "zero";
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:30:5 --> tests/ui/needless_late_init.rs:30:5
@ -22,10 +23,12 @@ LL | let c;
LL | b = 1; LL | b = 1;
| ^^^^^ initialised here | ^^^^^ initialised here
| |
help: declare `b` here help: move the declaration `b` here
|
LL ~
LL | let c;
LL ~ let b = 1;
| |
LL | let b = 1;
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:31:5 --> tests/ui/needless_late_init.rs:31:5
@ -36,10 +39,12 @@ LL | b = 1;
LL | c = 2; LL | c = 2;
| ^^^^^ initialised here | ^^^^^ initialised here
| |
help: declare `c` here help: move the declaration `c` here
|
LL ~
LL | b = 1;
LL ~ let c = 2;
| |
LL | let c = 2;
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:35:5 --> tests/ui/needless_late_init.rs:35:5
@ -49,10 +54,11 @@ LL | let d: usize;
LL | d = 1; LL | d = 1;
| ^^^^^ initialised here | ^^^^^ initialised here
| |
help: declare `d` here help: move the declaration `d` here
|
LL ~
LL ~ let d: usize = 1;
| |
LL | let d: usize = 1;
| ~~~~~~~~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:38:5 --> tests/ui/needless_late_init.rs:38:5
@ -62,10 +68,11 @@ LL | let e;
LL | e = format!("{}", d); LL | e = format!("{}", d);
| ^^^^^^^^^^^^^^^^^^^^ initialised here | ^^^^^^^^^^^^^^^^^^^^ initialised here
| |
help: declare `e` here help: move the declaration `e` here
|
LL ~
LL ~ let e = format!("{}", d);
| |
LL | let e = format!("{}", d);
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:43:5 --> tests/ui/needless_late_init.rs:43:5
@ -73,20 +80,17 @@ error: unneeded late initialization
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^
| |
help: declare `a` here help: move the declaration `a` here and remove the assignments from the `match` arms
|
LL | let a = match n {
| +++++++
help: remove the assignments from the `match` arms
| |
LL ~
LL | let n = 1;
LL ~ let a = match n {
LL ~ 1 => "one", LL ~ 1 => "one",
LL | _ => { LL | _ => {
LL ~ "two" LL ~ "two"
LL | },
LL ~ };
| |
help: add a semicolon after the `match` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:52:5 --> tests/ui/needless_late_init.rs:52:5
@ -94,20 +98,15 @@ error: unneeded late initialization
LL | let b; LL | let b;
| ^^^^^^ | ^^^^^^
| |
help: declare `b` here help: move the declaration `b` here and remove the assignments from the branches
|
LL | let b = if n == 3 {
| +++++++
help: remove the assignments from the branches
| |
LL ~
LL ~ let b = if n == 3 {
LL ~ "four" LL ~ "four"
LL | } else { LL | } else {
LL ~ "five" LL ~ "five"
LL ~ };
| |
help: add a semicolon after the `if` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:59:5 --> tests/ui/needless_late_init.rs:59:5
@ -115,20 +114,16 @@ error: unneeded late initialization
LL | let d; LL | let d;
| ^^^^^^ | ^^^^^^
| |
help: declare `d` here help: move the declaration `d` here and remove the assignments from the branches
|
LL | let d = if true {
| +++++++
help: remove the assignments from the branches
| |
LL ~
LL ~ let d = if true {
LL | let temp = 5;
LL ~ temp LL ~ temp
LL | } else { LL | } else {
LL ~ 15 LL ~ 15
LL ~ };
| |
help: add a semicolon after the `if` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:67:5 --> tests/ui/needless_late_init.rs:67:5
@ -136,20 +131,15 @@ error: unneeded late initialization
LL | let e; LL | let e;
| ^^^^^^ | ^^^^^^
| |
help: declare `e` here help: move the declaration `e` here and remove the assignments from the branches
|
LL | let e = if true {
| +++++++
help: remove the assignments from the branches
| |
LL ~
LL ~ let e = if true {
LL ~ format!("{} {}", a, b) LL ~ format!("{} {}", a, b)
LL | } else { LL | } else {
LL ~ format!("{}", n) LL ~ format!("{}", n)
LL ~ };
| |
help: add a semicolon after the `if` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:74:5 --> tests/ui/needless_late_init.rs:74:5
@ -157,14 +147,11 @@ error: unneeded late initialization
LL | let f; LL | let f;
| ^^^^^^ | ^^^^^^
| |
help: declare `f` here help: move the declaration `f` here and remove the assignments from the `match` arms
| |
LL | let f = match 1 { LL ~
| +++++++ LL ~ let f = match 1 {
help: remove the assignments from the `match` arms LL ~ 1 => "three",
|
LL - 1 => f = "three",
LL + 1 => "three",
| |
error: unneeded late initialization error: unneeded late initialization
@ -173,19 +160,15 @@ error: unneeded late initialization
LL | let g: usize; LL | let g: usize;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
| |
help: declare `g` here help: move the declaration `g` here and remove the assignments from the branches
| |
LL | let g: usize = if true { LL ~
| ++++++++++++++ LL ~ let g: usize = if true {
help: remove the assignments from the branches LL ~ 5
LL | } else {
LL | panic!();
LL ~ };
| |
LL - g = 5;
LL + 5
|
help: add a semicolon after the `if` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:88:5 --> tests/ui/needless_late_init.rs:88:5
@ -196,10 +179,12 @@ LL | let y = SignificantDrop;
LL | x = 1; LL | x = 1;
| ^^^^^ initialised here | ^^^^^ initialised here
| |
help: declare `x` here help: move the declaration `x` here
|
LL ~
LL | let y = SignificantDrop;
LL ~ let x = 1;
| |
LL | let x = 1;
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:92:5 --> tests/ui/needless_late_init.rs:92:5
@ -210,10 +195,12 @@ LL | let y = 1;
LL | x = SignificantDrop; LL | x = SignificantDrop;
| ^^^^^^^^^^^^^^^^^^^ initialised here | ^^^^^^^^^^^^^^^^^^^ initialised here
| |
help: declare `x` here help: move the declaration `x` here
|
LL ~
LL | let y = 1;
LL ~ let x = SignificantDrop;
| |
LL | let x = SignificantDrop;
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:96:5 --> tests/ui/needless_late_init.rs:96:5
@ -224,10 +211,14 @@ LL | let x;
LL | x = SignificantDrop; LL | x = SignificantDrop;
| ^^^^^^^^^^^^^^^^^^^ initialised here | ^^^^^^^^^^^^^^^^^^^ initialised here
| |
help: declare `x` here help: move the declaration `x` here
|
LL ~
LL | // types that should be considered insignificant
...
LL | let y = Box::new(4);
LL ~ let x = SignificantDrop;
| |
LL | let x = SignificantDrop;
| ~~~~~
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:115:5 --> tests/ui/needless_late_init.rs:115:5
@ -235,20 +226,17 @@ error: unneeded late initialization
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^
| |
help: declare `a` here help: move the declaration `a` here and remove the assignments from the `match` arms
|
LL | let a = match n {
| +++++++
help: remove the assignments from the `match` arms
| |
LL ~
LL | let n = 1;
LL ~ let a = match n {
LL ~ 1 => f().await, LL ~ 1 => f().await,
LL | _ => { LL | _ => {
LL ~ "two" LL ~ "two"
LL | },
LL ~ };
| |
help: add a semicolon after the `match` expression
|
LL | };
| +
error: unneeded late initialization error: unneeded late initialization
--> tests/ui/needless_late_init.rs:132:5 --> tests/ui/needless_late_init.rs:132:5
@ -256,20 +244,17 @@ error: unneeded late initialization
LL | let a; LL | let a;
| ^^^^^^ | ^^^^^^
| |
help: declare `a` here help: move the declaration `a` here and remove the assignments from the `match` arms
|
LL | let a = match n {
| +++++++
help: remove the assignments from the `match` arms
| |
LL ~
LL | let n = 1;
LL ~ let a = match n {
LL ~ 1 => f(), LL ~ 1 => f(),
LL | _ => { LL | _ => {
LL ~ "two" LL ~ "two"
LL | },
LL ~ };
| |
help: add a semicolon after the `match` expression
|
LL | };
| +
error: aborting due to 16 previous errors error: aborting due to 16 previous errors