diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2022-06-06 11:17:38 -0400 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2022-08-19 10:54:55 -0400 |
| commit | 8acc4d2f1e255e0e97e48b7a285a7d6db4a03bd6 (patch) | |
| tree | fe4841372a44097c8df7a64e8ca63e2a3b120ef7 | |
| parent | d8d4a135ea2bc460033c75d4a56d21ae977b9ae2 (diff) | |
| download | rust-8acc4d2f1e255e0e97e48b7a285a7d6db4a03bd6.tar.gz rust-8acc4d2f1e255e0e97e48b7a285a7d6db4a03bd6.zip | |
Move `VecResizeToZero` into `Methods` lint pass
| -rw-r--r-- | clippy_lints/src/lib.register_all.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_correctness.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_lints.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 27 | ||||
| -rw-r--r-- | clippy_lints/src/methods/vec_resize_to_zero.rs | 45 | ||||
| -rw-r--r-- | clippy_lints/src/vec_resize_to_zero.rs | 64 | ||||
| -rw-r--r-- | tests/ui/vec_resize_to_zero.rs | 12 | ||||
| -rw-r--r-- | tests/ui/vec_resize_to_zero.stderr | 10 |
9 files changed, 88 insertions, 78 deletions
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs index bb5b2866268..4128096b43a 100644 --- a/clippy_lints/src/lib.register_all.rs +++ b/clippy_lints/src/lib.register_all.rs @@ -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), diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs index d30e69b2240..bb94037ec2e 100644 --- a/clippy_lints/src/lib.register_correctness.rs +++ b/clippy_lints/src/lib.register_correctness.rs @@ -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), ]) diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs index f5497c6bd6b..1b275516dfc 100644 --- a/clippy_lints/src/lib.register_lints.rs +++ b/clippy_lints/src/lib.register_lints.rs @@ -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, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index cfcd4e3d141..ff68fbd1964 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -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 || { diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 54a0275da96..1a225c9bc95 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -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); }, diff --git a/clippy_lints/src/methods/vec_resize_to_zero.rs b/clippy_lints/src/methods/vec_resize_to_zero.rs new file mode 100644 index 00000000000..02d8364cb29 --- /dev/null +++ b/clippy_lints/src/methods/vec_resize_to_zero.rs @@ -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, + ); + }, + ); + } + } +} diff --git a/clippy_lints/src/vec_resize_to_zero.rs b/clippy_lints/src/vec_resize_to_zero.rs deleted file mode 100644 index 0fee3e812d2..00000000000 --- a/clippy_lints/src/vec_resize_to_zero.rs +++ /dev/null @@ -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, - ); - }, - ); - } - } - } -} diff --git a/tests/ui/vec_resize_to_zero.rs b/tests/ui/vec_resize_to_zero.rs index 7ed27439ec6..a8307e741cf 100644 --- a/tests/ui/vec_resize_to_zero.rs +++ b/tests/ui/vec_resize_to_zero.rs @@ -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") } diff --git a/tests/ui/vec_resize_to_zero.stderr b/tests/ui/vec_resize_to_zero.stderr index feb846298c6..7428cf62d6c 100644 --- a/tests/ui/vec_resize_to_zero.stderr +++ b/tests/ui/vec_resize_to_zero.stderr @@ -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... |
