fix: create the suggestion "differentially"
This commit is contained in:
parent
48ee4705dd
commit
f6dd112a0a
4 changed files with 118 additions and 39 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
|
||||
use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_context};
|
||||
use clippy_utils::source::{snippet_indent, walk_span_to_context};
|
||||
use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_ast::{FormatArgs, FormatArgumentKind};
|
||||
|
|
@ -74,10 +74,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, format_args: &FormatArgsStorag
|
|||
"this let-binding has unit value",
|
||||
|diag| {
|
||||
let mut suggestions = Vec::new();
|
||||
let init_new_span = walk_span_to_context(init.span, local.span.ctxt()).unwrap();
|
||||
|
||||
// Suggest omitting the `let` binding
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let snip = snippet_with_context(cx, init.span, local.span.ctxt(), "()", &mut app).0;
|
||||
let app = Applicability::MachineApplicable;
|
||||
|
||||
// If this is a binding pattern, we need to add suggestions to remove any usages
|
||||
// of the variable
|
||||
|
|
@ -114,21 +114,23 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, format_args: &FormatArgsStorag
|
|||
// ```
|
||||
// TODO: find a less awkward way to do this
|
||||
suggestions.push((
|
||||
init.span,
|
||||
format!("();\n{}", reindent_multiline(&snip, false, indent_of(cx, local.span))),
|
||||
init_new_span.shrink_to_lo(),
|
||||
format!("();\n{}", snippet_indent(cx, local.span).as_deref().unwrap_or("")),
|
||||
));
|
||||
diag.multipart_suggestion("replace variable usages with `()`", suggestions, app);
|
||||
diag.multipart_suggestion_verbose("replace variable usages with `()`", suggestions, app);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
suggestions.push((local.span, format!("{snip};")));
|
||||
// let local = returns_unit();
|
||||
// ^^^^^^^^^^^^ remove this
|
||||
suggestions.push((local.span.until(init_new_span), String::new()));
|
||||
let message = if suggestions.len() == 1 {
|
||||
"omit the `let` binding"
|
||||
} else {
|
||||
"omit the `let` binding and replace variable usages with `()`"
|
||||
};
|
||||
diag.multipart_suggestion(message, suggestions, app);
|
||||
diag.multipart_suggestion_verbose(message, suggestions, app);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
#![warn(clippy::let_unit_value)]
|
||||
#![allow(clippy::no_effect, clippy::needless_late_init, path_statements)]
|
||||
#![allow(
|
||||
clippy::no_effect,
|
||||
clippy::needless_late_init,
|
||||
path_statements,
|
||||
clippy::match_single_binding
|
||||
)]
|
||||
|
||||
macro_rules! let_and_return {
|
||||
($n:expr) => {{
|
||||
|
|
@ -197,12 +202,30 @@ pub fn issue12594() {
|
|||
}
|
||||
}
|
||||
|
||||
fn issue15061() {
|
||||
fn do_something(x: ()) {}
|
||||
fn takes_unit(x: ()) {}
|
||||
|
||||
fn issue15061() {
|
||||
let res = ();
|
||||
returns_unit();
|
||||
//~^ let_unit_value
|
||||
do_something(());
|
||||
takes_unit(());
|
||||
println!("{res:?}");
|
||||
}
|
||||
|
||||
fn issue15771() {
|
||||
match "Example String" {
|
||||
_ => returns_unit(),
|
||||
//~^ let_unit_value
|
||||
}
|
||||
|
||||
if true {}
|
||||
//~^ let_unit_value
|
||||
}
|
||||
|
||||
fn issue_15784() {
|
||||
let res = ();
|
||||
eprintln!("I return unit");
|
||||
//~^ let_unit_value
|
||||
takes_unit(());
|
||||
println!("{res:?}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
#![warn(clippy::let_unit_value)]
|
||||
#![allow(clippy::no_effect, clippy::needless_late_init, path_statements)]
|
||||
#![allow(
|
||||
clippy::no_effect,
|
||||
clippy::needless_late_init,
|
||||
path_statements,
|
||||
clippy::match_single_binding
|
||||
)]
|
||||
|
||||
macro_rules! let_and_return {
|
||||
($n:expr) => {{
|
||||
|
|
@ -197,11 +202,28 @@ pub fn issue12594() {
|
|||
}
|
||||
}
|
||||
|
||||
fn issue15061() {
|
||||
fn do_something(x: ()) {}
|
||||
fn takes_unit(x: ()) {}
|
||||
|
||||
fn issue15061() {
|
||||
let res = returns_unit();
|
||||
//~^ let_unit_value
|
||||
do_something(res);
|
||||
takes_unit(res);
|
||||
println!("{res:?}");
|
||||
}
|
||||
|
||||
fn issue15771() {
|
||||
match "Example String" {
|
||||
_ => _ = returns_unit(),
|
||||
//~^ let_unit_value
|
||||
}
|
||||
|
||||
_ = if true {}
|
||||
//~^ let_unit_value
|
||||
}
|
||||
|
||||
fn issue_15784() {
|
||||
let res = eprintln!("I return unit");
|
||||
//~^ let_unit_value
|
||||
takes_unit(res);
|
||||
println!("{res:?}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:11:5
|
||||
--> tests/ui/let_unit.rs:16:5
|
||||
|
|
||||
LL | let _x = println!("x");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::let-unit-value` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
|
||||
help: omit the `let` binding
|
||||
|
|
||||
LL - let _x = println!("x");
|
||||
LL + println!("x");
|
||||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:60:5
|
||||
--> tests/ui/let_unit.rs:65:5
|
||||
|
|
||||
LL | / let _ = v
|
||||
LL | |
|
||||
|
|
@ -21,18 +26,12 @@ LL | | .unwrap();
|
|||
|
|
||||
help: omit the `let` binding
|
||||
|
|
||||
LL ~ v
|
||||
LL +
|
||||
LL + .into_iter()
|
||||
LL + .map(|i| i * 2)
|
||||
LL + .filter(|i| i.is_multiple_of(2))
|
||||
LL + .map(|_| ())
|
||||
LL + .next()
|
||||
LL + .unwrap();
|
||||
LL - let _ = v
|
||||
LL + v
|
||||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:110:5
|
||||
--> tests/ui/let_unit.rs:115:5
|
||||
|
|
||||
LL | / let x = match Some(0) {
|
||||
LL | |
|
||||
|
|
@ -45,17 +44,12 @@ LL | | };
|
|||
|
|
||||
help: omit the `let` binding
|
||||
|
|
||||
LL ~ match Some(0) {
|
||||
LL +
|
||||
LL + None => f2(1),
|
||||
LL + Some(0) => f(),
|
||||
LL + Some(1) => f2(3),
|
||||
LL + Some(_) => (),
|
||||
LL + };
|
||||
LL - let x = match Some(0) {
|
||||
LL + match Some(0) {
|
||||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:190:9
|
||||
--> tests/ui/let_unit.rs:195:9
|
||||
|
|
||||
LL | let res = returns_unit();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -69,7 +63,7 @@ LL ~ returns_result(()).unwrap();
|
|||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:203:5
|
||||
--> tests/ui/let_unit.rs:208:5
|
||||
|
|
||||
LL | let res = returns_unit();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -79,8 +73,46 @@ help: replace variable usages with `()`
|
|||
LL ~ let res = ();
|
||||
LL ~ returns_unit();
|
||||
LL |
|
||||
LL ~ do_something(());
|
||||
LL ~ takes_unit(());
|
||||
|
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:216:14
|
||||
|
|
||||
LL | _ => _ = returns_unit(),
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: omit the `let` binding
|
||||
|
|
||||
LL - _ => _ = returns_unit(),
|
||||
LL + _ => returns_unit(),
|
||||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:220:5
|
||||
|
|
||||
LL | _ = if true {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: omit the `let` binding
|
||||
|
|
||||
LL - _ = if true {}
|
||||
LL + if true {}
|
||||
|
|
||||
|
||||
error: this let-binding has unit value
|
||||
--> tests/ui/let_unit.rs:225:5
|
||||
|
|
||||
LL | let res = eprintln!("I return unit");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: replace variable usages with `()`
|
||||
|
|
||||
LL ~ let res = ();
|
||||
LL ~ eprintln!("I return unit");
|
||||
LL |
|
||||
LL ~ takes_unit(());
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue