mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-01 00:49:30 +00:00
Auto merge of #6181 - cgm616:undropped-manually-drops, r=flip1995
Add new lint for undropped ManuallyDrop values Adds a new lint for the following code: ```rust struct S; impl Drop for S { fn drop(&mut self) { println!("drip drop"); } } fn main() { // This will not drop the `S`!!! drop(std::mem::ManuallyDrop::new(S)); unsafe { // This will. std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S)); } } ``` The inner value of a `ManuallyDrop` will not be dropped unless the proper, unsafe drop function is called on it. This lint makes sure that a user does not accidently use the wrong function and forget to drop a `ManuallyDrop` value. Fixes #5581. --- *Please keep the line below* changelog: none
This commit is contained in:
commit
6b01c39e64
6 changed files with 108 additions and 0 deletions
|
@ -1982,6 +1982,7 @@ Released 2018-09-13
|
||||||
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
|
[`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_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
|
[`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
|
[`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
|
[`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
|
[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init
|
||||||
|
|
|
@ -314,6 +314,7 @@ mod transmute;
|
||||||
mod transmuting_null;
|
mod transmuting_null;
|
||||||
mod try_err;
|
mod try_err;
|
||||||
mod types;
|
mod types;
|
||||||
|
mod undropped_manually_drops;
|
||||||
mod unicode;
|
mod unicode;
|
||||||
mod unit_return_expecting_ord;
|
mod unit_return_expecting_ord;
|
||||||
mod unnamed_address;
|
mod unnamed_address;
|
||||||
|
@ -865,6 +866,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
&types::UNIT_CMP,
|
&types::UNIT_CMP,
|
||||||
&types::UNNECESSARY_CAST,
|
&types::UNNECESSARY_CAST,
|
||||||
&types::VEC_BOX,
|
&types::VEC_BOX,
|
||||||
|
&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
|
||||||
&unicode::INVISIBLE_CHARACTERS,
|
&unicode::INVISIBLE_CHARACTERS,
|
||||||
&unicode::NON_ASCII_LITERAL,
|
&unicode::NON_ASCII_LITERAL,
|
||||||
&unicode::UNICODE_NOT_NFC,
|
&unicode::UNICODE_NOT_NFC,
|
||||||
|
@ -1141,6 +1143,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_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::InlineAsmX86AttSyntax);
|
||||||
store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
|
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![
|
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
||||||
|
@ -1528,6 +1531,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
LintId::of(&types::UNIT_CMP),
|
LintId::of(&types::UNIT_CMP),
|
||||||
LintId::of(&types::UNNECESSARY_CAST),
|
LintId::of(&types::UNNECESSARY_CAST),
|
||||||
LintId::of(&types::VEC_BOX),
|
LintId::of(&types::VEC_BOX),
|
||||||
|
LintId::of(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
|
||||||
LintId::of(&unicode::INVISIBLE_CHARACTERS),
|
LintId::of(&unicode::INVISIBLE_CHARACTERS),
|
||||||
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
|
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
|
||||||
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
|
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
|
||||||
|
@ -1800,6 +1804,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
|
LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
|
||||||
LintId::of(&types::CAST_REF_TO_MUT),
|
LintId::of(&types::CAST_REF_TO_MUT),
|
||||||
LintId::of(&types::UNIT_CMP),
|
LintId::of(&types::UNIT_CMP),
|
||||||
|
LintId::of(&undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
|
||||||
LintId::of(&unicode::INVISIBLE_CHARACTERS),
|
LintId::of(&unicode::INVISIBLE_CHARACTERS),
|
||||||
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
|
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
|
||||||
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
|
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
|
||||||
|
|
50
clippy_lints/src/undropped_manually_drops.rs
Normal file
50
clippy_lints/src/undropped_manually_drops.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use crate::utils::{is_type_lang_item, match_function_call, paths, span_lint_and_help};
|
||||||
|
use rustc_hir::{lang_items, Expr};
|
||||||
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
|
||||||
|
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:** Does not catch cases if the user binds `std::mem::drop`
|
||||||
|
/// to a different name and calls it that way.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// struct S;
|
||||||
|
/// drop(std::mem::ManuallyDrop::new(S));
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// struct S;
|
||||||
|
/// unsafe {
|
||||||
|
/// std::mem::ManuallyDrop::drop(&mut 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",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2433,6 +2433,13 @@ vec![
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
module: "trait_bounds",
|
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 {
|
Lint {
|
||||||
name: "unicode_not_nfc",
|
name: "unicode_not_nfc",
|
||||||
group: "pedantic",
|
group: "pedantic",
|
||||||
|
|
26
tests/ui/undropped_manually_drops.rs
Normal file
26
tests/ui/undropped_manually_drops.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#![warn(clippy::undropped_manually_drops)]
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f = std::mem::drop;
|
||||||
|
let g = std::mem::ManuallyDrop::drop;
|
||||||
|
let mut manual1 = std::mem::ManuallyDrop::new(S);
|
||||||
|
let mut manual2 = std::mem::ManuallyDrop::new(S);
|
||||||
|
let mut manual3 = std::mem::ManuallyDrop::new(S);
|
||||||
|
let mut manual4 = std::mem::ManuallyDrop::new(S);
|
||||||
|
|
||||||
|
// These lines will not drop `S` and should be linted
|
||||||
|
drop(std::mem::ManuallyDrop::new(S));
|
||||||
|
drop(manual1);
|
||||||
|
|
||||||
|
// FIXME: this line is not linted, though it should be
|
||||||
|
f(manual2);
|
||||||
|
|
||||||
|
// 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 manual3);
|
||||||
|
g(&mut manual4);
|
||||||
|
}
|
||||||
|
}
|
19
tests/ui/undropped_manually_drops.stderr
Normal file
19
tests/ui/undropped_manually_drops.stderr
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
error: the inner value of this ManuallyDrop will not be dropped
|
||||||
|
--> $DIR/undropped_manually_drops.rs:14:5
|
||||||
|
|
|
||||||
|
LL | drop(std::mem::ManuallyDrop::new(S));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::undropped-manually-drops` implied by `-D warnings`
|
||||||
|
= help: to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop
|
||||||
|
|
||||||
|
error: the inner value of this ManuallyDrop will not be dropped
|
||||||
|
--> $DIR/undropped_manually_drops.rs:15:5
|
||||||
|
|
|
||||||
|
LL | drop(manual1);
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Reference in a new issue