diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index a754eea31165..b251f27a4dcf 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -777,7 +777,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::use_self::USE_SELF_INFO, crate::useless_concat::USELESS_CONCAT_INFO, crate::useless_conversion::USELESS_CONVERSION_INFO, - crate::vec::USELESS_VEC_INFO, + crate::useless_vec::USELESS_VEC_INFO, crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO, crate::visibility::NEEDLESS_PUB_SELF_INFO, crate::visibility::PUB_WITHOUT_SHORTHAND_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 033f85e70ef0..a769ed3e580d 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -386,7 +386,7 @@ mod upper_case_acronyms; mod use_self; mod useless_concat; mod useless_conversion; -mod vec; +mod useless_vec; mod vec_init_then_push; mod visibility; mod volatile_composites; @@ -530,7 +530,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co store.register_late_pass(move |_| Box::new(transmute::Transmute::new(conf))); store.register_late_pass(move |_| Box::new(cognitive_complexity::CognitiveComplexity::new(conf))); store.register_late_pass(move |_| Box::new(escape::BoxedLocal::new(conf))); - store.register_late_pass(move |_| Box::new(vec::UselessVec::new(conf))); + store.register_late_pass(move |_| Box::new(useless_vec::UselessVec::new(conf))); store.register_late_pass(move |_| Box::new(panic_unimplemented::PanicUnimplemented::new(conf))); store.register_late_pass(|_| Box::new(strings::StringLitAsBytes)); store.register_late_pass(|_| Box::new(derive::Derive)); diff --git a/clippy_lints/src/ptr/ptr_arg.rs b/clippy_lints/src/ptr/ptr_arg.rs index fd9230f00a8b..4bfff64b1bd4 100644 --- a/clippy_lints/src/ptr/ptr_arg.rs +++ b/clippy_lints/src/ptr/ptr_arg.rs @@ -2,7 +2,7 @@ use super::PTR_ARG; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::res::MaybeResPath; use clippy_utils::source::SpanRangeExt; -use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, sym}; +use clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_expr_use_or_unification_node, is_lint_allowed, sym}; use hir::LifetimeKind; use rustc_abi::ExternAbi; use rustc_errors::Applicability; @@ -23,8 +23,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use std::{fmt, iter}; -use crate::vec::is_allowed_vec_method; - pub(super) fn check_body<'tcx>( cx: &LateContext<'tcx>, body: &Body<'tcx>, @@ -383,7 +381,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[ // Some methods exist on both `[T]` and `Vec`, such as `len`, where the receiver type // doesn't coerce to a slice and our adjusted type check below isn't enough, // but it would still be valid to call with a slice - if is_allowed_vec_method(use_expr) { + if VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&name) { return; } } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/useless_vec.rs similarity index 90% rename from clippy_lints/src/vec.rs rename to clippy_lints/src/useless_vec.rs index b87db836869d..28c339ce2b7d 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/useless_vec.rs @@ -10,7 +10,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; -use clippy_utils::{get_parent_expr, higher, is_in_test, span_contains_comment, sym}; +use clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_parent_expr, higher, is_in_test, span_contains_comment}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -123,8 +123,16 @@ impl UselessVec { // allow indexing into a vec and some set of allowed method calls that exist on slices, too if let Some(parent) = get_parent_expr(cx, expr) && (adjusts_to_slice(cx, expr) - || matches!(parent.kind, ExprKind::Index(..)) - || is_allowed_vec_method(parent)) + || match parent.kind { + ExprKind::Index(..) => true, + ExprKind::MethodCall(path, _, [], _) => { + // If the given expression is a method call to a `Vec` method that also exists on + // slices, it means that this expression does not actually require a `Vec` and could + // just work with an array. + VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&path.ident.name) + }, + _ => false, + }) { ControlFlow::Continue(()) } else { @@ -144,8 +152,9 @@ impl UselessVec { VecToArray::Impossible }, // search for `for _ in vec![...]` - Node::Expr(Expr { span, .. }) - if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) => + Node::Expr(expr) + if expr.span.is_desugaring(DesugaringKind::ForLoop) + && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) => { VecToArray::Possible }, @@ -276,9 +285,8 @@ impl SuggestedType { assert!(args_span.is_none_or(|s| !s.from_expansion())); assert!(len_span.is_none_or(|s| !s.from_expansion())); - let maybe_args = args_span - .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")) - .map_or(String::new(), |x| x.to_owned()); + let maybe_args = args_span.map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")); + let maybe_args = maybe_args.as_deref().unwrap_or_default(); let maybe_len = len_span .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local")) .map(|st| format!("; {st}")) @@ -301,17 +309,6 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice()) } -/// Checks if the given expression is a method call to a `Vec` method -/// that also exists on slices. If this returns true, it means that -/// this expression does not actually require a `Vec` and could just work with an array. -pub fn is_allowed_vec_method(e: &Expr<'_>) -> bool { - if let ExprKind::MethodCall(path, _, [], _) = e.kind { - matches!(path.ident.name, sym::as_ptr | sym::is_empty | sym::len) - } else { - false - } -} - fn suggest_type(expr: &Expr<'_>) -> SuggestedType { if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind { // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 46c5af058ccc..3124ada0e94a 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -136,6 +136,9 @@ use crate::res::{MaybeDef, MaybeQPath, MaybeResPath}; use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type}; use crate::visitors::for_each_expr_without_closures; +/// Methods on `Vec` that also exists on slices. +pub const VEC_METHODS_SHADOWING_SLICE_METHODS: [Symbol; 3] = [sym::as_ptr, sym::is_empty, sym::len]; + #[macro_export] macro_rules! extract_msrv_attr { () => { diff --git a/tests/ui/vec.fixed b/tests/ui/useless_vec.fixed similarity index 90% rename from tests/ui/vec.fixed rename to tests/ui/useless_vec.fixed index 55742459c92c..3cea4862611d 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/useless_vec.fixed @@ -1,5 +1,4 @@ #![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] use std::rc::Rc; @@ -39,17 +38,14 @@ fn main() { on_mut_slice(&mut [1, 2]); //~^ useless_vec - on_slice(&[1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut [1, 2]); - //~^ useless_vec #[rustfmt::skip] - on_slice(&[1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut [1, 2]); - //~^ useless_vec + #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix + { + on_slice(&[1, 2]); + //~^ useless_vec + on_mut_slice(&mut [1, 2]); + //~^ useless_vec + }; on_slice(&[1; 2]); //~^ useless_vec @@ -75,22 +71,24 @@ fn main() { on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - // Ok + // Ok, size of `vec` higher than `too_large_for_stack` for a in vec![1; 201] { - println!("{:?}", a); + println!("{a:?}"); } // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 let _x: i32 = [1, 2, 3].iter().sum(); //~^ useless_vec - // Do lint - let mut x = [1, 2, 3]; - //~^ useless_vec - x.fill(123); - dbg!(x[0]); - dbg!(x.len()); - dbg!(x.iter().sum::()); + // Do lint, only used as slice + { + let mut x = [1, 2, 3]; + //~^ useless_vec + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + } let _x: &[i32] = &[1, 2, 3]; //~^ useless_vec diff --git a/tests/ui/useless_vec.rs b/tests/ui/useless_vec.rs index 880809f81d7a..2b5d71ae7fa4 100644 --- a/tests/ui/useless_vec.rs +++ b/tests/ui/useless_vec.rs @@ -1,15 +1,251 @@ -//@no-rustfix: no suggestions - #![warn(clippy::useless_vec)] -// Regression test for . -fn foo() { - // There should be no suggestion in this case. - let _some_variable = vec![ +use std::rc::Rc; + +struct StructWithVec { + _x: Vec, +} + +fn on_slice(_: &[u8]) {} + +fn on_mut_slice(_: &mut [u8]) {} + +#[allow(clippy::ptr_arg)] +fn on_vec(_: &Vec) {} + +fn on_mut_vec(_: &mut Vec) {} + +struct Line { + length: usize, +} + +impl Line { + fn length(&self) -> usize { + self.length + } +} + +fn main() { + on_slice(&vec![]); + //~^ useless_vec + on_slice(&[]); + on_mut_slice(&mut vec![]); + //~^ useless_vec + + on_slice(&vec![1, 2]); + //~^ useless_vec + on_slice(&[1, 2]); + on_mut_slice(&mut vec![1, 2]); + //~^ useless_vec + + #[rustfmt::skip] + #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix + { + on_slice(&vec!(1, 2)); //~^ useless_vec - 1, 2, // i'm here to stay - 3, 4, // but this one going away ;-; - ]; // that is life anyways + on_mut_slice(&mut vec!(1, 2)); + //~^ useless_vec + }; + + on_slice(&vec![1; 2]); + //~^ useless_vec + on_slice(&[1; 2]); + on_mut_slice(&mut vec![1; 2]); + //~^ useless_vec + + on_vec(&vec![]); + on_vec(&vec![1, 2]); + on_vec(&vec![1; 2]); + on_mut_vec(&mut vec![]); + on_mut_vec(&mut vec![1, 2]); + on_mut_vec(&mut vec![1; 2]); + + // Now with non-constant expressions + let line = Line { length: 2 }; + + on_slice(&vec![2; line.length]); + on_slice(&vec![2; line.length()]); + on_mut_slice(&mut vec![2; line.length]); + on_mut_slice(&mut vec![2; line.length()]); + + on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` + on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` + + // Ok, size of `vec` higher than `too_large_for_stack` + for a in vec![1; 201] { + println!("{a:?}"); + } + + // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 + let _x: i32 = vec![1, 2, 3].iter().sum(); + //~^ useless_vec + + // Do lint, only used as slice + { + let mut x = vec![1, 2, 3]; + //~^ useless_vec + x.fill(123); + dbg!(x[0]); + dbg!(x.len()); + dbg!(x.iter().sum::()); + } + + let _x: &[i32] = &vec![1, 2, 3]; + //~^ useless_vec + + for _ in vec![1, 2, 3] {} + //~^ useless_vec + + // Don't lint + let x = vec![1, 2, 3]; + let _v: Vec = x; + + let x = vec![1, 2, 3]; + let _s = StructWithVec { _x: x }; + + // Explicit type annotation would make the change to [1, 2, 3] + // a compile error. + let _x: Vec = vec![1, 2, 3]; + + // Calling a Vec method through a mutable reference + let mut x = vec![1, 2, 3]; + let re = &mut x; + re.push(4); + + // Comparing arrays whose length is not equal is a compile error + let x = vec![1, 2, 3]; + let y = vec![1, 2, 3, 4]; + dbg!(x == y); + + // Non-copy types + let _x = vec![String::new(); 10]; + #[allow(clippy::rc_clone_in_vec_init)] + let _x = vec![Rc::new(1); 10]; + + // Too large + let _x = vec![1; 201]; +} + +fn issue11075() { + macro_rules! repro { + ($e:expr) => { + stringify!($e) + }; + } + #[allow(clippy::never_loop)] + for _string in vec![repro!(true), repro!(null)] { + //~^ useless_vec + unimplemented!(); + } + + macro_rules! in_macro { + ($e:expr, $vec:expr, $vec2:expr) => {{ + vec![1; 2].fill(3); + vec![1, 2].fill(3); + for _ in vec![1, 2] {} + for _ in vec![1; 2] {} + for _ in vec![$e, $e] {} + for _ in vec![$e; 2] {} + for _ in $vec {} + for _ in $vec2 {} + }}; + } + + in_macro!(1, vec![1, 2], vec![1; 2]); + //~^ useless_vec + //~| useless_vec + + macro_rules! from_macro { + () => { + vec![1, 2, 3] + }; + } + macro_rules! from_macro_repeat { + () => { + vec![1; 3] + }; + } + + for _ in from_macro!() {} + for _ in from_macro_repeat!() {} +} + +#[clippy::msrv = "1.53"] +fn above() { + for a in vec![1, 2, 3] { + //~^ useless_vec + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + //~^ useless_vec + let _: String = a; + } +} + +#[clippy::msrv = "1.52"] +fn below() { + for a in vec![1, 2, 3] { + let _: usize = a; + } + + for a in vec![String::new(), String::new()] { + let _: String = a; + } +} + +fn func_needing_vec(_bar: usize, _baz: Vec) {} +fn func_not_needing_vec(_bar: usize, _baz: usize) {} + +fn issue11861() { + macro_rules! this_macro_needs_vec { + ($x:expr) => {{ + func_needing_vec($x.iter().sum(), $x); + for _ in $x {} + }}; + } + macro_rules! this_macro_doesnt_need_vec { + ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; + } + + // Do not lint the next line + this_macro_needs_vec!(vec![1]); + this_macro_doesnt_need_vec!(vec![1]); + //~^ useless_vec + + macro_rules! m { + ($x:expr) => { + fn f2() { + let _x: Vec = $x; + } + fn f() { + let _x = $x; + $x.starts_with(&[]); + } + }; + } + + // should not lint + m!(vec![1]); } -fn main() {} +fn issue_11958() { + fn f(_s: &[String]) {} + + // should not lint, `String` is not `Copy` + f(&vec!["test".to_owned(); 2]); +} + +fn issue_12101() { + for a in &(vec![1, 2]) {} + //~^ useless_vec +} + +fn issue_14531() { + // The lint used to suggest using an array rather than a reference to a slice. + + fn requires_ref_slice(v: &[()]) {} + let v = &vec![]; + //~^ useless_vec + requires_ref_slice(v); +} diff --git a/tests/ui/useless_vec.stderr b/tests/ui/useless_vec.stderr index e47364fb06d3..65120d8b338f 100644 --- a/tests/ui/useless_vec.stderr +++ b/tests/ui/useless_vec.stderr @@ -1,21 +1,125 @@ error: useless use of `vec!` - --> tests/ui/useless_vec.rs:8:26 + --> tests/ui/useless_vec.rs:29:14 | -LL | let _some_variable = vec![ - | __________________________^ -LL | | -LL | | 1, 2, // i'm here to stay -LL | | 3, 4, // but this one going away ;-; -LL | | ]; // that is life anyways - | |_____^ +LL | on_slice(&vec![]); + | ^^^^^^^ help: you can use a slice directly: `&[]` | = note: `-D clippy::useless-vec` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` -help: you can use an array directly + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:32:18 + | +LL | on_mut_slice(&mut vec![]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:35:14 + | +LL | on_slice(&vec![1, 2]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:38:18 + | +LL | on_mut_slice(&mut vec![1, 2]); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:44:18 + | +LL | on_slice(&vec!(1, 2)); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:46:22 | -LL ~ let _some_variable = [1, 2, // i'm here to stay -LL ~ 3, 4]; // that is life anyways +LL | on_mut_slice(&mut vec!(1, 2)); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:50:14 + | +LL | on_slice(&vec![1; 2]); + | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:53:18 + | +LL | on_mut_slice(&mut vec![1; 2]); + | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:80:19 + | +LL | let _x: i32 = vec![1, 2, 3].iter().sum(); + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:85:21 + | +LL | let mut x = vec![1, 2, 3]; + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:93:22 + | +LL | let _x: &[i32] = &vec![1, 2, 3]; + | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:96:14 + | +LL | for _ in vec![1, 2, 3] {} + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:136:20 + | +LL | for _string in vec![repro!(true), repro!(null)] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:154:18 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:154:30 + | +LL | in_macro!(1, vec![1, 2], vec![1; 2]); + | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:175:14 + | +LL | for a in vec![1, 2, 3] { + | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:180:14 + | +LL | for a in vec![String::new(), String::new()] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:213:33 + | +LL | this_macro_doesnt_need_vec!(vec![1]); + | ^^^^^^^ help: you can use an array directly: `[1]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:240:14 + | +LL | for a in &(vec![1, 2]) {} + | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` + +error: useless use of `vec!` + --> tests/ui/useless_vec.rs:248:13 | +LL | let v = &vec![]; + | ^^^^^^^ help: you can use a slice directly: `&[]` -error: aborting due to 1 previous error +error: aborting due to 20 previous errors diff --git a/tests/ui/useless_vec_unfixable.rs b/tests/ui/useless_vec_unfixable.rs new file mode 100644 index 000000000000..7f45f4df5ee6 --- /dev/null +++ b/tests/ui/useless_vec_unfixable.rs @@ -0,0 +1,14 @@ +//@no-rustfix: no suggestions +#![warn(clippy::useless_vec)] + +// Regression test for . +fn foo() { + // There should be no suggestion in this case. + let _some_variable = vec![ + //~^ useless_vec + 1, 2, // i'm here to stay + 3, 4, // but this one going away ;-; + ]; // that is life anyways +} + +fn main() {} diff --git a/tests/ui/useless_vec_unfixable.stderr b/tests/ui/useless_vec_unfixable.stderr new file mode 100644 index 000000000000..980194ac7191 --- /dev/null +++ b/tests/ui/useless_vec_unfixable.stderr @@ -0,0 +1,21 @@ +error: useless use of `vec!` + --> tests/ui/useless_vec_unfixable.rs:7:26 + | +LL | let _some_variable = vec![ + | __________________________^ +LL | | +LL | | 1, 2, // i'm here to stay +LL | | 3, 4, // but this one going away ;-; +LL | | ]; // that is life anyways + | |_____^ + | + = note: `-D clippy::useless-vec` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` +help: you can use an array directly + | +LL ~ let _some_variable = [1, 2, // i'm here to stay +LL ~ 3, 4]; // that is life anyways + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs deleted file mode 100644 index fbf7131323c3..000000000000 --- a/tests/ui/vec.rs +++ /dev/null @@ -1,253 +0,0 @@ -#![warn(clippy::useless_vec)] -#![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args, unused)] - -use std::rc::Rc; - -struct StructWithVec { - _x: Vec, -} - -fn on_slice(_: &[u8]) {} - -fn on_mut_slice(_: &mut [u8]) {} - -#[allow(clippy::ptr_arg)] -fn on_vec(_: &Vec) {} - -fn on_mut_vec(_: &mut Vec) {} - -struct Line { - length: usize, -} - -impl Line { - fn length(&self) -> usize { - self.length - } -} - -fn main() { - on_slice(&vec![]); - //~^ useless_vec - on_slice(&[]); - on_mut_slice(&mut vec![]); - //~^ useless_vec - - on_slice(&vec![1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - - on_slice(&vec![1, 2]); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - #[rustfmt::skip] - on_slice(&vec!(1, 2)); - //~^ useless_vec - on_slice(&[1, 2]); - on_mut_slice(&mut vec![1, 2]); - //~^ useless_vec - - on_slice(&vec![1; 2]); - //~^ useless_vec - on_slice(&[1; 2]); - on_mut_slice(&mut vec![1; 2]); - //~^ useless_vec - - on_vec(&vec![]); - on_vec(&vec![1, 2]); - on_vec(&vec![1; 2]); - on_mut_vec(&mut vec![]); - on_mut_vec(&mut vec![1, 2]); - on_mut_vec(&mut vec![1; 2]); - - // Now with non-constant expressions - let line = Line { length: 2 }; - - on_slice(&vec![2; line.length]); - on_slice(&vec![2; line.length()]); - on_mut_slice(&mut vec![2; line.length]); - on_mut_slice(&mut vec![2; line.length()]); - - on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack` - - // Ok - for a in vec![1; 201] { - println!("{:?}", a); - } - - // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246 - let _x: i32 = vec![1, 2, 3].iter().sum(); - //~^ useless_vec - - // Do lint - let mut x = vec![1, 2, 3]; - //~^ useless_vec - x.fill(123); - dbg!(x[0]); - dbg!(x.len()); - dbg!(x.iter().sum::()); - - let _x: &[i32] = &vec![1, 2, 3]; - //~^ useless_vec - - for _ in vec![1, 2, 3] {} - //~^ useless_vec - - // Don't lint - let x = vec![1, 2, 3]; - let _v: Vec = x; - - let x = vec![1, 2, 3]; - let _s = StructWithVec { _x: x }; - - // Explicit type annotation would make the change to [1, 2, 3] - // a compile error. - let _x: Vec = vec![1, 2, 3]; - - // Calling a Vec method through a mutable reference - let mut x = vec![1, 2, 3]; - let re = &mut x; - re.push(4); - - // Comparing arrays whose length is not equal is a compile error - let x = vec![1, 2, 3]; - let y = vec![1, 2, 3, 4]; - dbg!(x == y); - - // Non-copy types - let _x = vec![String::new(); 10]; - #[allow(clippy::rc_clone_in_vec_init)] - let _x = vec![Rc::new(1); 10]; - - // Too large - let _x = vec![1; 201]; -} - -fn issue11075() { - macro_rules! repro { - ($e:expr) => { - stringify!($e) - }; - } - #[allow(clippy::never_loop)] - for _string in vec![repro!(true), repro!(null)] { - //~^ useless_vec - unimplemented!(); - } - - macro_rules! in_macro { - ($e:expr, $vec:expr, $vec2:expr) => {{ - vec![1; 2].fill(3); - vec![1, 2].fill(3); - for _ in vec![1, 2] {} - for _ in vec![1; 2] {} - for _ in vec![$e, $e] {} - for _ in vec![$e; 2] {} - for _ in $vec {} - for _ in $vec2 {} - }}; - } - - in_macro!(1, vec![1, 2], vec![1; 2]); - //~^ useless_vec - //~| useless_vec - - macro_rules! from_macro { - () => { - vec![1, 2, 3] - }; - } - macro_rules! from_macro_repeat { - () => { - vec![1; 3] - }; - } - - for _ in from_macro!() {} - for _ in from_macro_repeat!() {} -} - -#[clippy::msrv = "1.53"] -fn above() { - for a in vec![1, 2, 3] { - //~^ useless_vec - let _: usize = a; - } - - for a in vec![String::new(), String::new()] { - //~^ useless_vec - let _: String = a; - } -} - -#[clippy::msrv = "1.52"] -fn below() { - for a in vec![1, 2, 3] { - let _: usize = a; - } - - for a in vec![String::new(), String::new()] { - let _: String = a; - } -} - -fn func_needing_vec(_bar: usize, _baz: Vec) {} -fn func_not_needing_vec(_bar: usize, _baz: usize) {} - -fn issue11861() { - macro_rules! this_macro_needs_vec { - ($x:expr) => {{ - func_needing_vec($x.iter().sum(), $x); - for _ in $x {} - }}; - } - macro_rules! this_macro_doesnt_need_vec { - ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }}; - } - - // Do not lint the next line - this_macro_needs_vec!(vec![1]); - this_macro_doesnt_need_vec!(vec![1]); - //~^ useless_vec - - macro_rules! m { - ($x:expr) => { - fn f2() { - let _x: Vec = $x; - } - fn f() { - let _x = $x; - $x.starts_with(&[]); - } - }; - } - - // should not lint - m!(vec![1]); -} - -fn issue_11958() { - fn f(_s: &[String]) {} - - // should not lint, `String` is not `Copy` - f(&vec!["test".to_owned(); 2]); -} - -fn issue_12101() { - for a in &(vec![1, 2]) {} - //~^ useless_vec -} - -fn issue_14531() { - // The lint used to suggest using an array rather than a reference to a slice. - - fn requires_ref_slice(v: &[()]) {} - let v = &vec![]; - //~^ useless_vec - requires_ref_slice(v); -} diff --git a/tests/ui/vec.stderr b/tests/ui/vec.stderr deleted file mode 100644 index d16c8a8944a2..000000000000 --- a/tests/ui/vec.stderr +++ /dev/null @@ -1,137 +0,0 @@ -error: useless use of `vec!` - --> tests/ui/vec.rs:30:14 - | -LL | on_slice(&vec![]); - | ^^^^^^^ help: you can use a slice directly: `&[]` - | - = note: `-D clippy::useless-vec` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:33:18 - | -LL | on_mut_slice(&mut vec![]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&mut []` - -error: useless use of `vec!` - --> tests/ui/vec.rs:36:14 - | -LL | on_slice(&vec![1, 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:39:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:42:14 - | -LL | on_slice(&vec![1, 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:45:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:48:14 - | -LL | on_slice(&vec!(1, 2)); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:51:18 - | -LL | on_mut_slice(&mut vec![1, 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:54:14 - | -LL | on_slice(&vec![1; 2]); - | ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:57:18 - | -LL | on_mut_slice(&mut vec![1; 2]); - | ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:84:19 - | -LL | let _x: i32 = vec![1, 2, 3].iter().sum(); - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:88:17 - | -LL | let mut x = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:95:22 - | -LL | let _x: &[i32] = &vec![1, 2, 3]; - | ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:98:14 - | -LL | for _ in vec![1, 2, 3] {} - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:138:20 - | -LL | for _string in vec![repro!(true), repro!(null)] { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:156:18 - | -LL | in_macro!(1, vec![1, 2], vec![1; 2]); - | ^^^^^^^^^^ help: you can use an array directly: `[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:156:30 - | -LL | in_macro!(1, vec![1, 2], vec![1; 2]); - | ^^^^^^^^^^ help: you can use an array directly: `[1; 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:177:14 - | -LL | for a in vec![1, 2, 3] { - | ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:182:14 - | -LL | for a in vec![String::new(), String::new()] { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:215:33 - | -LL | this_macro_doesnt_need_vec!(vec![1]); - | ^^^^^^^ help: you can use an array directly: `[1]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:242:14 - | -LL | for a in &(vec![1, 2]) {} - | ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]` - -error: useless use of `vec!` - --> tests/ui/vec.rs:250:13 - | -LL | let v = &vec![]; - | ^^^^^^^ help: you can use a slice directly: `&[]` - -error: aborting due to 22 previous errors -