return_self_not_must_use document #[must_use] on the type

Inspired by a discussion in rust-lang/rust-clippy#8197

---

r? `@llogiq`

changelog: none

The lint is this on nightly, therefore no changelog entry for you xD
This commit is contained in:
bors 2022-01-01 13:16:49 +00:00
parent c736a63123
commit 262b148d88
2 changed files with 35 additions and 6 deletions

View file

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_must_use_ty;
use clippy_utils::{diagnostics::span_lint, nth_arg, return_ty};
use clippy_utils::{nth_arg, return_ty};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, HirId, TraitItem, TraitItemKind};
@ -13,25 +14,46 @@ declare_clippy_lint! {
/// This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.
///
/// ### Why is this bad?
/// It prevents to "forget" to use the newly created value.
/// Methods returning `Self` often create new values, having the `#[must_use]` attribute
/// prevents users from "forgetting" to use the newly created value.
///
/// The `#[must_use]` attribute can be added to the type itself to ensure that instances
/// are never forgotten. Functions returning a type marked with `#[must_use]` will not be
/// linted, as the usage is already enforced by the type attribute.
///
/// ### Limitations
/// This lint is only applied on methods taking a `self` argument. It would be mostly noise
/// if it was added on constructors for example.
///
/// ### Example
/// Missing attribute
/// ```rust
/// pub struct Bar;
///
/// impl Bar {
/// // Bad
/// pub fn bar(&self) -> Self {
/// Self
/// }
/// }
/// ```
///
/// // Good
/// It's better to have the `#[must_use]` attribute on the method like this:
/// ```rust
/// pub struct Bar;
/// impl Bar {
/// #[must_use]
/// pub fn foo(&self) -> Self {
/// pub fn bar(&self) -> Self {
/// Self
/// }
/// }
/// ```
///
/// Or on the type definition like this:
/// ```rust
/// #[must_use]
/// pub struct Bar;
/// impl Bar {
/// pub fn bar(&self) -> Self {
/// Self
/// }
/// }
@ -65,11 +87,13 @@ fn check_method(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'tcx>, fn_def: LocalD
if !is_must_use_ty(cx, ret_ty);
then {
span_lint(
span_lint_and_help(
cx,
RETURN_SELF_NOT_MUST_USE,
span,
"missing `#[must_use]` attribute on a method returning `Self`",
None,
"consider adding the `#[must_use]` attribute to the method or directly to the `Self` type"
);
}
}

View file

@ -5,6 +5,7 @@ LL | fn what(&self) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::return-self-not-must-use` implied by `-D warnings`
= help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
error: missing `#[must_use]` attribute on a method returning `Self`
--> $DIR/return_self_not_must_use.rs:17:5
@ -13,6 +14,8 @@ LL | / pub fn foo(&self) -> Self {
LL | | Self
LL | | }
| |_____^
|
= help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
error: missing `#[must_use]` attribute on a method returning `Self`
--> $DIR/return_self_not_must_use.rs:20:5
@ -21,6 +24,8 @@ LL | / pub fn bar(self) -> Self {
LL | | self
LL | | }
| |_____^
|
= help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type
error: aborting due to 3 previous errors