about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlengyijun <sjtu5140809011@gmail.com>2021-08-22 15:22:28 +0800
committerlengyijun <sjtu5140809011@gmail.com>2021-08-24 13:03:48 +0800
commit641be558fcdbddbabc1b6af841c05b61dbdd9d5f (patch)
tree8d4a60249d1e89f17b8a9a405f03df15d1fc45a8
parent1fc1aee7be6e7e71f12eacd60b9b1040e7640fe4 (diff)
downloadrust-641be558fcdbddbabc1b6af841c05b61dbdd9d5f.tar.gz
rust-641be558fcdbddbabc1b6af841c05b61dbdd9d5f.zip
redundant_allocation: fix 7487
-rw-r--r--clippy_lints/src/types/redundant_allocation.rs8
-rw-r--r--tests/ui/redundant_allocation.rs20
-rw-r--r--tests/ui/redundant_allocation.stderr11
3 files changed, 37 insertions, 2 deletions
diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs
index 8e83dcbf704..ac7bdd6a1eb 100644
--- a/clippy_lints/src/types/redundant_allocation.rs
+++ b/clippy_lints/src/types/redundant_allocation.rs
@@ -54,7 +54,13 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
         _ => return false,
     };
     let inner_span = match get_qpath_generic_tys(inner_qpath).next() {
-        Some(ty) => ty.span,
+        Some(ty) => {
+            // Box<Box<dyn T>> is smaller than Box<dyn T> because of wide pointers
+            if matches!(ty.kind, TyKind::TraitObject(..)) {
+                return false;
+            }
+            ty.span
+        },
         None => return false,
     };
     if inner_sym == outer_sym {
diff --git a/tests/ui/redundant_allocation.rs b/tests/ui/redundant_allocation.rs
index 1b4f2a66c70..52fbc91e325 100644
--- a/tests/ui/redundant_allocation.rs
+++ b/tests/ui/redundant_allocation.rs
@@ -77,4 +77,24 @@ mod outer_arc {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/7487
+mod box_dyn {
+    use std::boxed::Box;
+    use std::rc::Rc;
+    use std::sync::Arc;
+
+    pub trait T {}
+
+    struct S {
+        a: Box<Box<dyn T>>,
+        b: Rc<Box<dyn T>>,
+        c: Arc<Box<dyn T>>,
+    }
+
+    pub fn test_box(_: Box<Box<dyn T>>) {}
+    pub fn test_rc(_: Rc<Box<dyn T>>) {}
+    pub fn test_arc(_: Arc<Box<dyn T>>) {}
+    pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}
+}
+
 fn main() {}
diff --git a/tests/ui/redundant_allocation.stderr b/tests/ui/redundant_allocation.stderr
index fdab74eb538..c3b10e5f5e6 100644
--- a/tests/ui/redundant_allocation.stderr
+++ b/tests/ui/redundant_allocation.stderr
@@ -134,5 +134,14 @@ LL |     pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {
    = note: `Rc<SubT<T>>` is already on the heap, `Arc<Rc<SubT<T>>>` makes an extra allocation
    = help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>`
 
-error: aborting due to 15 previous errors
+error: usage of `Rc<Box<Box<dyn T>>>`
+  --> $DIR/redundant_allocation.rs:97:27
+   |
+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