Do not suggest [T; n] instead of vec![T; n] if T is not Copy

This commit is contained in:
Samuel Tardieu 2023-12-16 14:02:50 +01:00
parent 29bdc8b2bc
commit 4cea5a8f33
3 changed files with 20 additions and 11 deletions

View file

@ -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<T>`).
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?");
}
}

View file

@ -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]);
}

View file

@ -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]);
}