about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs22
-rw-r--r--tests/ui/coercion/coerce-block-tail.stderr7
-rw-r--r--tests/ui/coercion/coerce-box-new-to-unboxed.rs4
-rw-r--r--tests/ui/coercion/coerce-box-new-to-unboxed.stderr19
4 files changed, 49 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1998a1884b7..a5c6a7f34ef 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -3021,6 +3021,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         )
                     {
                         let deref_kind = if checked_ty.is_box() {
+                            // detect Box::new(..)
+                            if let ExprKind::Call(box_new, [_]) = expr.kind
+                                && let ExprKind::Path(qpath) = &box_new.kind
+                                && let Res::Def(DefKind::AssocFn, fn_id) =
+                                    self.typeck_results.borrow().qpath_res(qpath, box_new.hir_id)
+                                && let Some(impl_id) = self.tcx.inherent_impl_of_assoc(fn_id)
+                                && self.tcx.type_of(impl_id).skip_binder().is_box()
+                                && self.tcx.item_name(fn_id) == sym::new
+                            {
+                                let l_paren = self.tcx.sess.source_map().next_point(box_new.span);
+                                let r_paren = self.tcx.sess.source_map().end_point(expr.span);
+                                return Some((
+                                    vec![
+                                        (box_new.span.to(l_paren), String::new()),
+                                        (r_paren, String::new()),
+                                    ],
+                                    "consider removing the Box".to_string(),
+                                    Applicability::MachineApplicable,
+                                    false,
+                                    false,
+                                ));
+                            }
                             "unboxing the value"
                         } else if checked_ty.is_ref() {
                             "dereferencing the borrow"
diff --git a/tests/ui/coercion/coerce-block-tail.stderr b/tests/ui/coercion/coerce-block-tail.stderr
index 1301f3b7813..b358401b706 100644
--- a/tests/ui/coercion/coerce-block-tail.stderr
+++ b/tests/ui/coercion/coerce-block-tail.stderr
@@ -6,10 +6,11 @@ LL |     let _: &i32 = & { Box::new(1i32) };
    |
    = note: expected type `i32`
             found struct `Box<i32>`
-help: consider unboxing the value
+help: consider removing the Box
+   |
+LL -     let _: &i32 = & { Box::new(1i32) };
+LL +     let _: &i32 = & { 1i32 };
    |
-LL |     let _: &i32 = & { *Box::new(1i32) };
-   |                       +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coercion/coerce-box-new-to-unboxed.rs b/tests/ui/coercion/coerce-box-new-to-unboxed.rs
new file mode 100644
index 00000000000..63ff0fc4e23
--- /dev/null
+++ b/tests/ui/coercion/coerce-box-new-to-unboxed.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let _: String = Box::new(String::new());
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/coercion/coerce-box-new-to-unboxed.stderr b/tests/ui/coercion/coerce-box-new-to-unboxed.stderr
new file mode 100644
index 00000000000..bdd962686e4
--- /dev/null
+++ b/tests/ui/coercion/coerce-box-new-to-unboxed.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-box-new-to-unboxed.rs:2:21
+   |
+LL |     let _: String = Box::new(String::new());
+   |            ------   ^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `Box<String>`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `String`
+              found struct `Box<String>`
+help: consider removing the Box
+   |
+LL -     let _: String = Box::new(String::new());
+LL +     let _: String = String::new();
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.