mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
Move VecResizeToZero
into Methods
lint pass
This commit is contained in:
parent
d8d4a135ea
commit
8acc4d2f1e
9 changed files with 88 additions and 78 deletions
|
@ -217,6 +217,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
|||
LintId::of(methods::UNNECESSARY_TO_OWNED),
|
||||
LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
|
||||
LintId::of(methods::USELESS_ASREF),
|
||||
LintId::of(methods::VEC_RESIZE_TO_ZERO),
|
||||
LintId::of(methods::WRONG_SELF_CONVENTION),
|
||||
LintId::of(methods::ZST_OFFSET),
|
||||
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(vec::USELESS_VEC),
|
||||
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::PRINTLN_EMPTY_STRING),
|
||||
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::UNINIT_ASSUMED_INIT),
|
||||
LintId::of(methods::UNIT_HASH),
|
||||
LintId::of(methods::VEC_RESIZE_TO_ZERO),
|
||||
LintId::of(methods::ZST_OFFSET),
|
||||
LintId::of(minmax::MIN_MAX),
|
||||
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(unused_io_amount::UNUSED_IO_AMOUNT),
|
||||
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_USED,
|
||||
methods::USELESS_ASREF,
|
||||
methods::VEC_RESIZE_TO_ZERO,
|
||||
methods::WRONG_SELF_CONVENTION,
|
||||
methods::ZST_OFFSET,
|
||||
minmax::MIN_MAX,
|
||||
|
@ -584,7 +585,6 @@ store.register_lints(&[
|
|||
useless_conversion::USELESS_CONVERSION,
|
||||
vec::USELESS_VEC,
|
||||
vec_init_then_push::VEC_INIT_THEN_PUSH,
|
||||
vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
|
||||
verbose_file_reads::VERBOSE_FILE_READS,
|
||||
wildcard_imports::ENUM_GLOB_USE,
|
||||
wildcard_imports::WILDCARD_IMPORTS,
|
||||
|
|
|
@ -391,7 +391,6 @@ mod use_self;
|
|||
mod useless_conversion;
|
||||
mod vec;
|
||||
mod vec_init_then_push;
|
||||
mod vec_resize_to_zero;
|
||||
mod verbose_file_reads;
|
||||
mod wildcard_imports;
|
||||
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(equatable_if_let::PatternEquality));
|
||||
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));
|
||||
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;
|
||||
store.register_early_pass(move || {
|
||||
|
|
|
@ -90,6 +90,7 @@ mod unwrap_or_else_default;
|
|||
mod unwrap_used;
|
||||
mod useless_asref;
|
||||
mod utils;
|
||||
mod vec_resize_to_zero;
|
||||
mod wrong_self_convention;
|
||||
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"
|
||||
}
|
||||
|
||||
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 {
|
||||
avoid_breaking_exported_api: bool,
|
||||
msrv: Option<RustcVersion>,
|
||||
|
@ -3026,6 +3049,7 @@ impl_lint_pass!(Methods => [
|
|||
STABLE_SORT_PRIMITIVE,
|
||||
UNIT_HASH,
|
||||
UNNECESSARY_SORT_BY,
|
||||
VEC_RESIZE_TO_ZERO,
|
||||
]);
|
||||
|
||||
/// Extracts a method call name, args, and `Span` of the method name.
|
||||
|
@ -3420,6 +3444,9 @@ impl Methods {
|
|||
("repeat", [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", []) => {
|
||||
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)]
|
||||
|
||||
fn main() {
|
||||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
|
||||
// applicable here
|
||||
vec![1, 2, 3, 4, 5].resize(0, 5);
|
||||
v.resize(0, 5);
|
||||
|
||||
// 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
|
||||
vec!["foo", "bar", "baz"].resize(0, "bar");
|
||||
v.resize(0, "bar");
|
||||
|
||||
// not applicable
|
||||
vec!["foo", "bar", "baz"].resize(2, "bar")
|
||||
v.resize(2, "bar")
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
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);
|
||||
| ^^^^^^^^^^^^^^^^^^^^------------
|
||||
| |
|
||||
| help: ...or you can empty the vector with: `clear()`
|
||||
LL | v.resize(0, 5);
|
||||
| ^^------------
|
||||
| |
|
||||
| help: ...or you can empty the vector with: `clear()`
|
||||
|
|
||||
= note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`
|
||||
= help: the arguments may be inverted...
|
||||
|
|
Loading…
Reference in a new issue