Mark let_underscore_drop as uplifted
This commit is contained in:
parent
4f142aa105
commit
ff893366c1
15 changed files with 121 additions and 253 deletions
|
|
@ -1,7 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::{is_must_use_ty, is_type_diagnostic_item, match_type};
|
||||
use clippy_utils::{is_must_use_func_call, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::{Local, PatKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
|
@ -60,45 +59,7 @@ declare_clippy_lint! {
|
|||
"non-binding let on a synchronization lock"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for `let _ = <expr>`
|
||||
/// where expr has a type that implements `Drop`
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// This statement immediately drops the initializer
|
||||
/// expression instead of extending its lifetime to the end of the scope, which
|
||||
/// is often not intended. To extend the expression's lifetime to the end of the
|
||||
/// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
|
||||
/// explicitly drop the expression, `std::mem::drop` conveys your intention
|
||||
/// better and is less error-prone.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// # struct DroppableItem;
|
||||
/// {
|
||||
/// let _ = DroppableItem;
|
||||
/// // ^ dropped here
|
||||
/// /* more code */
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// # struct DroppableItem;
|
||||
/// {
|
||||
/// let _droppable = DroppableItem;
|
||||
/// /* more code */
|
||||
/// // dropped at end of scope
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.50.0"]
|
||||
pub LET_UNDERSCORE_DROP,
|
||||
pedantic,
|
||||
"non-binding let on a type that implements `Drop`"
|
||||
}
|
||||
|
||||
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_DROP]);
|
||||
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK]);
|
||||
|
||||
const SYNC_GUARD_SYMS: [Symbol; 3] = [sym::MutexGuard, sym::RwLockReadGuard, sym::RwLockWriteGuard];
|
||||
|
||||
|
|
@ -110,64 +71,49 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
|
||||
if in_external_macro(cx.tcx.sess, local.span) {
|
||||
return;
|
||||
}
|
||||
if !in_external_macro(cx.tcx.sess, local.span)
|
||||
&& let PatKind::Wild = local.pat.kind
|
||||
&& let Some(init) = local.init
|
||||
{
|
||||
let init_ty = cx.typeck_results().expr_ty(init);
|
||||
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
|
||||
GenericArgKind::Type(inner_ty) => {
|
||||
SYNC_GUARD_SYMS
|
||||
.iter()
|
||||
.any(|&sym| is_type_diagnostic_item(cx, inner_ty, sym))
|
||||
|| SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path))
|
||||
},
|
||||
|
||||
if_chain! {
|
||||
if let PatKind::Wild = local.pat.kind;
|
||||
if let Some(init) = local.init;
|
||||
then {
|
||||
let init_ty = cx.typeck_results().expr_ty(init);
|
||||
let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
|
||||
GenericArgKind::Type(inner_ty) => {
|
||||
SYNC_GUARD_SYMS
|
||||
.iter()
|
||||
.any(|&sym| is_type_diagnostic_item(cx, inner_ty, sym))
|
||||
|| SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path))
|
||||
},
|
||||
|
||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||
});
|
||||
if contains_sync_guard {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_LOCK,
|
||||
local.span,
|
||||
"non-binding let on a synchronization lock",
|
||||
None,
|
||||
"consider using an underscore-prefixed named \
|
||||
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
|
||||
});
|
||||
if contains_sync_guard {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_LOCK,
|
||||
local.span,
|
||||
"non-binding let on a synchronization lock",
|
||||
None,
|
||||
"consider using an underscore-prefixed named \
|
||||
binding or dropping explicitly with `std::mem::drop`",
|
||||
);
|
||||
} else if init_ty.needs_drop(cx.tcx, cx.param_env) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_DROP,
|
||||
local.span,
|
||||
"non-binding `let` on a type that implements `Drop`",
|
||||
None,
|
||||
"consider using an underscore-prefixed named \
|
||||
binding or dropping explicitly with `std::mem::drop`",
|
||||
);
|
||||
} else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_MUST_USE,
|
||||
local.span,
|
||||
"non-binding let on an expression with `#[must_use]` type",
|
||||
None,
|
||||
"consider explicitly using expression value",
|
||||
);
|
||||
} else if is_must_use_func_call(cx, init) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_MUST_USE,
|
||||
local.span,
|
||||
"non-binding let on a result of a `#[must_use]` function",
|
||||
None,
|
||||
"consider explicitly using function result",
|
||||
);
|
||||
}
|
||||
);
|
||||
} else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_MUST_USE,
|
||||
local.span,
|
||||
"non-binding let on an expression with `#[must_use]` type",
|
||||
None,
|
||||
"consider explicitly using expression value",
|
||||
);
|
||||
} else if is_must_use_func_call(cx, init) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
LET_UNDERSCORE_MUST_USE,
|
||||
local.span,
|
||||
"non-binding let on a result of a `#[must_use]` function",
|
||||
None,
|
||||
"consider explicitly using function result",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ store.register_lints(&[
|
|||
len_zero::LEN_WITHOUT_IS_EMPTY,
|
||||
len_zero::LEN_ZERO,
|
||||
let_if_seq::USELESS_LET_IF_SEQ,
|
||||
let_underscore::LET_UNDERSCORE_DROP,
|
||||
let_underscore::LET_UNDERSCORE_LOCK,
|
||||
let_underscore::LET_UNDERSCORE_MUST_USE,
|
||||
lifetimes::EXTRA_UNUSED_LIFETIMES,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
|
|||
LintId::of(items_after_statements::ITEMS_AFTER_STATEMENTS),
|
||||
LintId::of(iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR),
|
||||
LintId::of(large_stack_arrays::LARGE_STACK_ARRAYS),
|
||||
LintId::of(let_underscore::LET_UNDERSCORE_DROP),
|
||||
LintId::of(literal_representation::LARGE_DIGIT_GROUPS),
|
||||
LintId::of(literal_representation::UNREADABLE_LITERAL),
|
||||
LintId::of(loops::EXPLICIT_INTO_ITER_LOOP),
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
|
|||
("clippy::disallowed_method", "clippy::disallowed_methods"),
|
||||
("clippy::disallowed_type", "clippy::disallowed_types"),
|
||||
("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"),
|
||||
("clippy::for_loop_over_option", "for_loops_over_fallibles"),
|
||||
("clippy::for_loop_over_result", "for_loops_over_fallibles"),
|
||||
("clippy::identity_conversion", "clippy::useless_conversion"),
|
||||
("clippy::if_let_some_result", "clippy::match_result_ok"),
|
||||
("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
|
||||
|
|
@ -31,10 +29,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
|
|||
("clippy::to_string_in_display", "clippy::recursive_format_impl"),
|
||||
("clippy::zero_width_space", "clippy::invisible_characters"),
|
||||
("clippy::drop_bounds", "drop_bounds"),
|
||||
("clippy::for_loop_over_option", "for_loops_over_fallibles"),
|
||||
("clippy::for_loop_over_result", "for_loops_over_fallibles"),
|
||||
("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
|
||||
("clippy::into_iter_on_array", "array_into_iter"),
|
||||
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
|
||||
("clippy::invalid_ref", "invalid_value"),
|
||||
("clippy::let_underscore_drop", "let_underscore_drop"),
|
||||
("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"),
|
||||
("clippy::panic_params", "non_fmt_panics"),
|
||||
("clippy::positional_named_format_parameters", "named_arguments_used_positionally"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue