2022-06-25 22:15:44 +00:00
|
|
|
#![feature(async_closure)]
|
2019-09-25 16:30:27 +00:00
|
|
|
#![warn(clippy::redundant_closure_call)]
|
2023-03-04 16:28:53 +00:00
|
|
|
#![allow(clippy::redundant_async_block)]
|
2023-06-11 21:54:48 +00:00
|
|
|
#![allow(clippy::type_complexity)]
|
2019-09-25 16:30:27 +00:00
|
|
|
#![allow(unused)]
|
|
|
|
|
2022-06-25 22:15:44 +00:00
|
|
|
async fn something() -> u32 {
|
|
|
|
21
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn something_else() -> u32 {
|
|
|
|
2
|
|
|
|
}
|
|
|
|
|
2019-09-25 16:30:27 +00:00
|
|
|
fn main() {
|
|
|
|
let a = (|| 42)();
|
2022-06-25 22:15:44 +00:00
|
|
|
let b = (async || {
|
|
|
|
let x = something().await;
|
|
|
|
let y = something_else().await;
|
|
|
|
x * y
|
|
|
|
})();
|
|
|
|
let c = (|| {
|
|
|
|
let x = 21;
|
|
|
|
let y = 2;
|
|
|
|
x * y
|
|
|
|
})();
|
|
|
|
let d = (async || something().await)();
|
2022-11-29 15:36:43 +00:00
|
|
|
|
|
|
|
macro_rules! m {
|
|
|
|
() => {
|
|
|
|
(|| 0)()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
macro_rules! m2 {
|
|
|
|
() => {
|
|
|
|
(|| m!())()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
m2!();
|
2023-06-11 21:54:48 +00:00
|
|
|
issue9956();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn issue9956() {
|
|
|
|
assert_eq!((|| || 43)()(), 42);
|
|
|
|
|
|
|
|
// ... 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)());
|
|
|
|
|
|
|
|
// immediately calling only one closure, so we can't remove the other ones
|
|
|
|
let a = (|| || || 123)();
|
|
|
|
dbg!(a()());
|
|
|
|
|
|
|
|
// nested async closures
|
|
|
|
let a = (|| || || || async || 1)()()()()();
|
|
|
|
let h = async { a.await };
|
|
|
|
|
|
|
|
// macro expansion tests
|
|
|
|
macro_rules! echo {
|
|
|
|
($e:expr) => {
|
|
|
|
$e
|
|
|
|
};
|
|
|
|
}
|
|
|
|
let a = (|| echo!(|| echo!(|| 1)))()()();
|
|
|
|
assert_eq!(a, 1);
|
|
|
|
let a = (|| echo!((|| 123)))()();
|
|
|
|
assert_eq!(a, 123);
|
|
|
|
|
|
|
|
// chaining calls, but not closures
|
|
|
|
fn x() -> fn() -> fn() -> fn() -> i32 {
|
|
|
|
|| || || 42
|
|
|
|
}
|
|
|
|
let _ = x()()()();
|
2023-06-15 20:04:25 +00:00
|
|
|
|
|
|
|
fn bar() -> fn(i32, i32) {
|
|
|
|
foo
|
|
|
|
}
|
|
|
|
fn foo(_: i32, _: i32) {}
|
|
|
|
bar()((|| || 42)()(), 5);
|
|
|
|
foo((|| || 42)()(), 5);
|
2019-09-25 16:30:27 +00:00
|
|
|
}
|
2023-11-27 14:43:39 +00:00
|
|
|
|
|
|
|
async fn issue11357() {
|
|
|
|
(|| async {})().await;
|
|
|
|
}
|
|
|
|
|
|
|
|
mod issue11707 {
|
|
|
|
use core::future::Future;
|
|
|
|
|
|
|
|
fn spawn_on(fut: impl Future<Output = ()>) {}
|
|
|
|
|
|
|
|
fn demo() {
|
2023-11-27 14:50:08 +00:00
|
|
|
spawn_on((|| async move {})());
|
2023-11-27 14:43:39 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-27 15:27:51 +00:00
|
|
|
|
|
|
|
fn avoid_double_parens() {
|
|
|
|
std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
|
|
|
|
}
|
2024-01-03 11:36:44 +00:00
|
|
|
|
|
|
|
fn fp_11274() {
|
|
|
|
macro_rules! m {
|
|
|
|
($closure:expr) => {
|
|
|
|
$closure(1)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
m!(|x| println!("{x}"));
|
|
|
|
}
|
2024-02-28 18:03:12 +00:00
|
|
|
|
|
|
|
// 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)();
|
|
|
|
}
|