mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-25 12:33:30 +00:00
197 lines
4.5 KiB
Rust
197 lines
4.5 KiB
Rust
#![allow(unused, clippy::manual_async_fn)]
|
|
#![warn(clippy::redundant_async_block)]
|
|
|
|
use std::future::{Future, IntoFuture};
|
|
|
|
async fn func1(n: usize) -> usize {
|
|
n + 1
|
|
}
|
|
|
|
async fn func2() -> String {
|
|
let s = String::from("some string");
|
|
let f = async { (*s).to_owned() };
|
|
let x = async { f.await };
|
|
x.await
|
|
}
|
|
|
|
fn main() {
|
|
let fut1 = async { 17 };
|
|
// Lint
|
|
let fut2 = async { fut1.await };
|
|
|
|
let fut1 = async { 25 };
|
|
// Lint
|
|
let fut2 = async move { fut1.await };
|
|
|
|
// Lint
|
|
let fut = async { async { 42 }.await };
|
|
|
|
// Do not lint: not a single expression
|
|
let fut = async {
|
|
func1(10).await;
|
|
func2().await
|
|
};
|
|
|
|
// Do not lint: expression contains `.await`
|
|
let fut = async { func1(func2().await.len()).await };
|
|
}
|
|
|
|
#[allow(clippy::let_and_return)]
|
|
fn capture_local() -> impl Future<Output = i32> {
|
|
let fut = async { 17 };
|
|
// Lint
|
|
async move { fut.await }
|
|
}
|
|
|
|
fn capture_local_closure(s: &str) -> impl Future<Output = &str> {
|
|
let f = move || std::future::ready(s);
|
|
// Do not lint: `f` would not live long enough
|
|
async move { f().await }
|
|
}
|
|
|
|
#[allow(clippy::let_and_return)]
|
|
fn capture_arg(s: &str) -> impl Future<Output = &str> {
|
|
let fut = async move { s };
|
|
// Lint
|
|
async move { fut.await }
|
|
}
|
|
|
|
fn capture_future_arg<T>(f: impl Future<Output = T>) -> impl Future<Output = T> {
|
|
// Lint
|
|
async { f.await }
|
|
}
|
|
|
|
fn capture_func_result<FN, F, T>(f: FN) -> impl Future<Output = T>
|
|
where
|
|
F: Future<Output = T>,
|
|
FN: FnOnce() -> F,
|
|
{
|
|
// Do not lint, as f() would be evaluated prematurely
|
|
async { f().await }
|
|
}
|
|
|
|
fn double_future(f: impl Future<Output = impl Future<Output = u32>>) -> impl Future<Output = u32> {
|
|
// Do not lint, we will get a `.await` outside a `.async`
|
|
async { f.await.await }
|
|
}
|
|
|
|
fn await_in_async<F, R>(f: F) -> impl Future<Output = u32>
|
|
where
|
|
F: FnOnce() -> R,
|
|
R: Future<Output = u32>,
|
|
{
|
|
// Lint
|
|
async { async { f().await + 1 }.await }
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct F {}
|
|
|
|
impl F {
|
|
async fn run(&self) {}
|
|
}
|
|
|
|
pub async fn run() {
|
|
let f = F {};
|
|
let c = f.clone();
|
|
// Do not lint: `c` would not live long enough
|
|
spawn(async move { c.run().await });
|
|
let _f = f;
|
|
}
|
|
|
|
fn spawn<F: Future + 'static>(_: F) {}
|
|
|
|
async fn work(_: &str) {}
|
|
|
|
fn capture() {
|
|
let val = "Hello World".to_owned();
|
|
// Do not lint: `val` would not live long enough
|
|
spawn(async { work(&{ val }).await });
|
|
}
|
|
|
|
fn await_from_macro() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
($e:expr) => {
|
|
$e.await
|
|
};
|
|
}
|
|
// Do not lint: the macro may change in the future
|
|
// or return different things depending on its argument
|
|
async { mac!(async { 42 }) }
|
|
}
|
|
|
|
fn async_expr_from_macro() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
() => {
|
|
async { 42 }
|
|
};
|
|
}
|
|
// Do not lint: the macro may change in the future
|
|
async { mac!().await }
|
|
}
|
|
|
|
fn async_expr_from_macro_deep() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
() => {
|
|
async { 42 }
|
|
};
|
|
}
|
|
// Do not lint: the macro may change in the future
|
|
async { ({ mac!() }).await }
|
|
}
|
|
|
|
fn all_from_macro() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
() => {
|
|
// Lint
|
|
async { async { 42 }.await }
|
|
};
|
|
}
|
|
mac!()
|
|
}
|
|
|
|
fn parts_from_macro() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
($e: expr) => {
|
|
// Do not lint: `$e` might not always be side-effect free
|
|
async { $e.await }
|
|
};
|
|
}
|
|
mac!(async { 42 })
|
|
}
|
|
|
|
fn safe_parts_from_macro() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
($e: expr) => {
|
|
// Lint
|
|
async { async { $e }.await }
|
|
};
|
|
}
|
|
mac!(42)
|
|
}
|
|
|
|
fn parts_from_macro_deep() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
($e: expr) => {
|
|
// Do not lint: `$e` might not always be side-effect free
|
|
async { ($e,).0.await }
|
|
};
|
|
}
|
|
let f = std::future::ready(42);
|
|
mac!(f)
|
|
}
|
|
|
|
fn await_from_macro_deep() -> impl Future<Output = u32> {
|
|
macro_rules! mac {
|
|
($e:expr) => {{ $e }.await};
|
|
}
|
|
// Do not lint: the macro may change in the future
|
|
// or return different things depending on its argument
|
|
async { mac!(async { 42 }) }
|
|
}
|
|
|
|
// Issue 11959
|
|
fn from_into_future(a: impl IntoFuture<Output = u32>) -> impl Future<Output = u32> {
|
|
// Do not lint: `a` is not equivalent to this expression
|
|
async { a.await }
|
|
}
|