Uplift clippy::undropped_manually_drops to rustc
This commit is contained in:
parent
a9baa16482
commit
52300bf8d8
5 changed files with 126 additions and 2 deletions
|
@ -492,6 +492,10 @@ lint_tykind = usage of `ty::TyKind`
|
|||
lint_tykind_kind = usage of `ty::TyKind::<kind>`
|
||||
.suggestion = try using `ty::<kind>` directly
|
||||
|
||||
lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
|
||||
.label = argument has type `{$arg_ty}`
|
||||
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
||||
|
||||
lint_ungated_async_fn_track_caller = `#[track_caller]` on async functions is a no-op
|
||||
.label = this function will not propagate the caller location
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -699,6 +699,25 @@ pub struct ForgetCopyDiag<'a> {
|
|||
pub label: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_undropped_manually_drops)]
|
||||
pub struct UndroppedManuallyDropsDiag<'a> {
|
||||
pub arg_ty: Ty<'a>,
|
||||
#[label]
|
||||
pub label: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UndroppedManuallyDropsSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
|
||||
pub struct UndroppedManuallyDropsSuggestion {
|
||||
#[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")]
|
||||
pub start_span: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub end_span: Span,
|
||||
}
|
||||
|
||||
// invalid_from_utf8.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
pub enum InvalidFromUtf8Diag {
|
||||
|
|
19
tests/ui/lint/undropped_manually_drops.rs
Normal file
19
tests/ui/lint/undropped_manually_drops.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
// check-fail
|
||||
|
||||
struct S;
|
||||
|
||||
fn main() {
|
||||
let mut manual1 = std::mem::ManuallyDrop::new(S);
|
||||
let mut manual2 = std::mem::ManuallyDrop::new(S);
|
||||
let mut manual3 = std::mem::ManuallyDrop::new(S);
|
||||
|
||||
drop(std::mem::ManuallyDrop::new(S)); //~ ERROR calls to `std::mem::drop`
|
||||
drop(manual1); //~ ERROR calls to `std::mem::drop`
|
||||
drop({ manual3 }); //~ ERROR calls to `std::mem::drop`
|
||||
|
||||
// These lines will drop `S` and should be okay.
|
||||
unsafe {
|
||||
std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
|
||||
std::mem::ManuallyDrop::drop(&mut manual2);
|
||||
}
|
||||
}
|
42
tests/ui/lint/undropped_manually_drops.stderr
Normal file
42
tests/ui/lint/undropped_manually_drops.stderr
Normal file
|
@ -0,0 +1,42 @@
|
|||
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
|
||||
--> $DIR/undropped_manually_drops.rs:10:5
|
||||
|
|
||||
LL | drop(std::mem::ManuallyDrop::new(S));
|
||||
| ^^^^^------------------------------^
|
||||
| |
|
||||
| argument has type `ManuallyDrop<S>`
|
||||
|
|
||||
= note: `#[deny(undropped_manually_drops)]` on by default
|
||||
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
||||
|
|
||||
LL | drop(std::mem::ManuallyDrop::into_inner(std::mem::ManuallyDrop::new(S)));
|
||||
| +++++++++++++++++++++++++++++++++++ +
|
||||
|
||||
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
|
||||
--> $DIR/undropped_manually_drops.rs:11:5
|
||||
|
|
||||
LL | drop(manual1);
|
||||
| ^^^^^-------^
|
||||
| |
|
||||
| argument has type `ManuallyDrop<S>`
|
||||
|
|
||||
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
||||
|
|
||||
LL | drop(std::mem::ManuallyDrop::into_inner(manual1));
|
||||
| +++++++++++++++++++++++++++++++++++ +
|
||||
|
||||
error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
|
||||
--> $DIR/undropped_manually_drops.rs:12:5
|
||||
|
|
||||
LL | drop({ manual3 });
|
||||
| ^^^^^-----------^
|
||||
| |
|
||||
| argument has type `ManuallyDrop<S>`
|
||||
|
|
||||
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
|
||||
|
Loading…
Add table
Reference in a new issue