Skip to content

Commit fd9d330

Browse files
Centri3Alexendoo
authored andcommitted
Don't lint let_unit_value when () is explicit
1 parent 2d6c238 commit fd9d330

File tree

7 files changed

+71
-127
lines changed

7 files changed

+71
-127
lines changed

clippy_lints/src/unit_types/let_unit_value.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,31 @@ use rustc_middle::ty;
1313
use super::LET_UNIT_VALUE;
1414

1515
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
16+
// skip `let () = { ... }`
17+
if let PatKind::Tuple(fields, ..) = local.pat.kind
18+
&& fields.is_empty()
19+
{
20+
return;
21+
}
22+
1623
if let Some(init) = local.init
1724
&& !local.pat.span.from_expansion()
1825
&& !in_external_macro(cx.sess(), local.span)
1926
&& !is_from_async_await(local.span)
2027
&& cx.typeck_results().pat_ty(local.pat).is_unit()
2128
{
29+
// skip `let awa = ()`
30+
if let ExprKind::Tup([]) = init.kind {
31+
return;
32+
}
33+
34+
// skip `let _: () = { ... }`
35+
if let Some(ty) = local.ty
36+
&& let TyKind::Tup([]) = ty.kind
37+
{
38+
return;
39+
}
40+
2241
if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
2342
|| matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()))
2443
&& expr_needs_inferred_result(cx, init)
@@ -34,7 +53,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
3453
|diag| {
3554
diag.span_suggestion(
3655
local.pat.span,
37-
"use a wild (`_`) binding",
56+
"use a wildcard binding",
3857
"_",
3958
Applicability::MaybeIncorrect, // snippet
4059
);

tests/ui/crashes/ice-8821.fixed

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/ui/crashes/ice-8821.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,4 @@ static FN: fn() = f;
55

66
fn main() {
77
let _: () = FN();
8-
//~^ ERROR: this let-binding has unit value
9-
//~| NOTE: `-D clippy::let-unit-value` implied by `-D warnings`
108
}

tests/ui/crashes/ice-8821.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/ui/let_unit.fixed

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ fn main() {
1313
let _y = 1; // this is fine
1414
let _z = ((), 1); // this as well
1515
if true {
16-
();
16+
// do not lint this, since () is explicit
17+
let _a = ();
18+
let () = dummy();
19+
let () = ();
20+
() = dummy();
21+
() = ();
22+
let _a: () = ();
23+
let _a: () = dummy();
1724
}
1825

1926
consume_units_with_for_loop(); // should be fine as well
@@ -23,6 +30,8 @@ fn main() {
2330
let_and_return!(()) // should be fine
2431
}
2532

33+
fn dummy() {}
34+
2635
// Related to issue #1964
2736
fn consume_units_with_for_loop() {
2837
// `for_let_unit` lint should not be triggered by consuming them using for loop.
@@ -74,40 +83,29 @@ fn _returns_generic() {
7483
x.then(|| T::default())
7584
}
7685

77-
let _: () = f(); // Ok
78-
let _: () = f(); // Lint.
86+
let _: () = f();
87+
let x: () = f();
7988

80-
let _: () = f2(0i32); // Ok
81-
let _: () = f2(0i32); // Lint.
89+
let _: () = f2(0i32);
90+
let x: () = f2(0i32);
8291

83-
f3(()); // Lint
84-
f3(()); // Lint
92+
let _: () = f3(());
93+
let x: () = f3(());
8594

86-
// Should lint:
87-
// fn f4<T>(mut x: Vec<T>) -> T {
88-
// x.pop().unwrap()
89-
// }
90-
// let _: () = f4(vec![()]);
91-
// let x: () = f4(vec![()]);
95+
fn f4<T>(mut x: Vec<T>) -> T {
96+
x.pop().unwrap()
97+
}
98+
let _: () = f4(vec![()]);
99+
let x: () = f4(vec![()]);
92100

93-
// Ok
94101
let _: () = {
95102
let x = 5;
96103
f2(x)
97104
};
98105

99-
let _: () = if true { f() } else { f2(0) }; // Ok
100-
let _: () = if true { f() } else { f2(0) }; // Lint
101-
102-
// Ok
103-
let _: () = match Some(0) {
104-
None => f2(1),
105-
Some(0) => f(),
106-
Some(1) => f2(3),
107-
Some(_) => f2('x'),
108-
};
106+
let _: () = if true { f() } else { f2(0) };
107+
let x: () = if true { f() } else { f2(0) };
109108

110-
// Lint
111109
match Some(0) {
112110
None => f2(1),
113111
Some(0) => f(),
@@ -155,7 +153,7 @@ fn _returns_generic() {
155153
{
156154
let _: () = x;
157155
let _: () = y;
158-
z;
156+
let _: () = z;
159157
let _: () = x1;
160158
let _: () = x2;
161159
let _: () = opt;

tests/ui/let_unit.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ fn main() {
1313
let _y = 1; // this is fine
1414
let _z = ((), 1); // this as well
1515
if true {
16+
// do not lint this, since () is explicit
1617
let _a = ();
18+
let () = dummy();
19+
let () = ();
20+
() = dummy();
21+
() = ();
22+
let _a: () = ();
23+
let _a: () = dummy();
1724
}
1825

1926
consume_units_with_for_loop(); // should be fine as well
@@ -23,6 +30,8 @@ fn main() {
2330
let_and_return!(()) // should be fine
2431
}
2532

33+
fn dummy() {}
34+
2635
// Related to issue #1964
2736
fn consume_units_with_for_loop() {
2837
// `for_let_unit` lint should not be triggered by consuming them using for loop.
@@ -74,41 +83,30 @@ fn _returns_generic() {
7483
x.then(|| T::default())
7584
}
7685

77-
let _: () = f(); // Ok
78-
let x: () = f(); // Lint.
86+
let _: () = f();
87+
let x: () = f();
7988

80-
let _: () = f2(0i32); // Ok
81-
let x: () = f2(0i32); // Lint.
89+
let _: () = f2(0i32);
90+
let x: () = f2(0i32);
8291

83-
let _: () = f3(()); // Lint
84-
let x: () = f3(()); // Lint
92+
let _: () = f3(());
93+
let x: () = f3(());
8594

86-
// Should lint:
87-
// fn f4<T>(mut x: Vec<T>) -> T {
88-
// x.pop().unwrap()
89-
// }
90-
// let _: () = f4(vec![()]);
91-
// let x: () = f4(vec![()]);
95+
fn f4<T>(mut x: Vec<T>) -> T {
96+
x.pop().unwrap()
97+
}
98+
let _: () = f4(vec![()]);
99+
let x: () = f4(vec![()]);
92100

93-
// Ok
94101
let _: () = {
95102
let x = 5;
96103
f2(x)
97104
};
98105

99-
let _: () = if true { f() } else { f2(0) }; // Ok
100-
let x: () = if true { f() } else { f2(0) }; // Lint
101-
102-
// Ok
103-
let _: () = match Some(0) {
104-
None => f2(1),
105-
Some(0) => f(),
106-
Some(1) => f2(3),
107-
Some(_) => f2('x'),
108-
};
106+
let _: () = if true { f() } else { f2(0) };
107+
let x: () = if true { f() } else { f2(0) };
109108

110-
// Lint
111-
let _: () = match Some(0) {
109+
let x = match Some(0) {
112110
None => f2(1),
113111
Some(0) => f(),
114112
Some(1) => f2(3),

tests/ui/let_unit.stderr

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ LL | let _x = println!("x");
88
= help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
99

1010
error: this let-binding has unit value
11-
--> $DIR/let_unit.rs:16:9
12-
|
13-
LL | let _a = ();
14-
| ^^^^^^^^^^^^ help: omit the `let` binding: `();`
15-
16-
error: this let-binding has unit value
17-
--> $DIR/let_unit.rs:51:5
11+
--> $DIR/let_unit.rs:60:5
1812
|
1913
LL | / let _ = v
2014
LL | | .into_iter()
@@ -37,45 +31,9 @@ LL + .unwrap();
3731
|
3832

3933
error: this let-binding has unit value
40-
--> $DIR/let_unit.rs:78:5
41-
|
42-
LL | let x: () = f(); // Lint.
43-
| ^^^^-^^^^^^^^^^^
44-
| |
45-
| help: use a wild (`_`) binding: `_`
46-
47-
error: this let-binding has unit value
48-
--> $DIR/let_unit.rs:81:5
34+
--> $DIR/let_unit.rs:109:5
4935
|
50-
LL | let x: () = f2(0i32); // Lint.
51-
| ^^^^-^^^^^^^^^^^^^^^^
52-
| |
53-
| help: use a wild (`_`) binding: `_`
54-
55-
error: this let-binding has unit value
56-
--> $DIR/let_unit.rs:83:5
57-
|
58-
LL | let _: () = f3(()); // Lint
59-
| ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
60-
61-
error: this let-binding has unit value
62-
--> $DIR/let_unit.rs:84:5
63-
|
64-
LL | let x: () = f3(()); // Lint
65-
| ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
66-
67-
error: this let-binding has unit value
68-
--> $DIR/let_unit.rs:100:5
69-
|
70-
LL | let x: () = if true { f() } else { f2(0) }; // Lint
71-
| ^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
72-
| |
73-
| help: use a wild (`_`) binding: `_`
74-
75-
error: this let-binding has unit value
76-
--> $DIR/let_unit.rs:111:5
77-
|
78-
LL | / let _: () = match Some(0) {
36+
LL | / let x = match Some(0) {
7937
LL | | None => f2(1),
8038
LL | | Some(0) => f(),
8139
LL | | Some(1) => f2(3),
@@ -93,11 +51,5 @@ LL + Some(_) => (),
9351
LL + };
9452
|
9553

96-
error: this let-binding has unit value
97-
--> $DIR/let_unit.rs:158:13
98-
|
99-
LL | let _: () = z;
100-
| ^^^^^^^^^^^^^^ help: omit the `let` binding: `z;`
101-
102-
error: aborting due to 10 previous errors
54+
error: aborting due to 3 previous errors
10355

0 commit comments

Comments
 (0)