Skip to content

Commit a90b3ba

Browse files
committed
Auto merge of #4337 - flip1995:let_unit, r=phansch
Make let_unit lint suggestion auto applicable changelog: Make `let_unit` lint suggestion auto applicable
2 parents 20021bb + 385f447 commit a90b3ba

File tree

4 files changed

+120
-17
lines changed

4 files changed

+120
-17
lines changed

clippy_lints/src/types.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::utils::paths;
2525
use crate::utils::{
2626
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro_or_desugar, int_bits, last_path_segment,
2727
match_def_path, match_path, multispan_sugg, same_tys, sext, snippet, snippet_opt, snippet_with_applicability,
28-
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext,
28+
snippet_with_macro_callsite, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext,
2929
};
3030

3131
declare_clippy_lint! {
@@ -467,15 +467,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnitValue {
467467
if higher::is_from_for_desugar(local) {
468468
return;
469469
}
470-
span_lint(
471-
cx,
472-
LET_UNIT_VALUE,
473-
stmt.span,
474-
&format!(
475-
"this let-binding has unit value. Consider omitting `let {} =`",
476-
snippet(cx, local.pat.span, "..")
477-
),
478-
);
470+
span_lint_and_then(cx, LET_UNIT_VALUE, stmt.span, "this let-binding has unit value", |db| {
471+
if let Some(expr) = &local.init {
472+
let snip = snippet_with_macro_callsite(cx, expr.span, "()");
473+
db.span_suggestion(
474+
stmt.span,
475+
"omit the `let` binding",
476+
format!("{};", snip),
477+
Applicability::MachineApplicable, // snippet
478+
);
479+
}
480+
});
479481
}
480482
}
481483
}

tests/ui/let_unit.fixed

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::let_unit_value)]
4+
#![allow(clippy::no_effect)]
5+
#![allow(unused_variables)]
6+
7+
macro_rules! let_and_return {
8+
($n:expr) => {{
9+
let ret = $n;
10+
}};
11+
}
12+
13+
fn main() {
14+
println!("x");
15+
let _y = 1; // this is fine
16+
let _z = ((), 1); // this as well
17+
if true {
18+
();
19+
}
20+
21+
consume_units_with_for_loop(); // should be fine as well
22+
23+
multiline_sugg();
24+
25+
let_and_return!(()) // should be fine
26+
}
27+
28+
// Related to issue #1964
29+
fn consume_units_with_for_loop() {
30+
// `for_let_unit` lint should not be triggered by consuming them using for loop.
31+
let v = vec![(), (), ()];
32+
let mut count = 0;
33+
for _ in v {
34+
count += 1;
35+
}
36+
assert_eq!(count, 3);
37+
38+
// Same for consuming from some other Iterator<Item = ()>.
39+
let (tx, rx) = ::std::sync::mpsc::channel();
40+
tx.send(()).unwrap();
41+
drop(tx);
42+
43+
count = 0;
44+
for _ in rx.iter() {
45+
count += 1;
46+
}
47+
assert_eq!(count, 1);
48+
}
49+
50+
fn multiline_sugg() {
51+
let v: Vec<u8> = vec![2];
52+
53+
v
54+
.into_iter()
55+
.map(|i| i * 2)
56+
.filter(|i| i % 2 == 0)
57+
.map(|_| ())
58+
.next()
59+
.unwrap();
60+
}
61+
62+
#[derive(Copy, Clone)]
63+
pub struct ContainsUnit(()); // should be fine

tests/ui/let_unit.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
// run-rustfix
2+
13
#![warn(clippy::let_unit_value)]
4+
#![allow(clippy::no_effect)]
25
#![allow(unused_variables)]
36

47
macro_rules! let_and_return {
@@ -17,6 +20,8 @@ fn main() {
1720

1821
consume_units_with_for_loop(); // should be fine as well
1922

23+
multiline_sugg();
24+
2025
let_and_return!(()) // should be fine
2126
}
2227

@@ -42,5 +47,17 @@ fn consume_units_with_for_loop() {
4247
assert_eq!(count, 1);
4348
}
4449

50+
fn multiline_sugg() {
51+
let v: Vec<u8> = vec![2];
52+
53+
let _ = v
54+
.into_iter()
55+
.map(|i| i * 2)
56+
.filter(|i| i % 2 == 0)
57+
.map(|_| ())
58+
.next()
59+
.unwrap();
60+
}
61+
4562
#[derive(Copy, Clone)]
4663
pub struct ContainsUnit(()); // should be fine

tests/ui/let_unit.stderr

+28-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
1-
error: this let-binding has unit value. Consider omitting `let _x =`
2-
--> $DIR/let_unit.rs:11:5
1+
error: this let-binding has unit value
2+
--> $DIR/let_unit.rs:14:5
33
|
44
LL | let _x = println!("x");
5-
| ^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
66
|
77
= note: `-D clippy::let-unit-value` implied by `-D warnings`
88

9-
error: this let-binding has unit value. Consider omitting `let _a =`
10-
--> $DIR/let_unit.rs:15:9
9+
error: this let-binding has unit value
10+
--> $DIR/let_unit.rs:18:9
1111
|
1212
LL | let _a = ();
13-
| ^^^^^^^^^^^^
13+
| ^^^^^^^^^^^^ help: omit the `let` binding: `();`
1414

15-
error: aborting due to 2 previous errors
15+
error: this let-binding has unit value
16+
--> $DIR/let_unit.rs:53:5
17+
|
18+
LL | / let _ = v
19+
LL | | .into_iter()
20+
LL | | .map(|i| i * 2)
21+
LL | | .filter(|i| i % 2 == 0)
22+
LL | | .map(|_| ())
23+
LL | | .next()
24+
LL | | .unwrap();
25+
| |__________________^
26+
help: omit the `let` binding
27+
|
28+
LL | v
29+
LL | .into_iter()
30+
LL | .map(|i| i * 2)
31+
LL | .filter(|i| i % 2 == 0)
32+
LL | .map(|_| ())
33+
LL | .next()
34+
...
35+
36+
error: aborting due to 3 previous errors
1637

0 commit comments

Comments
 (0)