1+ use clippy_utils:: diagnostics:: span_lint_and_help;
12use clippy_utils:: ty:: is_must_use_ty;
2- use clippy_utils:: { diagnostics :: span_lint , nth_arg, return_ty} ;
3+ use clippy_utils:: { nth_arg, return_ty} ;
34use rustc_hir:: def_id:: LocalDefId ;
45use rustc_hir:: intravisit:: FnKind ;
56use rustc_hir:: { Body , FnDecl , HirId , TraitItem , TraitItemKind } ;
@@ -13,25 +14,46 @@ declare_clippy_lint! {
1314 /// This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.
1415 ///
1516 /// ### Why is this bad?
16- /// It prevents to "forget" to use the newly created value.
17+ /// Methods returning `Self` often create new values, having the `#[must_use]` attribute
18+ /// prevents users from "forgetting" to use the newly created value.
19+ ///
20+ /// The `#[must_use]` attribute can be added to the type itself to ensure that instances
21+ /// are never forgotten. Functions returning a type marked with `#[must_use]` will not be
22+ /// linted, as the usage is already enforced by the type attribute.
1723 ///
1824 /// ### Limitations
1925 /// This lint is only applied on methods taking a `self` argument. It would be mostly noise
2026 /// if it was added on constructors for example.
2127 ///
2228 /// ### Example
29+ /// Missing attribute
2330 /// ```rust
2431 /// pub struct Bar;
25- ///
2632 /// impl Bar {
2733 /// // Bad
2834 /// pub fn bar(&self) -> Self {
2935 /// Self
3036 /// }
37+ /// }
38+ /// ```
3139 ///
32- /// // Good
40+ /// It's better to have the `#[must_use]` attribute on the method like this:
41+ /// ```rust
42+ /// pub struct Bar;
43+ /// impl Bar {
3344 /// #[must_use]
34- /// pub fn foo(&self) -> Self {
45+ /// pub fn bar(&self) -> Self {
46+ /// Self
47+ /// }
48+ /// }
49+ /// ```
50+ ///
51+ /// Or on the type definition like this:
52+ /// ```rust
53+ /// #[must_use]
54+ /// pub struct Bar;
55+ /// impl Bar {
56+ /// pub fn bar(&self) -> Self {
3557 /// Self
3658 /// }
3759 /// }
@@ -65,11 +87,13 @@ fn check_method(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'tcx>, fn_def: LocalD
6587 if !is_must_use_ty( cx, ret_ty) ;
6688
6789 then {
68- span_lint (
90+ span_lint_and_help (
6991 cx,
7092 RETURN_SELF_NOT_MUST_USE ,
7193 span,
7294 "missing `#[must_use]` attribute on a method returning `Self`" ,
95+ None ,
96+ "consider adding the `#[must_use]` attribute to the method or directly to the `Self` type"
7397 ) ;
7498 }
7599 }
0 commit comments