1
1
use rustc_hir:: { Arm , Expr , ExprKind , Node } ;
2
+ use rustc_middle:: ty;
2
3
use rustc_span:: sym;
3
4
4
5
use crate :: {
5
- lints:: { DropCopyDiag , DropRefDiag , ForgetCopyDiag , ForgetRefDiag } ,
6
+ lints:: {
7
+ DropCopyDiag , DropRefDiag , ForgetCopyDiag , ForgetRefDiag , UndroppedManuallyDropsDiag ,
8
+ UndroppedManuallyDropsSuggestion ,
9
+ } ,
6
10
LateContext , LateLintPass , LintContext ,
7
11
} ;
8
12
@@ -109,7 +113,29 @@ declare_lint! {
109
113
"calls to `std::mem::forget` with a value that implements Copy"
110
114
}
111
115
112
- declare_lint_pass ! ( DropForgetUseless => [ DROPPING_REFERENCES , FORGETTING_REFERENCES , DROPPING_COPY_TYPES , FORGETTING_COPY_TYPES ] ) ;
116
+ declare_lint ! {
117
+ /// The `undropped_manually_drops` lint check for calls to `std::mem::drop` with
118
+ /// a value of `std::mem::ManuallyDrop` which doesn't drop.
119
+ ///
120
+ /// ### Example
121
+ ///
122
+ /// ```rust,compile_fail
123
+ /// struct S;
124
+ /// drop(std::mem::ManuallyDrop::new(S));
125
+ /// ```
126
+ ///
127
+ /// {{produces}}
128
+ ///
129
+ /// ### Explanation
130
+ ///
131
+ /// `ManuallyDrop` does not drop it's inner value so calling `std::mem::drop` will
132
+ /// not drop the inner value of the `ManuallyDrop` either.
133
+ pub UNDROPPED_MANUALLY_DROPS ,
134
+ Deny ,
135
+ "calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value"
136
+ }
137
+
138
+ declare_lint_pass ! ( DropForgetUseless => [ DROPPING_REFERENCES , FORGETTING_REFERENCES , DROPPING_COPY_TYPES , FORGETTING_COPY_TYPES , UNDROPPED_MANUALLY_DROPS ] ) ;
113
139
114
140
impl < ' tcx > LateLintPass < ' tcx > for DropForgetUseless {
115
141
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
@@ -134,6 +160,20 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
134
160
sym:: mem_forget if is_copy => {
135
161
cx. emit_spanned_lint ( FORGETTING_COPY_TYPES , expr. span , ForgetCopyDiag { arg_ty, label : arg. span } ) ;
136
162
}
163
+ sym:: mem_drop if let ty:: Adt ( adt, _) = arg_ty. kind ( ) && adt. is_manually_drop ( ) => {
164
+ cx. emit_spanned_lint (
165
+ UNDROPPED_MANUALLY_DROPS ,
166
+ expr. span ,
167
+ UndroppedManuallyDropsDiag {
168
+ arg_ty,
169
+ label : arg. span ,
170
+ suggestion : UndroppedManuallyDropsSuggestion {
171
+ start_span : arg. span . shrink_to_lo ( ) ,
172
+ end_span : arg. span . shrink_to_hi ( )
173
+ }
174
+ }
175
+ ) ;
176
+ }
137
177
_ => return ,
138
178
} ;
139
179
}
0 commit comments