about summary refs log tree commit diff
path: root/compiler/rustc_passes
diff options
context:
space:
mode:
authorRuby Lazuli <general@patchmixolydic.com>2022-02-11 18:21:02 -0600
committerRuby Lazuli <general@patchmixolydic.com>2022-02-27 08:52:37 -0600
commit6dcf5d8fdeb341a3ec2ed00d2cb4449da35d8623 (patch)
tree3b3e3598c2edfbf34bf9deea021a53efae392ec3 /compiler/rustc_passes
parent6499c5e7fc173a3f55b7a3bd1e6a50e9edef782d (diff)
downloadrust-6dcf5d8fdeb341a3ec2ed00d2cb4449da35d8623.tar.gz
rust-6dcf5d8fdeb341a3ec2ed00d2cb4449da35d8623.zip
Lint against more useless `#[must_use]` attributes
This expands the existing `#[must_use]` check in `unused_attributes`
to lint against pretty much everything `#[must_use]` doesn't support.
Fixes #93906.
Diffstat (limited to 'compiler/rustc_passes')
-rw-r--r--compiler/rustc_passes/src/check_attr.rs35
1 files changed, 34 insertions, 1 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 479a08e43c0..a87b253aae0 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1111,7 +1111,7 @@ impl CheckAttrVisitor<'_> {
     }
 
     /// Warns against some misuses of `#[must_use]`
-    fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, _target: Target) -> bool {
+    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() {
@@ -1131,6 +1131,39 @@ impl CheckAttrVisitor<'_> {
             }
         }
 
+        if !matches!(
+            target,
+            Target::Fn
+                | Target::Enum
+                | Target::Struct
+                | Target::Union
+                | Target::Method(_)
+                | Target::ForeignFn
+                // `impl Trait` in return position can trip
+                // `unused_must_use` if `Trait` is marked as
+                // `#[must_use]`
+                | Target::Trait
+        ) {
+            let article = match target {
+                Target::ExternCrate
+                | Target::OpaqueTy
+                | Target::Enum
+                | Target::Impl
+                | Target::Expression
+                | Target::Arm
+                | Target::AssocConst
+                | Target::AssocTy => "an",
+                _ => "a",
+            };
+
+            self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+                lint.build(&format!(
+                    "`#[must_use]` has no effect when applied to {article} {target}"
+                ))
+                .emit();
+            });
+        }
+
         // For now, its always valid
         true
     }