Skip to content

Commit 52300bf

Browse files
committed
Uplift clippy::undropped_manually_drops to rustc
1 parent a9baa16 commit 52300bf

File tree

5 files changed

+126
-2
lines changed

5 files changed

+126
-2
lines changed

Diff for: compiler/rustc_lint/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ lint_tykind = usage of `ty::TyKind`
492492
lint_tykind_kind = usage of `ty::TyKind::<kind>`
493493
.suggestion = try using `ty::<kind>` directly
494494
495+
lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
496+
.label = argument has type `{$arg_ty}`
497+
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
498+
495499
lint_ungated_async_fn_track_caller = `#[track_caller]` on async functions is a no-op
496500
.label = this function will not propagate the caller location
497501

Diff for: compiler/rustc_lint/src/drop_forget_useless.rs

+42-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use rustc_hir::{Arm, Expr, ExprKind, Node};
2+
use rustc_middle::ty;
23
use rustc_span::sym;
34

45
use 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

114140
impl<'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
}

Diff for: compiler/rustc_lint/src/lints.rs

+19
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,25 @@ pub struct ForgetCopyDiag<'a> {
699699
pub label: Span,
700700
}
701701

702+
#[derive(LintDiagnostic)]
703+
#[diag(lint_undropped_manually_drops)]
704+
pub struct UndroppedManuallyDropsDiag<'a> {
705+
pub arg_ty: Ty<'a>,
706+
#[label]
707+
pub label: Span,
708+
#[subdiagnostic]
709+
pub suggestion: UndroppedManuallyDropsSuggestion,
710+
}
711+
712+
#[derive(Subdiagnostic)]
713+
#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
714+
pub struct UndroppedManuallyDropsSuggestion {
715+
#[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")]
716+
pub start_span: Span,
717+
#[suggestion_part(code = ")")]
718+
pub end_span: Span,
719+
}
720+
702721
// invalid_from_utf8.rs
703722
#[derive(LintDiagnostic)]
704723
pub enum InvalidFromUtf8Diag {

Diff for: tests/ui/lint/undropped_manually_drops.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// check-fail
2+
3+
struct S;
4+
5+
fn main() {
6+
let mut manual1 = std::mem::ManuallyDrop::new(S);
7+
let mut manual2 = std::mem::ManuallyDrop::new(S);
8+
let mut manual3 = std::mem::ManuallyDrop::new(S);
9+
10+
drop(std::mem::ManuallyDrop::new(S)); //~ ERROR calls to `std::mem::drop`
11+
drop(manual1); //~ ERROR calls to `std::mem::drop`
12+
drop({ manual3 }); //~ ERROR calls to `std::mem::drop`
13+
14+
// These lines will drop `S` and should be okay.
15+
unsafe {
16+
std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
17+
std::mem::ManuallyDrop::drop(&mut manual2);
18+
}
19+
}

Diff for: tests/ui/lint/undropped_manually_drops.stderr

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
2+
--> $DIR/undropped_manually_drops.rs:10:5
3+
|
4+
LL | drop(std::mem::ManuallyDrop::new(S));
5+
| ^^^^^------------------------------^
6+
| |
7+
| argument has type `ManuallyDrop<S>`
8+
|
9+
= note: `#[deny(undropped_manually_drops)]` on by default
10+
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
11+
|
12+
LL | drop(std::mem::ManuallyDrop::into_inner(std::mem::ManuallyDrop::new(S)));
13+
| +++++++++++++++++++++++++++++++++++ +
14+
15+
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
16+
--> $DIR/undropped_manually_drops.rs:11:5
17+
|
18+
LL | drop(manual1);
19+
| ^^^^^-------^
20+
| |
21+
| argument has type `ManuallyDrop<S>`
22+
|
23+
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
24+
|
25+
LL | drop(std::mem::ManuallyDrop::into_inner(manual1));
26+
| +++++++++++++++++++++++++++++++++++ +
27+
28+
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
29+
--> $DIR/undropped_manually_drops.rs:12:5
30+
|
31+
LL | drop({ manual3 });
32+
| ^^^^^-----------^
33+
| |
34+
| argument has type `ManuallyDrop<S>`
35+
|
36+
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
37+
|
38+
LL | drop(std::mem::ManuallyDrop::into_inner({ manual3 }));
39+
| +++++++++++++++++++++++++++++++++++ +
40+
41+
error: aborting due to 3 previous errors
42+

0 commit comments

Comments
 (0)