diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 5e13c73f035..2c33c93412a 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -11,8 +11,8 @@ use clippy_utils::{get_parent_expr, higher, is_trait_method}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::{sym, DesugaringKind, Span}; @@ -79,7 +79,6 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec { // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..]; && local.ty.is_none() && let PatKind::Binding(_, id, ..) = local.pat.kind - && is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr.peel_borrows()))) { let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| { // allow indexing into a vec and some set of allowed method calls that exist on slices, too @@ -185,6 +184,11 @@ impl UselessVec { let snippet = match *vec_args { higher::VecArgs::Repeat(elem, len) => { if let Some(Constant::Int(len_constant)) = constant(cx, cx.typeck_results(), len) { + // vec![ty; N] works when ty is Clone, [ty; N] requires it to be Copy also + if !is_copy(cx, cx.typeck_results().expr_ty(elem)) { + return; + } + #[expect(clippy::cast_possible_truncation)] if len_constant as u64 * size_of(cx, elem) > self.too_large_for_stack { return; @@ -241,12 +245,3 @@ fn size_of(cx: &LateContext<'_>, expr: &Expr<'_>) -> u64 { let ty = cx.typeck_results().expr_ty_adjusted(expr); cx.layout_of(ty).map_or(0, |l| l.size.bytes()) } - -/// Returns the item type of the vector (i.e., the `T` in `Vec`). -fn vec_type(ty: Ty<'_>) -> Ty<'_> { - if let ty::Adt(_, args) = ty.kind() { - args.type_at(0) - } else { - panic!("The type of `vec!` is a not a struct?"); - } -} diff --git a/tests/ui/vec.fixed b/tests/ui/vec.fixed index 81b8bd7da77..b318fd42f7c 100644 --- a/tests/ui/vec.fixed +++ b/tests/ui/vec.fixed @@ -210,3 +210,10 @@ fn issue11861() { // 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]); +} diff --git a/tests/ui/vec.rs b/tests/ui/vec.rs index 5aca9b2925c..08ad6efa37f 100644 --- a/tests/ui/vec.rs +++ b/tests/ui/vec.rs @@ -210,3 +210,10 @@ fn issue11861() { // 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]); +}