Skip to content

Commit 1962ce0

Browse files
committed
Auto merge of rust-lang#8146 - GuillaumeGomez:must-use-self, r=xFrednet
Don't emit RETURN_SELF_NOT_MUST_USE lint if `Self` already is marked as `#[must_use]` New bug discovered with this lint. Hopefully, this is the last one. --- changelog: none
2 parents 25e90ec + 07a00ef commit 1962ce0

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

clippy_lints/src/return_self_not_must_use.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use clippy_utils::{diagnostics::span_lint, must_use_attr, nth_arg, return_ty};
1+
use clippy_utils::ty::is_must_use_ty;
2+
use clippy_utils::{diagnostics::span_lint, nth_arg, return_ty};
23
use rustc_hir::def_id::LocalDefId;
34
use rustc_hir::intravisit::FnKind;
45
use rustc_hir::{Body, FnDecl, HirId, TraitItem, TraitItemKind};
@@ -50,16 +51,18 @@ fn check_method(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'tcx>, fn_def: LocalD
5051
if decl.implicit_self.has_implicit_self();
5152
// We only show this warning for public exported methods.
5253
if cx.access_levels.is_exported(fn_def);
54+
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
55+
if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
5356
if cx.tcx.visibility(fn_def.to_def_id()).is_public();
54-
// No need to warn if the attribute is already present.
55-
if must_use_attr(cx.tcx.hir().attrs(hir_id)).is_none();
5657
let ret_ty = return_ty(cx, hir_id);
5758
let self_arg = nth_arg(cx, hir_id, 0);
5859
// If `Self` has the same type as the returned type, then we want to warn.
5960
//
6061
// For this check, we don't want to remove the reference on the returned type because if
6162
// there is one, we shouldn't emit a warning!
6263
if self_arg.peel_refs() == ret_ty;
64+
// If `Self` is already marked as `#[must_use]`, no need for the attribute here.
65+
if !is_must_use_ty(cx, ret_ty);
6366

6467
then {
6568
span_lint(
@@ -86,8 +89,6 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
8689
// We are only interested in methods, not in functions or associated functions.
8790
if matches!(kind, FnKind::Method(_, _, _));
8891
if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id);
89-
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
90-
if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
9192
if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id());
9293
// We don't want this method to be te implementation of a trait because the
9394
// `#[must_use]` should be put on the trait definition directly.

tests/ui/return_self_not_must_use.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ impl Whatever for Bar {
4545
self
4646
}
4747
}
48+
49+
#[must_use]
50+
pub struct Foo;
51+
52+
impl Foo {
53+
// There should be no warning here! (`Foo` already implements `#[must_use]`)
54+
fn foo(&self) -> Self {
55+
Self
56+
}
57+
}

0 commit comments

Comments
 (0)