about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-20 13:14:23 +0000
committerbors <bors@rust-lang.org>2023-02-20 13:14:23 +0000
commit574c8aeeb5320a672c4956a8749d577637ad7712 (patch)
treec46758be9ae6e9910a97193d4766cc0c5a35460c
parent85d4b5ac4855433fdb7584285db4f0af65805041 (diff)
parent92c403c9b01e213ad9b5a003d9c3c289abc653f1 (diff)
downloadrust-574c8aeeb5320a672c4956a8749d577637ad7712.tar.gz
rust-574c8aeeb5320a672c4956a8749d577637ad7712.zip
Auto merge of #10382 - samueltardieu:issue-10381, r=llogiq
Box::default(): do not omit the type of the removed trait object

Within a larger expression, when the type of `Box::new(T::default())` is `Box<dyn Trait>`, the concrete type `T` cannot be omitted in the proposed replacement `Box::<T>::default()`.

Fixes #10381

changelog: [`box_default`]: in case of a trait object do not omit the concrete type name
-rw-r--r--clippy_lints/src/box_default.rs3
-rw-r--r--tests/ui/box_default.fixed18
-rw-r--r--tests/ui/box_default.rs18
-rw-r--r--tests/ui/box_default.stderr14
4 files changed, 48 insertions, 5 deletions
diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs
index 9d98a6bab71..dfa949d1af2 100644
--- a/clippy_lints/src/box_default.rs
+++ b/clippy_lints/src/box_default.rs
@@ -117,7 +117,8 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         ) => {
             if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) &&
                 let Some(sig) = expr_sig(cx, path) &&
-                let Some(input) = sig.input(index)
+                let Some(input) = sig.input(index) &&
+                !cx.typeck_results().expr_ty_adjusted(expr).boxed_ty().is_trait()
             {
                 input.no_bound_vars().is_some()
             } else {
diff --git a/tests/ui/box_default.fixed b/tests/ui/box_default.fixed
index 7e9f074fdca..59c0baf8718 100644
--- a/tests/ui/box_default.fixed
+++ b/tests/ui/box_default.fixed
@@ -33,6 +33,7 @@ fn main() {
     let _vec4: Box<_> = Box::<Vec<bool>>::default();
     let _more = ret_ty_fn();
     call_ty_fn(Box::default());
+    issue_10381();
 }
 
 fn ret_ty_fn() -> Box<bool> {
@@ -65,3 +66,20 @@ fn issue_10089() {
         let _ = Box::<WeirdPathed>::default();
     };
 }
+
+fn issue_10381() {
+    #[derive(Default)]
+    pub struct Foo {}
+    pub trait Bar {}
+    impl Bar for Foo {}
+
+    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
+        if i % 2 == 0 {
+            Some(Box::<Foo>::default())
+        } else {
+            None
+        }
+    }
+
+    assert!(maybe_get_bar(2).is_some());
+}
diff --git a/tests/ui/box_default.rs b/tests/ui/box_default.rs
index 5c8d0b8354c..f7d832193a3 100644
--- a/tests/ui/box_default.rs
+++ b/tests/ui/box_default.rs
@@ -33,6 +33,7 @@ fn main() {
     let _vec4: Box<_> = Box::new(Vec::from([false; 0]));
     let _more = ret_ty_fn();
     call_ty_fn(Box::new(u8::default()));
+    issue_10381();
 }
 
 fn ret_ty_fn() -> Box<bool> {
@@ -65,3 +66,20 @@ fn issue_10089() {
         let _ = Box::new(WeirdPathed::default());
     };
 }
+
+fn issue_10381() {
+    #[derive(Default)]
+    pub struct Foo {}
+    pub trait Bar {}
+    impl Bar for Foo {}
+
+    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
+        if i % 2 == 0 {
+            Some(Box::new(Foo::default()))
+        } else {
+            None
+        }
+    }
+
+    assert!(maybe_get_bar(2).is_some());
+}
diff --git a/tests/ui/box_default.stderr b/tests/ui/box_default.stderr
index 249eb340f96..78e17b9f035 100644
--- a/tests/ui/box_default.stderr
+++ b/tests/ui/box_default.stderr
@@ -73,22 +73,28 @@ LL |     call_ty_fn(Box::new(u8::default()));
    |                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> $DIR/box_default.rs:39:5
+  --> $DIR/box_default.rs:40:5
    |
 LL |     Box::new(bool::default())
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()`
 
 error: `Box::new(_)` of default value
-  --> $DIR/box_default.rs:56:28
+  --> $DIR/box_default.rs:57:28
    |
 LL |     let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
 
 error: `Box::new(_)` of default value
-  --> $DIR/box_default.rs:65:17
+  --> $DIR/box_default.rs:66:17
    |
 LL |         let _ = Box::new(WeirdPathed::default());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()`
 
-error: aborting due to 15 previous errors
+error: `Box::new(_)` of default value
+  --> $DIR/box_default.rs:78:18
+   |
+LL |             Some(Box::new(Foo::default()))
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()`
+
+error: aborting due to 16 previous errors