LintId::of(&types::UNIT_CMP),
LintId::of(&types::UNNECESSARY_CAST),
LintId::of(&types::VEC_BOX),
+ 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),
-use rustc_lint::{LateLintPass, LateContext};
+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};
-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.
+ /// **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;
/// unsafe {
- /// std::mem::ManuallyDrop::drop(std::mem::ManuallyDrop::new(S));
+ /// std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
/// }
/// ```
pub 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"
+ "to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop",
);
}
}
}
-}
\ No newline at end of file
+}
struct S;
fn main() {
- let f = drop;
- let manual = std::mem::ManuallyDrop::new(S);
+ 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`
+ // These lines will not drop `S` and should be linted
drop(std::mem::ManuallyDrop::new(S));
- f(manual);
+ drop(manual1);
- // These lines will
+ // 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(std::mem::ManuallyDrop::new(S));
- std::mem::ManuallyDrop::drop(manual);
+ std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
+ std::mem::ManuallyDrop::drop(&mut manual3);
+ g(&mut manual4);
}
}
--- /dev/null
+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
+