diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index aca4149199010..fd5bcc472729e 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -986,6 +986,38 @@ pub(crate) struct DropCopyDiag<'a> { pub sugg: UseLetUnderscoreIgnoreSuggestion, } +#[derive(Diagnostic)] +#[diag( + "calls to {$from_fn -> + [true] `std::ptr::drop_in_place` + *[false] `drop_in_place` + } with a pointer to a reference instead of a pointer to an owned value does nothing" +)] +pub(crate) struct DropInPlaceRefDiag<'a> { + pub from_fn: bool, + pub arg_ty: Ty<'a>, + #[label("argument has type `{$arg_ty}`")] + pub label: Span, + #[subdiagnostic] + pub sugg: UseLetUnderscoreIgnoreSuggestion, +} + +#[derive(Diagnostic)] +#[diag( + "calls to {$from_fn -> + [true] `std::ptr::drop_in_place` + *[false] `drop_in_place` + } with a pointer to a value that implements `Copy` does nothing" +)] +pub(crate) struct DropInPlaceCopyDiag<'a> { + pub from_fn: bool, + pub arg_ty: Ty<'a>, + #[label("argument has type `{$arg_ty}`")] + pub label: Span, + #[subdiagnostic] + pub sugg: UseLetUnderscoreIgnoreSuggestion, +} + #[derive(Diagnostic)] #[diag("calls to `std::mem::forget` with a reference instead of an owned value does nothing")] pub(crate) struct ForgetRefDiag<'a> { @@ -1030,6 +1062,30 @@ pub(crate) struct UndroppedManuallyDropsSuggestion { pub end_span: Span, } +#[derive(Diagnostic)] +#[diag( + "calls to `drop_in_place` with a pointer to a `std::mem::ManuallyDrop` instead of the inner value does nothing" +)] +pub(crate) struct UndroppedManuallyDropsInPlaceDiag<'a> { + pub arg_ty: Ty<'a>, + #[label("argument has type `{$arg_ty}`")] + pub label: Span, + #[subdiagnostic] + pub suggestion: UndroppedManuallyDropsInPlaceSuggestion, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + "use `std::mem::ManuallyDrop::drop` to drop the inner value", + applicability = "maybe-incorrect" +)] +pub(crate) struct UndroppedManuallyDropsInPlaceSuggestion { + #[suggestion_part(code = "std::mem::ManuallyDrop::drop(&mut *")] + pub start_span: Span, + #[suggestion_part(code = ")")] + pub end_span: Span, +} + // invalid_from_utf8.rs #[derive(Diagnostic)] pub(crate) enum InvalidFromUtf8Diag { diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 2768a54f0207e..684aa21dfcb3e 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -4,14 +4,17 @@ use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; use crate::diagnostics::{ - DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag, - UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion, + DropCopyDiag, DropInPlaceCopyDiag, DropInPlaceRefDiag, DropRefDiag, ForgetCopyDiag, + ForgetRefDiag, UndroppedManuallyDropsDiag, UndroppedManuallyDropsInPlaceDiag, + UndroppedManuallyDropsInPlaceSuggestion, UndroppedManuallyDropsSuggestion, + UseLetUnderscoreIgnoreSuggestion, }; use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { - /// The `dropping_references` lint checks for calls to `std::mem::drop` with a reference - /// instead of an owned value. + /// The `dropping_references` lint checks for calls to `std::mem::drop` + /// and `std::ptr::drop_in_place` where the dropped type is a reference instead of + /// an owned value. /// /// ### Example /// @@ -34,7 +37,7 @@ declare_lint! { /// is likely what was intended. pub DROPPING_REFERENCES, Warn, - "calls to `std::mem::drop` with a reference instead of an owned value" + "calls to `drop` and `drop_in_place` where the dropped type is a reference instead of an owned value" } declare_lint! { @@ -61,8 +64,8 @@ declare_lint! { } declare_lint! { - /// The `dropping_copy_types` lint checks for calls to `std::mem::drop` with a value - /// that derives the Copy trait. + /// The `dropping_copy_types` lint checks for calls to `std::mem::drop` + /// and `std::ptr::drop_in_place` where the dropped value implements the `Copy` trait. /// /// ### Example /// @@ -81,7 +84,7 @@ declare_lint! { /// value will be copied and moved into the function on invocation. pub DROPPING_COPY_TYPES, Warn, - "calls to `std::mem::drop` with a value that implements Copy" + "calls to `drop` and `drop_in_place` where the dropped value implements Copy" } declare_lint! { @@ -113,8 +116,9 @@ declare_lint! { } 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. + /// The `undropped_manually_drops` lint check for calls to `std::mem::drop` + /// and `std::ptr::drop_in_place` where the dropped value is `std::mem::ManuallyDrop` + /// which doesn't drop. /// /// ### Example /// @@ -131,21 +135,32 @@ declare_lint! { /// 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" + "calls to `drop` and `drop_in_place` where the dropped value is `std::mem::ManuallyDrop`" } 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>) { - if let ExprKind::Call(path, [arg]) = expr.kind - && let ExprKind::Path(ref qpath) = path.kind - && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) + let (fn_did, arg) = match expr.kind { + // matching on `function(, ...)` + ExprKind::Call(path, [arg]) if let ExprKind::Path(ref qpath) = path.kind => { + (cx.qpath_res(qpath, path.hir_id).opt_def_id(), arg) + } + // matching on `.method(..)` + ExprKind::MethodCall(_, arg, _, _) => { + (cx.typeck_results().type_dependent_def_id(expr.hir_id), arg) + } + _ => return, + }; + + if let Some(fn_did) = fn_did + && let Some(fn_name) = cx.tcx.get_diagnostic_name(fn_did) { let arg_ty = cx.typeck_results().expr_ty(arg); let is_copy = cx.type_is_copy_modulo_regions(arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); + let let_underscore_ignore_sugg = || { if let Some((_, node)) = cx.tcx.hir_parent_iter(expr.hir_id).nth(0) && let Node::Stmt(stmt) = node @@ -161,6 +176,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { UseLetUnderscoreIgnoreSuggestion::Note } }; + match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { cx.emit_span_lint( @@ -169,6 +185,22 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { DropRefDiag { arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg() }, ); } + sym::ptr_drop_in_place | sym::ptr_drop_in_place_self + if let &ty::RawPtr(inner_ty, _mutbl) = arg_ty.kind() + && inner_ty.is_ref() + && !drop_is_single_call_in_arm => + { + cx.emit_span_lint( + DROPPING_REFERENCES, + expr.span, + DropInPlaceRefDiag { + arg_ty, + label: arg.span, + sugg: let_underscore_ignore_sugg(), + from_fn: fn_name == sym::ptr_drop_in_place, + }, + ); + } sym::mem_forget if arg_ty.is_ref() => { cx.emit_span_lint( FORGETTING_REFERENCES, @@ -191,6 +223,22 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { }, ); } + sym::ptr_drop_in_place | sym::ptr_drop_in_place_self + if let &ty::RawPtr(inner_ty, _mutbl) = arg_ty.kind() + && cx.type_is_copy_modulo_regions(inner_ty) + && !drop_is_single_call_in_arm => + { + cx.emit_span_lint( + DROPPING_COPY_TYPES, + expr.span, + DropInPlaceCopyDiag { + arg_ty, + label: arg.span, + sugg: let_underscore_ignore_sugg(), + from_fn: fn_name == sym::ptr_drop_in_place, + }, + ); + } sym::mem_forget if is_copy => { cx.emit_span_lint( FORGETTING_COPY_TYPES, @@ -219,6 +267,24 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { }, ); } + sym::ptr_drop_in_place | sym::ptr_drop_in_place_self + if let &ty::RawPtr(inner_ty, _mutbl) = arg_ty.kind() + && let ty::Adt(adt, _) = inner_ty.kind() + && adt.is_manually_drop() => + { + cx.emit_span_lint( + UNDROPPED_MANUALLY_DROPS, + expr.span, + UndroppedManuallyDropsInPlaceDiag { + arg_ty, + label: arg.span, + suggestion: UndroppedManuallyDropsInPlaceSuggestion { + start_span: expr.span.shrink_to_lo().until(arg.span.shrink_to_lo()), + end_span: arg.span.shrink_to_hi().until(expr.span.shrink_to_hi()), + }, + }, + ); + } _ => return, }; } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 165cf7855b83b..b4fa4d180f638 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1631,6 +1631,8 @@ symbols! { ptr_const_is_null, ptr_copy, ptr_copy_nonoverlapping, + ptr_drop_in_place, + ptr_drop_in_place_self, ptr_from_ref, ptr_guaranteed_cmp, ptr_is_null, diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 327e4ad3fb0e0..f3d2ba635320e 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1375,6 +1375,7 @@ impl *mut T { /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place() #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_unstable(feature = "const_drop_in_place", issue = "109342")] + #[rustc_diagnostic_item = "ptr_drop_in_place_self"] #[inline(always)] pub const unsafe fn drop_in_place(self) where diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs index 9126b7e8575b0..30e72122cf47c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs @@ -3,6 +3,8 @@ //@error-in-other-file: /retag .* for Unique permission .* only grants SharedReadOnly permission/ +#![allow(dropping_copy_types)] + fn main() { unsafe { let x = 0u8; diff --git a/src/tools/miri/tests/pass/drop_in_place.rs b/src/tools/miri/tests/pass/drop_in_place.rs index cac8d76dd9d41..d3643ff0e019f 100644 --- a/src/tools/miri/tests/pass/drop_in_place.rs +++ b/src/tools/miri/tests/pass/drop_in_place.rs @@ -2,6 +2,8 @@ // valid when dropped. This test confirms that behavior. // This is not a stable guarantee! +#![allow(dropping_copy_types)] + use std::ptr; fn main() { diff --git a/tests/ui/lint/dropping_copy_types.rs b/tests/ui/lint/dropping_copy_types.rs index ef1291325affe..904b11f1b997e 100644 --- a/tests/ui/lint/dropping_copy_types.rs +++ b/tests/ui/lint/dropping_copy_types.rs @@ -51,6 +51,26 @@ fn main() { drop(a3); drop(a4); //~ WARN calls to `std::mem::drop` drop(a5); + + unsafe { + let mut s6 = SomeStruct {}; + std::ptr::drop_in_place(&raw mut s6); //~ WARN calls to `std::ptr::drop_in_place` + + let mut s7 = SomeStruct {}; + let ptr = &raw mut s7; + std::ptr::drop_in_place(ptr); //~ WARN calls to `std::ptr::drop_in_place` + + std::ptr::drop_in_place(&mut SomeStruct {} as *mut _); //~ WARN calls to `std::ptr::drop_in_place` + } + + unsafe { + let mut s8 = SomeStruct {}; + (&raw mut s8).drop_in_place(); //~ WARN calls to `drop_in_place` + + let mut s9 = SomeStruct {}; + let ptr = &raw mut s9; + ptr.drop_in_place(); //~ WARN calls to `drop_in_place` + } } #[allow(unused)] diff --git a/tests/ui/lint/dropping_copy_types.stderr b/tests/ui/lint/dropping_copy_types.stderr index 41aa66a4efc68..1ddc5a8143241 100644 --- a/tests/ui/lint/dropping_copy_types.stderr +++ b/tests/ui/lint/dropping_copy_types.stderr @@ -102,8 +102,78 @@ LL - drop(a4); LL + let _ = a4; | +warning: calls to `std::ptr::drop_in_place` with a pointer to a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types.rs:57:9 + | +LL | std::ptr::drop_in_place(&raw mut s6); + | ^^^^^^^^^^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `*mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(&raw mut s6); +LL + let _ = &raw mut s6; + | + +warning: calls to `std::ptr::drop_in_place` with a pointer to a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types.rs:61:9 + | +LL | std::ptr::drop_in_place(ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | + | argument has type `*mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(ptr); +LL + let _ = ptr; + | + +warning: calls to `std::ptr::drop_in_place` with a pointer to a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types.rs:63:9 + | +LL | std::ptr::drop_in_place(&mut SomeStruct {} as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^----------------------------^ + | | + | argument has type `*mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(&mut SomeStruct {} as *mut _); +LL + let _ = &mut SomeStruct {} as *mut _; + | + +warning: calls to `drop_in_place` with a pointer to a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types.rs:68:9 + | +LL | (&raw mut s8).drop_in_place(); + | -------------^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - (&raw mut s8).drop_in_place(); +LL + let _ = (&raw mut s8); + | + +warning: calls to `drop_in_place` with a pointer to a value that implements `Copy` does nothing + --> $DIR/dropping_copy_types.rs:72:9 + | +LL | ptr.drop_in_place(); + | ---^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - ptr.drop_in_place(); +LL + let _ = ptr; + | + warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/dropping_copy_types.rs:71:13 + --> $DIR/dropping_copy_types.rs:91:13 | LL | drop(println_and(13)); | ^^^^^---------------^ @@ -117,7 +187,7 @@ LL + let _ = println_and(13); | warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/dropping_copy_types.rs:74:14 + --> $DIR/dropping_copy_types.rs:94:14 | LL | 3 if drop(println_and(14)) == () => (), | ^^^^^---------------^ @@ -127,7 +197,7 @@ LL | 3 if drop(println_and(14)) == () => (), = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing - --> $DIR/dropping_copy_types.rs:76:14 + --> $DIR/dropping_copy_types.rs:96:14 | LL | 4 => drop(2), | ^^^^^-^ @@ -136,5 +206,5 @@ LL | 4 => drop(2), | = note: use `let _ = ...` to ignore the expression or result -warning: 10 warnings emitted +warning: 15 warnings emitted diff --git a/tests/ui/lint/dropping_references.rs b/tests/ui/lint/dropping_references.rs index 7f0e7c3e35b72..0a2e48bf7f167 100644 --- a/tests/ui/lint/dropping_references.rs +++ b/tests/ui/lint/dropping_references.rs @@ -21,6 +21,26 @@ fn main() { let ref reference3 = SomeStruct; drop(reference3); //~ WARN calls to `std::mem::drop` + + unsafe { + let mut reference1 = &SomeStruct; + std::ptr::drop_in_place(&raw mut reference1); //~ WARN calls to `std::ptr::drop_in_place` + + let mut reference2 = &mut SomeStruct; + std::ptr::drop_in_place(&raw mut reference2); //~ WARN calls to `std::ptr::drop_in_place` + + std::ptr::drop_in_place(&mut &SomeStruct as *mut _); //~ WARN calls to `std::ptr::drop_in_place` + } + + unsafe { + let mut reference1 = &SomeStruct; + (&raw mut reference1).drop_in_place(); //~ WARN calls to `drop_in_place` + + let mut reference2 = &mut SomeStruct; + (&raw mut reference2).drop_in_place(); //~ WARN calls to `drop_in_place` + + (&mut &SomeStruct as *mut &SomeStruct).drop_in_place(); //~ WARN calls to `drop_in_place` + } } #[allow(dead_code)] diff --git a/tests/ui/lint/dropping_references.stderr b/tests/ui/lint/dropping_references.stderr index 312334b82ad4b..81a1f4b4797b8 100644 --- a/tests/ui/lint/dropping_references.stderr +++ b/tests/ui/lint/dropping_references.stderr @@ -101,8 +101,92 @@ LL - drop(reference3); LL + let _ = reference3; | +warning: calls to `std::ptr::drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:27:9 + | +LL | std::ptr::drop_in_place(&raw mut reference1); + | ^^^^^^^^^^^^^^^^^^^^^^^^-------------------^ + | | + | argument has type `*mut &SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(&raw mut reference1); +LL + let _ = &raw mut reference1; + | + +warning: calls to `std::ptr::drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:30:9 + | +LL | std::ptr::drop_in_place(&raw mut reference2); + | ^^^^^^^^^^^^^^^^^^^^^^^^-------------------^ + | | + | argument has type `*mut &mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(&raw mut reference2); +LL + let _ = &raw mut reference2; + | + +warning: calls to `std::ptr::drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:32:9 + | +LL | std::ptr::drop_in_place(&mut &SomeStruct as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^--------------------------^ + | | + | argument has type `*mut &SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - std::ptr::drop_in_place(&mut &SomeStruct as *mut _); +LL + let _ = &mut &SomeStruct as *mut _; + | + +warning: calls to `drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:37:9 + | +LL | (&raw mut reference1).drop_in_place(); + | ---------------------^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut &SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - (&raw mut reference1).drop_in_place(); +LL + let _ = (&raw mut reference1); + | + +warning: calls to `drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:40:9 + | +LL | (&raw mut reference2).drop_in_place(); + | ---------------------^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut &mut SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - (&raw mut reference2).drop_in_place(); +LL + let _ = (&raw mut reference2); + | + +warning: calls to `drop_in_place` with a pointer to a reference instead of a pointer to an owned value does nothing + --> $DIR/dropping_references.rs:42:9 + | +LL | (&mut &SomeStruct as *mut &SomeStruct).drop_in_place(); + | --------------------------------------^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut &SomeStruct` + | +help: use `let _ = ...` to ignore the expression or result + | +LL - (&mut &SomeStruct as *mut &SomeStruct).drop_in_place(); +LL + let _ = (&mut &SomeStruct as *mut &SomeStruct); + | + warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing - --> $DIR/dropping_references.rs:28:5 + --> $DIR/dropping_references.rs:48:5 | LL | drop(&val); | ^^^^^----^ @@ -116,7 +200,7 @@ LL + let _ = &val; | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing - --> $DIR/dropping_references.rs:36:5 + --> $DIR/dropping_references.rs:56:5 | LL | std::mem::drop(&SomeStruct); | ^^^^^^^^^^^^^^^-----------^ @@ -130,7 +214,7 @@ LL + let _ = &SomeStruct; | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing - --> $DIR/dropping_references.rs:91:13 + --> $DIR/dropping_references.rs:111:13 | LL | drop(println_and(&13)); | ^^^^^----------------^ @@ -144,7 +228,7 @@ LL + let _ = println_and(&13); | warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing - --> $DIR/dropping_references.rs:94:14 + --> $DIR/dropping_references.rs:114:14 | LL | 3 if drop(println_and(&14)) == () => (), | ^^^^^----------------^ @@ -154,7 +238,7 @@ LL | 3 if drop(println_and(&14)) == () => (), = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing - --> $DIR/dropping_references.rs:96:14 + --> $DIR/dropping_references.rs:116:14 | LL | 4 => drop(&2), | ^^^^^--^ @@ -163,5 +247,5 @@ LL | 4 => drop(&2), | = note: use `let _ = ...` to ignore the expression or result -warning: 12 warnings emitted +warning: 18 warnings emitted diff --git a/tests/ui/lint/undropped_manually_drops.rs b/tests/ui/lint/undropped_manually_drops.rs index 737bd5cd0f472..bb8765d0bcf92 100644 --- a/tests/ui/lint/undropped_manually_drops.rs +++ b/tests/ui/lint/undropped_manually_drops.rs @@ -11,6 +11,14 @@ fn main() { drop(manual1); //~ ERROR calls to `std::mem::drop` drop({ manual3 }); //~ ERROR calls to `std::mem::drop` + let mut manual4 = std::mem::ManuallyDrop::new(S); + let mut manual5 = std::mem::ManuallyDrop::new(S); + + unsafe { + std::ptr::drop_in_place(&raw mut manual4); //~ ERROR calls to `drop_in_place` + (&raw mut manual5).drop_in_place(); //~ ERROR calls to `drop_in_place` + } + // These lines will drop `S` and should be okay. unsafe { std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S)); diff --git a/tests/ui/lint/undropped_manually_drops.stderr b/tests/ui/lint/undropped_manually_drops.stderr index 156b647ebd3a7..39ff12c2e7e6f 100644 --- a/tests/ui/lint/undropped_manually_drops.stderr +++ b/tests/ui/lint/undropped_manually_drops.stderr @@ -38,5 +38,33 @@ help: use `std::mem::ManuallyDrop::into_inner` to get the inner value LL | drop(std::mem::ManuallyDrop::into_inner({ manual3 })); | +++++++++++++++++++++++++++++++++++ + -error: aborting due to 3 previous errors +error: calls to `drop_in_place` with a pointer to a `std::mem::ManuallyDrop` instead of the inner value does nothing + --> $DIR/undropped_manually_drops.rs:18:9 + | +LL | std::ptr::drop_in_place(&raw mut manual4); + | ^^^^^^^^^^^^^^^^^^^^^^^^----------------^ + | | + | argument has type `*mut ManuallyDrop` + | +help: use `std::mem::ManuallyDrop::drop` to drop the inner value + | +LL - std::ptr::drop_in_place(&raw mut manual4); +LL + std::mem::ManuallyDrop::drop(&mut *&raw mut manual4); + | + +error: calls to `drop_in_place` with a pointer to a `std::mem::ManuallyDrop` instead of the inner value does nothing + --> $DIR/undropped_manually_drops.rs:19:9 + | +LL | (&raw mut manual5).drop_in_place(); + | ------------------^^^^^^^^^^^^^^^^ + | | + | argument has type `*mut ManuallyDrop` + | +help: use `std::mem::ManuallyDrop::drop` to drop the inner value + | +LL - (&raw mut manual5).drop_in_place(); +LL + std::mem::ManuallyDrop::drop(&mut *(&raw mut manual5)); + | + +error: aborting due to 5 previous errors