1
Fork 0

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.
This commit is contained in:
Ruby Lazuli 2022-02-11 18:21:02 -06:00
parent 6499c5e7fc
commit 6dcf5d8fde
No known key found for this signature in database
GPG key ID: F7E7992881AB576D
6 changed files with 527 additions and 164 deletions

View file

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