@@ -7,7 +7,7 @@ use rustc_span::sym;
77declare_clippy_lint ! {
88 /// ### What it does
99 /// Checks for usage of `std::mem::forget(t)` where `t` is
10- /// `Drop`.
10+ /// `Drop` or has a field that implements `Drop` .
1111 ///
1212 /// ### Why is this bad?
1313 /// `std::mem::forget(t)` prevents `t` from running its
@@ -29,18 +29,26 @@ declare_lint_pass!(MemForget => [MEM_FORGET]);
2929
3030impl < ' tcx > LateLintPass < ' tcx > for MemForget {
3131 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"
4149 }
42- }
43- }
50+ ) ,
51+ ) ;
4452 }
4553 }
4654}
0 commit comments