Skip to content

Commit

Permalink
Do not consider async { (impl IntoFuture).await } as redundant
Browse files Browse the repository at this point in the history
  • Loading branch information
samueltardieu committed Dec 15, 2023
1 parent 29bdc8b commit e52405a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
4 changes: 4 additions & 0 deletions clippy_lints/src/redundant_async_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ops::ControlFlow;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::peel_blocks;
use clippy_utils::source::{snippet, walk_span_to_context};
use clippy_utils::ty::implements_trait;
use clippy_utils::visitors::for_each_expr;
use rustc_errors::Applicability;
use rustc_hir::{Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource};
Expand Down Expand Up @@ -49,6 +50,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {
let Some(expr) = desugar_await(peel_blocks(body_expr)) &&
// The await prefix must not come from a macro as its content could change in the future.
expr.span.eq_ctxt(body_expr.span) &&
// The await prefix must implement Future, as implementing IntoFuture is not enough.
let Some(future_trait) = cx.tcx.lang_items().future_trait() &&
implements_trait(cx, cx.typeck_results().expr_ty(expr), future_trait, &[]) &&
// An async block does not have immediate side-effects from a `.await` point-of-view.
(!expr.can_have_side_effects() || desugar_async_block(cx, expr).is_some()) &&
let Some(shortened_span) = walk_span_to_context(expr.span, span.ctxt())
Expand Down
8 changes: 7 additions & 1 deletion tests/ui/redundant_async_block.fixed
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(unused, clippy::manual_async_fn)]
#![warn(clippy::redundant_async_block)]

use std::future::Future;
use std::future::{Future, IntoFuture};

async fn func1(n: usize) -> usize {
n + 1
Expand Down Expand Up @@ -189,3 +189,9 @@ fn await_from_macro_deep() -> impl Future<Output = u32> {
// 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 }
}
8 changes: 7 additions & 1 deletion tests/ui/redundant_async_block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(unused, clippy::manual_async_fn)]
#![warn(clippy::redundant_async_block)]

use std::future::Future;
use std::future::{Future, IntoFuture};

async fn func1(n: usize) -> usize {
n + 1
Expand Down Expand Up @@ -189,3 +189,9 @@ fn await_from_macro_deep() -> impl Future<Output = u32> {
// 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 }
}

0 comments on commit e52405a

Please sign in to comment.