blob: 9f6643e8d52e855877a62ce794d8a3b447b1747f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#![warn(clippy::redundant_closure_call)]
#![allow(clippy::redundant_async_block)]
#![allow(clippy::type_complexity)]
#![allow(unused)]
async fn something() -> u32 {
21
}
async fn something_else() -> u32 {
2
}
fn main() {
let a = 42;
//~^ redundant_closure_call
let b = async {
//~^ redundant_closure_call
let x = something().await;
let y = something_else().await;
x * y
};
let c = {
//~^ redundant_closure_call
let x = 21;
let y = 2;
x * y
};
let d = async { something().await };
//~^ redundant_closure_call
macro_rules! m {
() => {
0
};
}
macro_rules! m2 {
() => {
m!()
//~^ redundant_closure_call
};
}
m2!();
//~^ redundant_closure_call
issue9956();
}
fn issue9956() {
assert_eq!(43, 42);
//~^ redundant_closure_call
// ... and some more interesting cases I've found while implementing the fix
// not actually immediately calling the closure:
let a = (|| 42);
dbg!(a());
// immediately calling it inside of a macro
dbg!(42);
//~^ redundant_closure_call
// immediately calling only one closure, so we can't remove the other ones
let a = || || 123;
//~^ redundant_closure_call
dbg!(a()());
// nested async closures
let a = async { 1 };
//~^ redundant_closure_call
let h = async { a.await };
// macro expansion tests
macro_rules! echo {
($e:expr) => {
$e
};
}
let a = 1;
//~^ redundant_closure_call
assert_eq!(a, 1);
let a = 123;
//~^ redundant_closure_call
assert_eq!(a, 123);
// chaining calls, but not closures
fn x() -> fn() -> fn() -> fn() -> i32 {
|| || || 42
}
let _ = x()()()();
fn bar() -> fn(i32, i32) {
foo
}
fn foo(_: i32, _: i32) {}
bar()(42, 5);
//~^ redundant_closure_call
foo(42, 5);
//~^ redundant_closure_call
}
async fn issue11357() {
async {}.await;
//~^ redundant_closure_call
}
mod issue11707 {
use core::future::Future;
fn spawn_on(fut: impl Future<Output = ()>) {}
fn demo() {
spawn_on(async move {});
//~^ redundant_closure_call
}
}
fn avoid_double_parens() {
std::convert::identity(13_i32 + 36_i32).leading_zeros();
//~^ redundant_closure_call
}
fn fp_11274() {
macro_rules! m {
($closure:expr) => {
$closure(1)
};
}
m!(|x| println!("{x}"));
}
// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
// triggers the lint.
fn issue_12358() {
macro_rules! make_closure {
() => {
(|| || {})
};
(x) => {
make_closure!()()
};
}
// The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
// different.
make_closure!(x)();
}
#[rustfmt::skip]
fn issue_9583() {
Some(true) == Some(true);
//~^ redundant_closure_call
Some(true) == Some(true);
//~^ redundant_closure_call
Some(if 1 > 2 {1} else {2}) == Some(2);
//~^ redundant_closure_call
Some( 1 > 2 ) == Some(true);
//~^ redundant_closure_call
}
|