Skip to content

Commit 788094c

Browse files
committed
Auto merge of rust-lang#11972 - samueltardieu:issue-11958, r=llogiq
Do not suggest `[T; n]` instead of `vec![T; n]` if `T` is not `Copy` changelog: [`useless_vec`]: do not suggest replacing `&vec![T; N]` by `&[T; N]` if `T` is not `Copy` Fix rust-lang#11958
2 parents 17b2418 + 4cea5a8 commit 788094c

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

Diff for: clippy_lints/src/vec.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use clippy_utils::{get_parent_expr, higher, is_trait_method};
1111
use rustc_errors::Applicability;
1212
use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Node, PatKind};
1313
use rustc_lint::{LateContext, LateLintPass};
14+
use rustc_middle::ty;
1415
use rustc_middle::ty::layout::LayoutOf;
15-
use rustc_middle::ty::{self, Ty};
1616
use rustc_session::impl_lint_pass;
1717
use rustc_span::{sym, DesugaringKind, Span};
1818

@@ -79,7 +79,6 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
7979
// this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..];
8080
&& local.ty.is_none()
8181
&& let PatKind::Binding(_, id, ..) = local.pat.kind
82-
&& is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr.peel_borrows())))
8382
{
8483
let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| {
8584
// allow indexing into a vec and some set of allowed method calls that exist on slices, too
@@ -185,6 +184,11 @@ impl UselessVec {
185184
let snippet = match *vec_args {
186185
higher::VecArgs::Repeat(elem, len) => {
187186
if let Some(Constant::Int(len_constant)) = constant(cx, cx.typeck_results(), len) {
187+
// vec![ty; N] works when ty is Clone, [ty; N] requires it to be Copy also
188+
if !is_copy(cx, cx.typeck_results().expr_ty(elem)) {
189+
return;
190+
}
191+
188192
#[expect(clippy::cast_possible_truncation)]
189193
if len_constant as u64 * size_of(cx, elem) > self.too_large_for_stack {
190194
return;
@@ -241,12 +245,3 @@ fn size_of(cx: &LateContext<'_>, expr: &Expr<'_>) -> u64 {
241245
let ty = cx.typeck_results().expr_ty_adjusted(expr);
242246
cx.layout_of(ty).map_or(0, |l| l.size.bytes())
243247
}
244-
245-
/// Returns the item type of the vector (i.e., the `T` in `Vec<T>`).
246-
fn vec_type(ty: Ty<'_>) -> Ty<'_> {
247-
if let ty::Adt(_, args) = ty.kind() {
248-
args.type_at(0)
249-
} else {
250-
panic!("The type of `vec!` is a not a struct?");
251-
}
252-
}

Diff for: tests/ui/vec.fixed

+7
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,10 @@ fn issue11861() {
210210
// should not lint
211211
m!(vec![1]);
212212
}
213+
214+
fn issue_11958() {
215+
fn f(_s: &[String]) {}
216+
217+
// should not lint, `String` is not `Copy`
218+
f(&vec!["test".to_owned(); 2]);
219+
}

Diff for: tests/ui/vec.rs

+7
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,10 @@ fn issue11861() {
210210
// should not lint
211211
m!(vec![1]);
212212
}
213+
214+
fn issue_11958() {
215+
fn f(_s: &[String]) {}
216+
217+
// should not lint, `String` is not `Copy`
218+
f(&vec!["test".to_owned(); 2]);
219+
}

0 commit comments

Comments
 (0)