Add new lint for undropped ManuallyDrop values

This commit is contained in:
cgm616 2020-10-16 11:12:37 -04:00
parent 85959be606
commit 4a4f998c39
5 changed files with 79 additions and 0 deletions

View File

@ -1979,6 +1979,7 @@ Released 2018-09-13
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops
[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc
[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init

View File

@ -314,6 +314,7 @@ mod transmuting_null;
mod trivially_copy_pass_by_ref;
mod try_err;
mod types;
mod undropped_manually_drops;
mod unicode;
mod unit_return_expecting_ord;
mod unnamed_address;
@ -862,6 +863,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&types::UNIT_CMP,
&types::UNNECESSARY_CAST,
&types::VEC_BOX,
&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
&unicode::INVISIBLE_CHARACTERS,
&unicode::NON_ASCII_LITERAL,
&unicode::UNICODE_NOT_NFC,
@ -1137,6 +1139,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(move || box disallowed_method::DisallowedMethod::new(&disallowed_methods));
store.register_early_pass(|| box asm_syntax::InlineAsmX86AttSyntax);
store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
store.register_late_pass(|| box undropped_manually_drops::UndroppedManuallyDrops);
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
@ -1790,6 +1793,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
LintId::of(&types::CAST_REF_TO_MUT),
LintId::of(&types::UNIT_CMP),
LintId::of(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
LintId::of(&unicode::INVISIBLE_CHARACTERS),
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),

View File

@ -0,0 +1,49 @@
use rustc_lint::{LateLintPass, LateContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_hir::*;
use crate::utils::{match_function_call, is_type_lang_item, paths, span_lint_and_help};
declare_clippy_lint! {
/// **What it does:** Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`.
///
/// **Why is this bad?** The safe `drop` function does not drop the inner value of a `ManuallyDrop`.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// struct S;
/// drop(std::mem::ManuallyDrop::new(S));
/// ```
/// Use instead:
/// ```rust
/// struct S;
/// unsafe {
/// std::mem::ManuallyDrop::drop(std::mem::ManuallyDrop::new(S));
/// }
/// ```
pub UNDROPPED_MANUALLY_DROPS,
correctness,
"use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value"
}
declare_lint_pass!(UndroppedManuallyDrops => [UNDROPPED_MANUALLY_DROPS]);
impl LateLintPass<'tcx> for UndroppedManuallyDrops {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some(ref args) = match_function_call(cx, expr, &paths::DROP) {
let ty = cx.typeck_results().expr_ty(&args[0]);
if is_type_lang_item(cx, ty, lang_items::LangItem::ManuallyDrop) {
span_lint_and_help(
cx,
UNDROPPED_MANUALLY_DROPS,
expr.span,
"the inner value of this ManuallyDrop will not be dropped",
None,
"to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop"
);
}
}
}
}

View File

@ -2412,6 +2412,13 @@ vec![
deprecation: None,
module: "trait_bounds",
},
Lint {
name: "undropped_manually_drops",
group: "correctness",
desc: "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value",
deprecation: None,
module: "undropped_manually_drops",
},
Lint {
name: "unicode_not_nfc",
group: "pedantic",

View File

@ -0,0 +1,18 @@
#![warn(clippy::undropped_manually_drops)]
struct S;
fn main() {
let f = drop;
let manual = std::mem::ManuallyDrop::new(S);
// These lines will not drop `S`
drop(std::mem::ManuallyDrop::new(S));
f(manual);
// These lines will
unsafe {
std::mem::ManuallyDrop::drop(std::mem::ManuallyDrop::new(S));
std::mem::ManuallyDrop::drop(manual);
}
}