Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions compiler/rustc_lint/src/drop_forget_useless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;

use crate::lints::{
DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag, UndroppedManuallyDropsDiag,
UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion,
CopyDropInPlaceDiag, DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag,
UndroppedManuallyDropsDiag, UndroppedManuallyDropsSuggestion, UseLetUnderscoreIgnoreSuggestion,
};
use crate::{LateContext, LateLintPass, LintContext};

Expand Down Expand Up @@ -134,7 +134,32 @@ declare_lint! {
"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]);
declare_lint! {
/// The `copy_drop_in_place` lint checks for calls to `std::ptr::drop_in_place` with
/// a pointer that points to a type that derives the Copy trait.
///
/// ### Example
///
/// ```rust
/// let mut x = 0u8;
/// let y = &mut x as *mut _;
/// unsafe {
/// std::ptr::drop_in_place(y);
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
/// Types that implement Copy do not have a destructor so calling
/// `std::ptr::drop_in_place` on a pointer to a type that implements Copy
/// won't do anything.
pub COPY_DROP_IN_PLACE,
Warn,
"calls to `std::ptr::drop_in_place` with a pointer to a value that implements Copy"
}

declare_lint_pass!(DropForgetUseless => [DROPPING_REFERENCES, FORGETTING_REFERENCES, DROPPING_COPY_TYPES, FORGETTING_COPY_TYPES, UNDROPPED_MANUALLY_DROPS,COPY_DROP_IN_PLACE]);

impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
Expand Down Expand Up @@ -219,6 +244,16 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
},
);
}
sym::ptr_drop_in_place
if let ty::RawPtr(inner, ty::Mutability::Mut) = arg_ty.kind()
&& cx.type_is_copy_modulo_regions(*inner) =>
{
cx.emit_span_lint(
COPY_DROP_IN_PLACE,
expr.span,
CopyDropInPlaceDiag { arg_ty, label: arg.span },
);
}
_ => return,
};
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,14 @@ pub(crate) struct UndroppedManuallyDropsSuggestion {
pub end_span: Span,
}

#[derive(Diagnostic)]
#[diag("calls to `std::ptr::drop_in_place` with a pointer to a Copy type does nothing")]
pub(crate) struct CopyDropInPlaceDiag<'a> {
pub arg_ty: Ty<'a>,
#[label("argument has type `{$arg_ty}`")]
pub label: Span,
}

// invalid_from_utf8.rs
#[derive(Diagnostic)]
pub(crate) enum InvalidFromUtf8Diag {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ symbols! {
ptr_const_is_null,
ptr_copy,
ptr_copy_nonoverlapping,
ptr_drop_in_place,
ptr_from_ref,
ptr_guaranteed_cmp,
ptr_is_null,
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/lint/copy_drop_in_place.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Test if the `copy_drop_in_place` lint is working correctly.

#[deny(copy_drop_in_place)]

fn main() {
let mut x = 0u8;
let y = &mut x as *mut _;
unsafe {
std::ptr::drop_in_place(y);
//~^ ERROR calls to `std::ptr::drop_in_place` with a pointer to a Copy type does nothing
}
}
16 changes: 16 additions & 0 deletions tests/ui/lint/copy_drop_in_place.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: calls to `std::ptr::drop_in_place` with a pointer to a Copy type does nothing
--> $DIR/copy_drop_in_place.rs:9:9
|
LL | std::ptr::drop_in_place(y);
| ^^^^^^^^^^^^^^^^^^^^^^^^-^
| |
| argument has type `*mut u8`
|
note: the lint level is defined here
--> $DIR/copy_drop_in_place.rs:3:8
|
LL | #[deny(copy_drop_in_place)]
| ^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Loading