Move VecResizeToZero
into Methods
lint pass
This commit is contained in:
parent
d8d4a135ea
commit
8acc4d2f1e
@ -217,6 +217,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
|||||||
LintId::of(methods::UNNECESSARY_TO_OWNED),
|
LintId::of(methods::UNNECESSARY_TO_OWNED),
|
||||||
LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
|
LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
|
||||||
LintId::of(methods::USELESS_ASREF),
|
LintId::of(methods::USELESS_ASREF),
|
||||||
|
LintId::of(methods::VEC_RESIZE_TO_ZERO),
|
||||||
LintId::of(methods::WRONG_SELF_CONVENTION),
|
LintId::of(methods::WRONG_SELF_CONVENTION),
|
||||||
LintId::of(methods::ZST_OFFSET),
|
LintId::of(methods::ZST_OFFSET),
|
||||||
LintId::of(minmax::MIN_MAX),
|
LintId::of(minmax::MIN_MAX),
|
||||||
@ -344,7 +345,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
|||||||
LintId::of(useless_conversion::USELESS_CONVERSION),
|
LintId::of(useless_conversion::USELESS_CONVERSION),
|
||||||
LintId::of(vec::USELESS_VEC),
|
LintId::of(vec::USELESS_VEC),
|
||||||
LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
|
LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
|
||||||
LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
|
|
||||||
LintId::of(write::POSITIONAL_NAMED_FORMAT_PARAMETERS),
|
LintId::of(write::POSITIONAL_NAMED_FORMAT_PARAMETERS),
|
||||||
LintId::of(write::PRINTLN_EMPTY_STRING),
|
LintId::of(write::PRINTLN_EMPTY_STRING),
|
||||||
LintId::of(write::PRINT_LITERAL),
|
LintId::of(write::PRINT_LITERAL),
|
||||||
|
@ -43,6 +43,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
|
|||||||
LintId::of(methods::SUSPICIOUS_SPLITN),
|
LintId::of(methods::SUSPICIOUS_SPLITN),
|
||||||
LintId::of(methods::UNINIT_ASSUMED_INIT),
|
LintId::of(methods::UNINIT_ASSUMED_INIT),
|
||||||
LintId::of(methods::UNIT_HASH),
|
LintId::of(methods::UNIT_HASH),
|
||||||
|
LintId::of(methods::VEC_RESIZE_TO_ZERO),
|
||||||
LintId::of(methods::ZST_OFFSET),
|
LintId::of(methods::ZST_OFFSET),
|
||||||
LintId::of(minmax::MIN_MAX),
|
LintId::of(minmax::MIN_MAX),
|
||||||
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
|
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
|
||||||
@ -74,5 +75,4 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
|
|||||||
LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
|
LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
|
||||||
LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
|
LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
|
||||||
LintId::of(unwrap::PANICKING_UNWRAP),
|
LintId::of(unwrap::PANICKING_UNWRAP),
|
||||||
LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
|
|
||||||
])
|
])
|
||||||
|
@ -369,6 +369,7 @@ store.register_lints(&[
|
|||||||
methods::UNWRAP_OR_ELSE_DEFAULT,
|
methods::UNWRAP_OR_ELSE_DEFAULT,
|
||||||
methods::UNWRAP_USED,
|
methods::UNWRAP_USED,
|
||||||
methods::USELESS_ASREF,
|
methods::USELESS_ASREF,
|
||||||
|
methods::VEC_RESIZE_TO_ZERO,
|
||||||
methods::WRONG_SELF_CONVENTION,
|
methods::WRONG_SELF_CONVENTION,
|
||||||
methods::ZST_OFFSET,
|
methods::ZST_OFFSET,
|
||||||
minmax::MIN_MAX,
|
minmax::MIN_MAX,
|
||||||
@ -584,7 +585,6 @@ store.register_lints(&[
|
|||||||
useless_conversion::USELESS_CONVERSION,
|
useless_conversion::USELESS_CONVERSION,
|
||||||
vec::USELESS_VEC,
|
vec::USELESS_VEC,
|
||||||
vec_init_then_push::VEC_INIT_THEN_PUSH,
|
vec_init_then_push::VEC_INIT_THEN_PUSH,
|
||||||
vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
|
|
||||||
verbose_file_reads::VERBOSE_FILE_READS,
|
verbose_file_reads::VERBOSE_FILE_READS,
|
||||||
wildcard_imports::ENUM_GLOB_USE,
|
wildcard_imports::ENUM_GLOB_USE,
|
||||||
wildcard_imports::WILDCARD_IMPORTS,
|
wildcard_imports::WILDCARD_IMPORTS,
|
||||||
|
@ -391,7 +391,6 @@ mod use_self;
|
|||||||
mod useless_conversion;
|
mod useless_conversion;
|
||||||
mod vec;
|
mod vec;
|
||||||
mod vec_init_then_push;
|
mod vec_init_then_push;
|
||||||
mod vec_resize_to_zero;
|
|
||||||
mod verbose_file_reads;
|
mod verbose_file_reads;
|
||||||
mod wildcard_imports;
|
mod wildcard_imports;
|
||||||
mod write;
|
mod write;
|
||||||
@ -803,7 +802,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
|
store.register_late_pass(|| Box::new(if_not_else::IfNotElse));
|
||||||
store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
|
store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
|
||||||
store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
|
store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
|
||||||
store.register_late_pass(|| Box::new(vec_resize_to_zero::VecResizeToZero));
|
|
||||||
store.register_late_pass(|| Box::new(panic_in_result_fn::PanicInResultFn));
|
store.register_late_pass(|| Box::new(panic_in_result_fn::PanicInResultFn));
|
||||||
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
|
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
|
||||||
store.register_early_pass(move || {
|
store.register_early_pass(move || {
|
||||||
|
@ -90,6 +90,7 @@ mod unwrap_or_else_default;
|
|||||||
mod unwrap_used;
|
mod unwrap_used;
|
||||||
mod useless_asref;
|
mod useless_asref;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod vec_resize_to_zero;
|
||||||
mod wrong_self_convention;
|
mod wrong_self_convention;
|
||||||
mod zst_offset;
|
mod zst_offset;
|
||||||
|
|
||||||
@ -2907,6 +2908,28 @@ declare_clippy_lint! {
|
|||||||
"Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
|
"Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Finds occurrences of `Vec::resize(0, an_int)`
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// This is probably an argument inversion mistake.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// vec!(1, 2, 3, 4, 5).resize(0, 5)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// vec!(1, 2, 3, 4, 5).clear()
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.46.0"]
|
||||||
|
pub VEC_RESIZE_TO_ZERO,
|
||||||
|
correctness,
|
||||||
|
"emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake"
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Methods {
|
pub struct Methods {
|
||||||
avoid_breaking_exported_api: bool,
|
avoid_breaking_exported_api: bool,
|
||||||
msrv: Option<RustcVersion>,
|
msrv: Option<RustcVersion>,
|
||||||
@ -3026,6 +3049,7 @@ impl_lint_pass!(Methods => [
|
|||||||
STABLE_SORT_PRIMITIVE,
|
STABLE_SORT_PRIMITIVE,
|
||||||
UNIT_HASH,
|
UNIT_HASH,
|
||||||
UNNECESSARY_SORT_BY,
|
UNNECESSARY_SORT_BY,
|
||||||
|
VEC_RESIZE_TO_ZERO,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// Extracts a method call name, args, and `Span` of the method name.
|
/// Extracts a method call name, args, and `Span` of the method name.
|
||||||
@ -3420,6 +3444,9 @@ impl Methods {
|
|||||||
("repeat", [arg]) => {
|
("repeat", [arg]) => {
|
||||||
repeat_once::check(cx, expr, recv, arg);
|
repeat_once::check(cx, expr, recv, arg);
|
||||||
},
|
},
|
||||||
|
("resize", [count_arg, default_arg]) => {
|
||||||
|
vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);
|
||||||
|
},
|
||||||
("sort", []) => {
|
("sort", []) => {
|
||||||
stable_sort_primitive::check(cx, expr, recv);
|
stable_sort_primitive::check(cx, expr, recv);
|
||||||
},
|
},
|
||||||
|
45
clippy_lints/src/methods/vec_resize_to_zero.rs
Normal file
45
clippy_lints/src/methods/vec_resize_to_zero.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
|
use clippy_utils::ty::is_type_diagnostic_item;
|
||||||
|
use if_chain::if_chain;
|
||||||
|
use rustc_ast::LitKind;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::{Expr, ExprKind};
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_span::source_map::Spanned;
|
||||||
|
use rustc_span::{sym, Span};
|
||||||
|
|
||||||
|
use super::VEC_RESIZE_TO_ZERO;
|
||||||
|
|
||||||
|
pub(super) fn check<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
expr: &'tcx Expr<'_>,
|
||||||
|
count_arg: &'tcx Expr<'_>,
|
||||||
|
default_arg: &'tcx Expr<'_>,
|
||||||
|
name_span: Span,
|
||||||
|
) {
|
||||||
|
if_chain! {
|
||||||
|
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
|
||||||
|
if let Some(impl_id) = cx.tcx.impl_of_method(method_id);
|
||||||
|
if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Vec);
|
||||||
|
if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind;
|
||||||
|
if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind;
|
||||||
|
then {
|
||||||
|
let method_call_span = expr.span.with_lo(name_span.lo());
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
VEC_RESIZE_TO_ZERO,
|
||||||
|
expr.span,
|
||||||
|
"emptying a vector with `resize`",
|
||||||
|
|db| {
|
||||||
|
db.help("the arguments may be inverted...");
|
||||||
|
db.span_suggestion(
|
||||||
|
method_call_span,
|
||||||
|
"...or you can empty the vector with",
|
||||||
|
"clear()".to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,64 +0,0 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
|
||||||
use clippy_utils::{match_def_path, paths};
|
|
||||||
use if_chain::if_chain;
|
|
||||||
use rustc_ast::LitKind;
|
|
||||||
use rustc_errors::Applicability;
|
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::{Expr, ExprKind};
|
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
|
||||||
use rustc_span::source_map::Spanned;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
|
||||||
/// ### What it does
|
|
||||||
/// Finds occurrences of `Vec::resize(0, an_int)`
|
|
||||||
///
|
|
||||||
/// ### Why is this bad?
|
|
||||||
/// This is probably an argument inversion mistake.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
/// ```rust
|
|
||||||
/// vec!(1, 2, 3, 4, 5).resize(0, 5)
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Use instead:
|
|
||||||
/// ```rust
|
|
||||||
/// vec!(1, 2, 3, 4, 5).clear()
|
|
||||||
/// ```
|
|
||||||
#[clippy::version = "1.46.0"]
|
|
||||||
pub VEC_RESIZE_TO_ZERO,
|
|
||||||
correctness,
|
|
||||||
"emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake"
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint_pass!(VecResizeToZero => [VEC_RESIZE_TO_ZERO]);
|
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for VecResizeToZero {
|
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|
||||||
if_chain! {
|
|
||||||
if let hir::ExprKind::MethodCall(path_segment, args, _) = expr.kind;
|
|
||||||
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
|
|
||||||
if match_def_path(cx, method_def_id, &paths::VEC_RESIZE) && args.len() == 3;
|
|
||||||
if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = args[1].kind;
|
|
||||||
if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = args[2].kind;
|
|
||||||
then {
|
|
||||||
let method_call_span = expr.span.with_lo(path_segment.ident.span.lo());
|
|
||||||
span_lint_and_then(
|
|
||||||
cx,
|
|
||||||
VEC_RESIZE_TO_ZERO,
|
|
||||||
expr.span,
|
|
||||||
"emptying a vector with `resize`",
|
|
||||||
|db| {
|
|
||||||
db.help("the arguments may be inverted...");
|
|
||||||
db.span_suggestion(
|
|
||||||
method_call_span,
|
|
||||||
"...or you can empty the vector with",
|
|
||||||
"clear()".to_string(),
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,19 @@
|
|||||||
#![warn(clippy::vec_resize_to_zero)]
|
#![warn(clippy::vec_resize_to_zero)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let mut v = vec![1, 2, 3, 4, 5];
|
||||||
|
|
||||||
// applicable here
|
// applicable here
|
||||||
vec![1, 2, 3, 4, 5].resize(0, 5);
|
v.resize(0, 5);
|
||||||
|
|
||||||
// not applicable
|
// not applicable
|
||||||
vec![1, 2, 3, 4, 5].resize(2, 5);
|
v.resize(2, 5);
|
||||||
|
|
||||||
|
let mut v = vec!["foo", "bar", "baz"];
|
||||||
|
|
||||||
// applicable here, but only implemented for integer literals for now
|
// applicable here, but only implemented for integer literals for now
|
||||||
vec!["foo", "bar", "baz"].resize(0, "bar");
|
v.resize(0, "bar");
|
||||||
|
|
||||||
// not applicable
|
// not applicable
|
||||||
vec!["foo", "bar", "baz"].resize(2, "bar")
|
v.resize(2, "bar")
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
error: emptying a vector with `resize`
|
error: emptying a vector with `resize`
|
||||||
--> $DIR/vec_resize_to_zero.rs:5:5
|
--> $DIR/vec_resize_to_zero.rs:7:5
|
||||||
|
|
|
|
||||||
LL | vec![1, 2, 3, 4, 5].resize(0, 5);
|
LL | v.resize(0, 5);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^------------
|
| ^^------------
|
||||||
| |
|
| |
|
||||||
| help: ...or you can empty the vector with: `clear()`
|
| help: ...or you can empty the vector with: `clear()`
|
||||||
|
|
|
|
||||||
= note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
|
= note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
|
||||||
= help: the arguments may be inverted...
|
= help: the arguments may be inverted...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user