From 631b4ee7a26e4e68469a607376005eb4064b3e6f Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Tue, 10 May 2022 14:21:51 -0400 Subject: [PATCH] Fix redundant_allocation warning for Rc> --- .../src/types/redundant_allocation.rs | 22 ++++++++++++++++--- tests/ui/redundant_allocation.rs | 18 +++++++++++++++ tests/ui/redundant_allocation.stderr | 11 +++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs index 10d2ae2eb1d..5fdf1731495 100644 --- a/clippy_lints/src/types/redundant_allocation.rs +++ b/clippy_lints/src/types/redundant_allocation.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::{path_def_id, qpath_generic_tys}; use rustc_errors::Applicability; -use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; +use rustc_hir::{self as hir, def, def_id::DefId, PrimTy, QPath, TyKind}; use rustc_lint::LateContext; use rustc_span::symbol::sym; @@ -54,8 +54,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ }; let inner_span = match qpath_generic_tys(inner_qpath).next() { Some(ty) => { - // Box> is smaller than Box because of wide pointers - if matches!(ty.kind, TyKind::TraitObject(..)) { + if alloc_makes_pointer_thin(cx, ty) { return false; } ty.span @@ -110,3 +109,20 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_ } true } + +/// Returns `true` if the allocation would make `hir_ty` go from fat to thin. +fn alloc_makes_pointer_thin(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) -> bool { + match &hir_ty.kind { + TyKind::TraitObject(..) => true, + TyKind::Path(ty_qpath) => { + let ty_res = cx.qpath_res(ty_qpath, hir_ty.hir_id); + if let def::Res::PrimTy(prim_ty) = ty_res { + if matches!(prim_ty, PrimTy::Str) { + return true; + } + } + false + }, + _ => false, + } +} diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs index 80f94e5f3cb..b830a3771d5 100644 --- a/tests/ui/redundant_allocation.rs +++ b/tests/ui/redundant_allocation.rs @@ -97,4 +97,22 @@ mod box_dyn { pub fn test_rc_box(_: Rc>>) {} } +// https://github.com/rust-lang/rust-clippy/issues/8604 +mod box_str { + use std::boxed::Box; + use std::rc::Rc; + use std::sync::Arc; + + struct S { + a: Box>, + b: Rc>, + c: Arc>, + } + + pub fn test_box(_: Box>) {} + pub fn test_rc(_: Rc>) {} + pub fn test_arc(_: Arc>) {} + pub fn test_rc_box(_: Rc>>) {} +} + fn main() {} diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr index c3b10e5f5e6..ae213cb8975 100644 --- a/tests/ui/redundant_allocation.stderr +++ b/tests/ui/redundant_allocation.stderr @@ -143,5 +143,14 @@ LL | pub fn test_rc_box(_: Rc>>) {} = note: `Box>` is already on the heap, `Rc>>` makes an extra allocation = help: consider using just `Rc>` or `Box>` -error: aborting due to 16 previous errors +error: usage of `Rc>>` + --> $DIR/redundant_allocation.rs:115:27 + | +LL | pub fn test_rc_box(_: Rc>>) {} + | ^^^^^^^^^^^^^^^^^ + | + = note: `Box>` is already on the heap, `Rc>>` makes an extra allocation + = help: consider using just `Rc>` or `Box>` + +error: aborting due to 17 previous errors