diff options
Diffstat (limited to 'compiler/rustc_lint/src/drop_forget_useless.rs')
-rw-r--r-- | compiler/rustc_lint/src/drop_forget_useless.rs | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 77e4a7669..467f53d44 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,8 +1,12 @@ use rustc_hir::{Arm, Expr, ExprKind, Node}; +use rustc_middle::ty; use rustc_span::sym; use crate::{ - lints::{DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag}, + lints::{ + DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag, + UndroppedManuallyDropsSuggestion, + }, LateContext, LateLintPass, LintContext, }; @@ -109,7 +113,29 @@ declare_lint! { "calls to `std::mem::forget` with a value that implements Copy" } -declare_lint_pass!(DropForgetUseless => [DROPPING_REFERENCES, FORGETTING_REFERENCES, DROPPING_COPY_TYPES, FORGETTING_COPY_TYPES]); +declare_lint! { + /// The `undropped_manually_drops` lint check for calls to `std::mem::drop` with + /// a value of `std::mem::ManuallyDrop` which doesn't drop. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// struct S; + /// drop(std::mem::ManuallyDrop::new(S)); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// `ManuallyDrop` does not drop it's inner value so calling `std::mem::drop` will + /// not drop the inner value of the `ManuallyDrop` either. + pub UNDROPPED_MANUALLY_DROPS, + Deny, + "calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value" +} + +declare_lint_pass!(DropForgetUseless => [DROPPING_REFERENCES, FORGETTING_REFERENCES, DROPPING_COPY_TYPES, FORGETTING_COPY_TYPES, UNDROPPED_MANUALLY_DROPS]); impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { @@ -134,6 +160,20 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { sym::mem_forget if is_copy => { cx.emit_spanned_lint(FORGETTING_COPY_TYPES, expr.span, ForgetCopyDiag { arg_ty, label: arg.span }); } + sym::mem_drop if let ty::Adt(adt, _) = arg_ty.kind() && adt.is_manually_drop() => { + cx.emit_spanned_lint( + UNDROPPED_MANUALLY_DROPS, + expr.span, + UndroppedManuallyDropsDiag { + arg_ty, + label: arg.span, + suggestion: UndroppedManuallyDropsSuggestion { + start_span: arg.span.shrink_to_lo(), + end_span: arg.span.shrink_to_hi() + } + } + ); + } _ => return, }; } |