11use rustc_hir:: { Arm , Expr , ExprKind , Node } ;
2+ use rustc_middle:: ty;
23use rustc_span:: sym;
34
45use crate :: {
5- lints:: { DropCopyDiag , DropRefDiag , ForgetCopyDiag , ForgetRefDiag } ,
6+ lints:: {
7+ DropCopyDiag , DropRefDiag , ForgetCopyDiag , ForgetRefDiag , UndroppedManuallyDropsDiag ,
8+ UndroppedManuallyDropsSuggestion ,
9+ } ,
610 LateContext , LateLintPass , LintContext ,
711} ;
812
@@ -109,7 +113,29 @@ declare_lint! {
109113 "calls to `std::mem::forget` with a value that implements Copy"
110114}
111115
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 ] ) ;
113139
114140impl < ' tcx > LateLintPass < ' tcx > for DropForgetUseless {
115141 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
@@ -134,6 +160,20 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
134160 sym:: mem_forget if is_copy => {
135161 cx. emit_spanned_lint ( FORGETTING_COPY_TYPES , expr. span , ForgetCopyDiag { arg_ty, label : arg. span } ) ;
136162 }
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+ }
137177 _ => return ,
138178 } ;
139179 }
0 commit comments