From 958de5a93864b90e7f90d7a5d0ce082c34232b59 Mon Sep 17 00:00:00 2001 From: Gus Wynn Date: Wed, 6 Oct 2021 13:19:39 -0700 Subject: [PATCH 1/2] warn on must_use use on async fn's --- compiler/rustc_passes/src/check_attr.rs | 32 +++++++++++++++ src/test/ui/lint/unused/unused-async.rs | 43 +++++++++++++++++++++ src/test/ui/lint/unused/unused-async.stderr | 26 +++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/test/ui/lint/unused/unused-async.rs create mode 100644 src/test/ui/lint/unused/unused-async.stderr diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 596d13d2d9a..633a90dd0ec 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -112,6 +112,7 @@ impl CheckAttrVisitor<'tcx> { self.check_default_method_body_is_const(attr, span, target) } sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), + sym::must_use => self.check_must_use(hir_id, &attr, span, target), sym::rustc_const_unstable | sym::rustc_const_stable | sym::unstable @@ -1046,6 +1047,37 @@ impl CheckAttrVisitor<'tcx> { is_valid } + /// Warns against some misuses of `#[must_use]` + fn check_must_use( + &self, + hir_id: HirId, + attr: &Attribute, + span: &Span, + _target: Target, + ) -> bool { + let node = self.tcx.hir().get(hir_id); + if let Some(fn_node) = node.fn_kind() { + if let rustc_hir::IsAsync::Async = fn_node.asyncness() { + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build( + "`must_use` attribute on `async` functions \ + applies to the anonymous `Future` returned by the \ + function, not the value within.", + ) + .span_label( + *span, + "this attribute does nothing, the `Future`s \ + returned by async functions are already `must_use`", + ) + .emit(); + }); + } + } + + // For now, its always valid + true + } + /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid. fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs new file mode 100644 index 00000000000..7d17af11573 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.rs @@ -0,0 +1,43 @@ +// edition:2018 +// run-pass +#![allow(dead_code)] + +#[must_use] +//~^ WARNING `must_use` +async fn test() -> i32 { + 1 +} + + +struct Wowee {} + +impl Wowee { + #[must_use] + //~^ WARNING `must_use` + async fn test_method() -> i32 { + 1 + } +} + +/* FIXME(guswynn) update this test when async-fn-in-traits works +trait Doer { + #[must_use] + async fn test_trait_method() -> i32; + WARNING must_use + async fn test_other_trait() -> i32; +} + +impl Doer for Wowee { + async fn test_trait_method() -> i32 { + 1 + } + #[must_use] + async fn test_other_trait() -> i32 { + WARNING must_use + 1 + } +} +*/ + +fn main() { +} diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr new file mode 100644 index 00000000000..e470b6dac94 --- /dev/null +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -0,0 +1,26 @@ +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. + --> $DIR/unused-async.rs:5:1 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test() -> i32 { +LL | | 1 +LL | | } + | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + | + = note: `#[warn(unused_attributes)]` on by default + +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. + --> $DIR/unused-async.rs:15:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ +LL | +LL | / async fn test_method() -> i32 { +LL | | 1 +LL | | } + | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use` + +warning: 2 warnings emitted + From 83ce771c0f3af07803423918a63ac4f958ca6ea9 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Tue, 16 Nov 2021 09:43:10 -0500 Subject: [PATCH 2/2] Update compiler/rustc_passes/src/check_attr.rs Co-authored-by: Yuki Okushi --- compiler/rustc_passes/src/check_attr.rs | 2 +- src/test/ui/lint/unused/unused-async.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 633a90dd0ec..09d883aad05 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1062,7 +1062,7 @@ impl CheckAttrVisitor<'tcx> { lint.build( "`must_use` attribute on `async` functions \ applies to the anonymous `Future` returned by the \ - function, not the value within.", + function, not the value within", ) .span_label( *span, diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr index e470b6dac94..6bbc9e2bf00 100644 --- a/src/test/ui/lint/unused/unused-async.stderr +++ b/src/test/ui/lint/unused/unused-async.stderr @@ -1,4 +1,4 @@ -warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within --> $DIR/unused-async.rs:5:1 | LL | #[must_use] @@ -11,7 +11,7 @@ LL | | } | = note: `#[warn(unused_attributes)]` on by default -warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within. +warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within --> $DIR/unused-async.rs:15:5 | LL | #[must_use]