Auto merge of #11967 - samueltardieu:issue-11959, r=llogiq

Do not consider `async { (impl IntoFuture).await }` as redundant

changelog: [`redundant_async_block`]: do not trigger on `IntoFuture` instances

Fix #11959
This commit is contained in:
bors 2023-12-25 12:42:26 +00:00
commit 99c783843d
3 changed files with 18 additions and 2 deletions

View file

@ -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};
@ -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())

View file

@ -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
@ -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 }
}

View file

@ -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
@ -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 }
}