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<Box<dyn T>> is smaller than Box<dyn T> 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<Box<Box<dyn T>>>) {}
 }
 
+// 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<Box<str>>,
+        b: Rc<Box<str>>,
+        c: Arc<Box<str>>,
+    }
+
+    pub fn test_box(_: Box<Box<str>>) {}
+    pub fn test_rc(_: Rc<Box<str>>) {}
+    pub fn test_arc(_: Arc<Box<str>>) {}
+    pub fn test_rc_box(_: Rc<Box<Box<str>>>) {}
+}
+
 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<Box<Box<dyn T>>>) {}
    = note: `Box<Box<dyn T>>` is already on the heap, `Rc<Box<Box<dyn T>>>` makes an extra allocation
    = help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>`
 
-error: aborting due to 16 previous errors
+error: usage of `Rc<Box<Box<str>>>`
+  --> $DIR/redundant_allocation.rs:115:27
+   |
+LL |     pub fn test_rc_box(_: Rc<Box<Box<str>>>) {}
+   |                           ^^^^^^^^^^^^^^^^^
+   |
+   = note: `Box<Box<str>>` is already on the heap, `Rc<Box<Box<str>>>` makes an extra allocation
+   = help: consider using just `Rc<Box<str>>` or `Box<Box<str>>`
+
+error: aborting due to 17 previous errors