1
1
use rustc_hir:: { Arm , Expr , ExprKind , Node } ;
2
2
use rustc_span:: sym;
3
3
4
- use crate :: { lints:: { DropRefDiag , DropCopyDiag , ForgetRefDiag } , LateContext , LateLintPass , LintContext } ;
4
+ use crate :: {
5
+ lints:: { DropCopyDiag , DropRefDiag , ForgetCopyDiag , ForgetRefDiag } ,
6
+ LateContext , LateLintPass , LintContext ,
7
+ } ;
5
8
6
9
declare_lint ! {
7
10
/// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference
@@ -78,7 +81,35 @@ declare_lint! {
78
81
"calls to `std::mem::drop` with a value that implements Copy"
79
82
}
80
83
81
- declare_lint_pass ! ( DropForgetUseless => [ DROP_REF , FORGET_REF , DROP_COPY ] ) ;
84
+ declare_lint ! {
85
+ /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value
86
+ /// that derives the Copy trait.
87
+ ///
88
+ /// ### Example
89
+ ///
90
+ /// ```rust
91
+ /// let x: i32 = 42; // i32 implements Copy
92
+ /// std::mem::forget(x); // A copy of x is passed to the function, leaving the
93
+ /// // original unaffected
94
+ /// ```
95
+ ///
96
+ /// {{produces}}
97
+ ///
98
+ /// ### Explanation
99
+ ///
100
+ /// Calling `std::mem::forget` [does nothing for types that
101
+ /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
102
+ /// value will be copied and moved into the function on invocation.
103
+ ///
104
+ /// An alternative, but also valid, explanation is that Copy types do not
105
+ /// implement the Drop trait, which means they have no destructors. Without a
106
+ /// destructor, there is nothing for `std::mem::forget` to ignore.
107
+ pub FORGET_COPY ,
108
+ Warn ,
109
+ "calls to `std::mem::forget` with a value that implements Copy"
110
+ }
111
+
112
+ declare_lint_pass ! ( DropForgetUseless => [ DROP_REF , FORGET_REF , DROP_COPY , FORGET_COPY ] ) ;
82
113
83
114
impl < ' tcx > LateLintPass < ' tcx > for DropForgetUseless {
84
115
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
@@ -100,6 +131,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
100
131
sym:: mem_drop if is_copy && !drop_is_single_call_in_arm => {
101
132
cx. emit_spanned_lint ( DROP_COPY , expr. span , DropCopyDiag { arg_ty, note : arg. span } ) ;
102
133
}
134
+ sym:: mem_forget if is_copy => {
135
+ cx. emit_spanned_lint ( FORGET_COPY , expr. span , ForgetCopyDiag { arg_ty, note : arg. span } ) ;
136
+ }
103
137
_ => return ,
104
138
} ;
105
139
}
0 commit comments