@@ -7,7 +7,7 @@ use rustc_span::sym;
7
7
declare_clippy_lint ! {
8
8
/// ### What it does
9
9
/// Checks for usage of `std::mem::forget(t)` where `t` is
10
- /// `Drop`.
10
+ /// `Drop` or has a field that implements `Drop` .
11
11
///
12
12
/// ### Why is this bad?
13
13
/// `std::mem::forget(t)` prevents `t` from running its
@@ -29,18 +29,26 @@ declare_lint_pass!(MemForget => [MEM_FORGET]);
29
29
30
30
impl < ' tcx > LateLintPass < ' tcx > for MemForget {
31
31
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) {
32
- if let ExprKind :: Call ( path_expr, [ ref first_arg, ..] ) = e. kind {
33
- if let ExprKind :: Path ( ref qpath) = path_expr. kind {
34
- if let Some ( def_id) = cx. qpath_res ( qpath, path_expr. hir_id ) . opt_def_id ( ) {
35
- if cx. tcx . is_diagnostic_item ( sym:: mem_forget, def_id) {
36
- let forgot_ty = cx. typeck_results ( ) . expr_ty ( first_arg) ;
37
-
38
- if forgot_ty. ty_adt_def ( ) . map_or ( false , |def| def. has_dtor ( cx. tcx ) ) {
39
- span_lint ( cx, MEM_FORGET , e. span , "usage of `mem::forget` on `Drop` type" ) ;
40
- }
32
+ if let ExprKind :: Call ( path_expr, [ ref first_arg, ..] ) = e. kind
33
+ && let ExprKind :: Path ( ref qpath) = path_expr. kind
34
+ && let Some ( def_id) = cx. qpath_res ( qpath, path_expr. hir_id ) . opt_def_id ( )
35
+ && cx. tcx . is_diagnostic_item ( sym:: mem_forget, def_id)
36
+ && let forgot_ty = cx. typeck_results ( ) . expr_ty ( first_arg)
37
+ && forgot_ty. needs_drop ( cx. tcx , cx. param_env )
38
+ {
39
+ span_lint (
40
+ cx,
41
+ MEM_FORGET ,
42
+ e. span ,
43
+ & format ! (
44
+ "usage of `mem::forget` on {}" ,
45
+ if forgot_ty. ty_adt_def( ) . map_or( false , |def| def. has_dtor( cx. tcx) ) {
46
+ "`Drop` type"
47
+ } else {
48
+ "type with `Drop` fields"
41
49
}
42
- }
43
- }
50
+ ) ,
51
+ ) ;
44
52
}
45
53
}
46
54
}
0 commit comments