1
Fork 0

Consider #[must_use] annotation on async fn as also affecting the Future::Output

No longer lint against `#[must_use] async fn foo()`.

When encountering a statement that awaits on a `Future`, check if the
`Future`'s parent item is annotated with `#[must_use]` and emit a lint
if so. This effectively makes `must_use` an annotation on the
`Future::Output` instead of only the `Future` itself.

Fix #78149.
This commit is contained in:
Esteban Küber 2022-08-16 07:56:42 -07:00
parent 50bb7a40e1
commit 243496e129
4 changed files with 89 additions and 39 deletions

View file

@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_infer::traits::util::elaborate_predicates_with_span;
use rustc_middle::ty::adjustment;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, DefIdTree, Ty};
use rustc_span::symbol::Symbol;
use rustc_span::symbol::{kw, sym};
use rustc_span::{BytePos, Span};
@ -93,6 +93,18 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
return;
}
if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
&& let ty = cx.typeck_results().expr_ty(&await_expr)
&& let ty::Opaque(def_id, _) = ty.kind()
&& cx.tcx.ty_is_opaque_future(ty)
&& let parent = cx.tcx.parent(*def_id)
&& check_must_use_def(cx, parent, expr.span, "awaited future returned by ", "")
{
// We have a bare `foo().await;` on an opaque type from an async function that was
// annotated with `#[must_use]`.
return;
}
let ty = cx.typeck_results().expr_ty(&expr);
let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1);