diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index b5c5fc0608b95..3fbd7db765b70 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
         }
 
         let ty = cx.tables.expr_ty(&expr);
-        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "");
+        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "");
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -133,6 +133,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             ty: Ty<'tcx>,
             expr: &hir::Expr,
             span: Span,
+            descr_pre_path: &str,
             descr_post_path: &str,
         ) -> bool {
             if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
@@ -142,14 +143,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             }
 
             match ty.sty {
-                ty::Adt(def, _) => check_must_use_def(cx, def.did, span, "", descr_post_path),
+                ty::Adt(..) if ty.is_box() => {
+                    let boxed_ty = ty.boxed_ty();
+                    let descr_pre_path = &format!("{}boxed ", descr_pre_path);
+                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre_path, descr_post_path)
+                }
+                ty::Adt(def, _) => {
+                    check_must_use_def(cx, def.did, span, descr_pre_path, descr_post_path)
+                }
                 ty::Opaque(def, _) => {
                     let mut has_emitted = false;
                     for (predicate, _) in &cx.tcx.predicates_of(def).predicates {
                         if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
                             let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
                             let def_id = trait_ref.def_id;
-                            if check_must_use_def(cx, def_id, span, "implementer of ", "") {
+                            let descr_pre = &format!("{}implementer of ", descr_pre_path);
+                            if check_must_use_def(cx, def_id, span, descr_pre, descr_post_path) {
                                 has_emitted = true;
                                 break;
                             }
@@ -162,7 +171,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                     for predicate in binder.skip_binder().iter() {
                         if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate {
                             let def_id = trait_ref.def_id;
-                            if check_must_use_def(cx, def_id, span, "", " trait object") {
+                            let descr_post = &format!(" trait object{}", descr_post_path);
+                            if check_must_use_def(cx, def_id, span, descr_pre_path, descr_post) {
                                 has_emitted = true;
                                 break;
                             }
@@ -181,7 +191,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                     for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
                         let descr_post_path = &format!(" in tuple element {}", i);
                         let span = *spans.get(i).unwrap_or(&span);
-                        if check_must_use_ty(cx, ty, expr, span, descr_post_path) {
+                        if check_must_use_ty(cx, ty, expr, span, descr_pre_path, descr_post_path) {
                             has_emitted = true;
                         }
                     }
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 9ef42063f9412..797d85e941d96 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -103,7 +103,9 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
         HOOK_LOCK.write_unlock();
 
         if let Hook::Custom(ptr) = old_hook {
-            Box::from_raw(ptr);
+            #[allow(unused_must_use)] {
+                Box::from_raw(ptr);
+            }
         }
     }
 }
diff --git a/src/test/run-pass/issues/issue-30530.rs b/src/test/run-pass/issues/issue-30530.rs
index e837fc81721a8..111fb8aa506a4 100644
--- a/src/test/run-pass/issues/issue-30530.rs
+++ b/src/test/run-pass/issues/issue-30530.rs
@@ -12,7 +12,9 @@ pub enum Handler {
 }
 
 fn main() {
-    take(Handler::Default, Box::new(main));
+    #[allow(unused_must_use)] {
+        take(Handler::Default, Box::new(main));
+    }
 }
 
 #[inline(never)]
diff --git a/src/test/run-pass/panics/panic-handler-flail-wildly.rs b/src/test/run-pass/panics/panic-handler-flail-wildly.rs
index ebe4f70378cf0..6badd203842ff 100644
--- a/src/test/run-pass/panics/panic-handler-flail-wildly.rs
+++ b/src/test/run-pass/panics/panic-handler-flail-wildly.rs
@@ -1,5 +1,7 @@
 // run-pass
+
 #![allow(stable_features)]
+#![allow(unused_must_use)]
 
 // ignore-emscripten no threads support
 
diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs
index 23df4fa6132d3..0aa751443a080 100644
--- a/src/test/ui/lint/must_use-trait.rs
+++ b/src/test/ui/lint/must_use-trait.rs
@@ -17,6 +17,23 @@ fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant {
     Anon {}
 }
 
+fn get_boxed_critical() -> Box<dyn Critical> {
+    Box::new(Anon {})
+}
+
+fn get_nested_boxed_critical() -> Box<Box<dyn Critical>> {
+    Box::new(Box::new(Anon {}))
+}
+
+fn get_critical_tuple() -> (u32, Box<dyn Critical>, impl Critical, ()) {
+    (0, get_boxed_critical(), get_critical(), ())
+}
+
 fn main() {
     get_critical(); //~ ERROR unused implementer of `Critical` that must be used
+    get_boxed_critical(); //~ ERROR unused boxed `Critical` trait object that must be used
+    get_nested_boxed_critical();
+    //~^ ERROR unused boxed boxed `Critical` trait object that must be used
+    get_critical_tuple(); //~ ERROR unused boxed `Critical` trait object in tuple element 1
+    //~^ ERROR unused implementer of `Critical` in tuple element 2
 }
diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr
index 7e2b2f67964ac..be74362e29d62 100644
--- a/src/test/ui/lint/must_use-trait.stderr
+++ b/src/test/ui/lint/must_use-trait.stderr
@@ -1,5 +1,5 @@
 error: unused implementer of `Critical` that must be used
-  --> $DIR/must_use-trait.rs:21:5
+  --> $DIR/must_use-trait.rs:33:5
    |
 LL |     get_critical();
    |     ^^^^^^^^^^^^^^^
@@ -10,5 +10,29 @@ note: lint level defined here
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: unused boxed `Critical` trait object that must be used
+  --> $DIR/must_use-trait.rs:34:5
+   |
+LL |     get_boxed_critical();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed boxed `Critical` trait object that must be used
+  --> $DIR/must_use-trait.rs:35:5
+   |
+LL |     get_nested_boxed_critical();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused boxed `Critical` trait object in tuple element 1 that must be used
+  --> $DIR/must_use-trait.rs:37:5
+   |
+LL |     get_critical_tuple();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: unused implementer of `Critical` in tuple element 2 that must be used
+  --> $DIR/must_use-trait.rs:37:5
+   |
+LL |     get_critical_tuple();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/miri b/src/tools/miri
index 945f007c0d305..72b2e1045d642 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 945f007c0d305c3ec069b5e5d911ef783f6d70e7
+Subproject commit 72b2e1045d642c517347c421b1db92e34c22a70d