From 262b148d8830efa4773f05b27403f94e47d27f52 Mon Sep 17 00:00:00 2001 From: bors Date: Sat, 1 Jan 2022 13:16:49 +0000 Subject: [PATCH] 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 --- clippy_lints/src/return_self_not_must_use.rs | 36 ++++++++++++++++---- tests/ui/return_self_not_must_use.stderr | 5 +++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/return_self_not_must_use.rs b/clippy_lints/src/return_self_not_must_use.rs index b57ec96bc..935bbc37d 100644 --- a/clippy_lints/src/return_self_not_must_use.rs +++ b/clippy_lints/src/return_self_not_must_use.rs @@ -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" ); } } diff --git a/tests/ui/return_self_not_must_use.stderr b/tests/ui/return_self_not_must_use.stderr index 3793a5559..8af10cb65 100644 --- a/tests/ui/return_self_not_must_use.stderr +++ b/tests/ui/return_self_not_must_use.stderr @@ -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