about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md6
-rw-r--r--src/libcore/char/methods.rs6
-rw-r--r--src/librustc_lint/unused.rs48
-rw-r--r--src/librustc_mir/dataflow/mod.rs20
-rw-r--r--src/librustc_mir/util/liveness.rs21
-rw-r--r--src/librustc_passes/ast_validation.rs7
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/clean/mod.rs111
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/format.rs3
-rw-r--r--src/librustdoc/html/item_type.rs1
-rw-r--r--src/librustdoc/html/render.rs3
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/libstd/panicking.rs4
-rw-r--r--src/libsyntax/parse/parser.rs26
-rw-r--r--src/test/run-pass/issues/issue-30530.rs4
-rw-r--r--src/test/run-pass/panics/panic-handler-flail-wildly.rs2
-rw-r--r--src/test/ui/async-await/async-await.rs13
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.rs6
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr28
-rw-r--r--src/test/ui/async-await/no-unsafe-async.rs11
-rw-r--r--src/test/ui/async-await/no-unsafe-async.stderr14
-rw-r--r--src/test/ui/lint/must_use-array.rs47
-rw-r--r--src/test/ui/lint/must_use-array.stderr44
-rw-r--r--src/test/ui/lint/must_use-trait.rs17
-rw-r--r--src/test/ui/lint/must_use-trait.stderr28
m---------src/tools/miri16
27 files changed, 366 insertions, 126 deletions
diff --git a/RELEASES.md b/RELEASES.md
index b6e2171f6ee..5ceeea8d037 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -309,9 +309,9 @@ Misc
 
 Compatibility Notes
 -------------------
-- [`Command::before_exec` is now deprecated in favor of the
-  unsafe method `Command::pre_exec`.][58059]
-- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated.][57425] As you
+- [`Command::before_exec` is being replaced by the unsafe method
+  `Command::pre_exec`][58059] and will be deprecated with Rust 1.37.0.
+- [Use of `ATOMIC_{BOOL, ISIZE, USIZE}_INIT` is now deprecated][57425] as you
   can now use `const` functions in `static` variables.
 
 [58370]: https://github.com/rust-lang/rust/pull/58370/
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 722c4c80516..e843303380a 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -337,16 +337,16 @@ impl char {
     /// ```
     /// // as chars
     /// let eastern = '東';
-    /// let capitol = '京';
+    /// let capital = '京';
     ///
     /// // both can be represented as three bytes
     /// assert_eq!(3, eastern.len_utf8());
-    /// assert_eq!(3, capitol.len_utf8());
+    /// assert_eq!(3, capital.len_utf8());
     ///
     /// // as a &str, these two are encoded in UTF-8
     /// let tokyo = "東京";
     ///
-    /// let len = eastern.len_utf8() + capitol.len_utf8();
+    /// let len = eastern.len_utf8() + capital.len_utf8();
     ///
     /// // we can see that they take six bytes total...
     /// assert_eq!(6, tokyo.len());
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index b5c5fc0608b..2db2e0bc0da 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, "", "", false);
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -133,7 +133,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             ty: Ty<'tcx>,
             expr: &hir::Expr,
             span: Span,
-            descr_post_path: &str,
+            descr_pre: &str,
+            descr_post: &str,
+            plural: bool,
         ) -> bool {
             if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
                 cx.tcx.hir().get_module_parent(expr.hir_id), ty)
@@ -141,15 +143,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 return true;
             }
 
+            let plural_suffix = if plural { "s" } else { "" };
+
             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 = &format!("{}boxed ", descr_pre);
+                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
+                }
+                ty::Adt(def, _) => {
+                    check_must_use_def(cx, def.did, span, descr_pre, descr_post)
+                }
                 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,
+                                plural_suffix,
+                            );
+                            if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
                                 has_emitted = true;
                                 break;
                             }
@@ -162,7 +178,12 @@ 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{}{}",
+                                plural_suffix,
+                                descr_post,
+                            );
+                            if check_must_use_def(cx, def_id, span, descr_pre, descr_post) {
                                 has_emitted = true;
                                 break;
                             }
@@ -179,14 +200,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                         vec![]
                     };
                     for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
-                        let descr_post_path = &format!(" in tuple element {}", i);
+                        let descr_post = &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, descr_post, plural) {
                             has_emitted = true;
                         }
                     }
                     has_emitted
                 }
+                ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
+                    // If the array is definitely non-empty, we can do `#[must_use]` checking.
+                    Some(n) if n != 0 => {
+                        let descr_pre = &format!(
+                            "{}array{} of ",
+                            descr_pre,
+                            plural_suffix,
+                        );
+                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
+                    }
+                    // Otherwise, we don't lint, to avoid false positives.
+                    _ => false,
+                }
                 _ => false,
             }
         }
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 80f65a9c8d0..6cdd9de8b95 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -228,9 +228,25 @@ where
     BD: BitDenotation<'tcx>,
 {
     fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
-        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
-            WorkQueue::with_all(self.builder.body.basic_blocks().len());
         let body = self.builder.body;
+
+        // Initialize the dirty queue in reverse post-order. This makes it more likely that the
+        // entry state for each basic block will have the effects of its predecessors applied
+        // before it is processed. In fact, for CFGs without back edges, this guarantees that
+        // dataflow will converge in exactly `N` iterations, where `N` is the number of basic
+        // blocks.
+        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
+            WorkQueue::with_none(body.basic_blocks().len());
+        for (bb, _) in traversal::reverse_postorder(body) {
+            dirty_queue.insert(bb);
+        }
+
+        // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
+        // be processed after the ones added above.
+        for bb in body.basic_blocks().indices() {
+            dirty_queue.insert(bb);
+        }
+
         while let Some(bb) = dirty_queue.pop() {
             let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index());
             debug_assert!(in_out.words().len() == on_entry.words().len());
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index cf0fc09472b..8ead571d966 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -75,9 +75,24 @@ pub fn liveness_of_locals<'tcx>(
 
     let mut bits = LiveVarSet::new_empty(num_live_vars);
 
-    // queue of things that need to be re-processed, and a set containing
-    // the things currently in the queue
-    let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(body.basic_blocks().len());
+    // The dirty queue contains the set of basic blocks whose entry sets have changed since they
+    // were last processed. At the start of the analysis, we initialize the queue in post-order to
+    // make it more likely that the entry set for a given basic block will have the effects of all
+    // its successors in the CFG applied before it is processed.
+    //
+    // FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
+    // order when cycles are present, but the overhead of computing the reverse CFG may outweigh
+    // any benefits. Benchmark this and find out.
+    let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks().len());
+    for (bb, _) in traversal::postorder(body) {
+        dirty_queue.insert(bb);
+    }
+
+    // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
+    // be processed after the ones added above.
+    for bb in body.basic_blocks().indices() {
+        dirty_queue.insert(bb);
+    }
 
     let predecessors = body.predecessors();
 
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 2da9c5adf9b..56063596299 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -837,13 +837,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                                  the relevant `fold_*()` method in `PlaceholderExpander`?");
     }
 
-    fn visit_fn_header(&mut self, header: &'a FnHeader) {
-        if header.asyncness.node.is_async() && self.session.rust_2015() {
-            struct_span_err!(self.session, header.asyncness.span, E0670,
-                             "`async fn` is not permitted in the 2015 edition").emit();
-        }
-    }
-
     fn visit_impl_item(&mut self, ii: &'a ImplItem) {
         match ii.node {
             ImplItemKind::Method(ref sig, _) => {
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 67113787915..ad211763a6c 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -16,7 +16,7 @@ use syntax_pos::Span;
 
 use crate::html::escape::Escape;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum Cfg {
     /// Accepts all configurations.
     True,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 41a56756a14..3fe048a6986 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -223,7 +223,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ExternalCrate {
     pub name: String,
     pub src: FileName,
@@ -355,7 +355,7 @@ impl Clean<ExternalCrate> for CrateNum {
 /// Anything with a source location and set of attributes and, optionally, a
 /// name. That is, anything that can be documented. This doesn't correspond
 /// directly to the AST's concept of an item; it's a strict superset.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone)]
 pub struct Item {
     /// Stringified span
     pub source: Span,
@@ -528,7 +528,7 @@ impl Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum ItemEnum {
     ExternCrateItem(String, Option<String>),
     ImportItem(Import),
@@ -594,7 +594,7 @@ impl ItemEnum {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Module {
     pub items: Vec<Item>,
     pub is_crate: bool,
@@ -731,7 +731,7 @@ impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
 /// Included files are kept separate from inline doc comments so that proper line-number
 /// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
 /// kept separate because of issue #42760.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum DocFragment {
     /// A doc fragment created from a `///` or `//!` doc comment.
     SugaredDoc(usize, syntax_pos::Span, String),
@@ -781,7 +781,7 @@ impl<'a> FromIterator<&'a DocFragment> for String {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default)]
+#[derive(Clone, Debug, Default)]
 pub struct Attributes {
     pub doc_strings: Vec<DocFragment>,
     pub other_attrs: Vec<ast::Attribute>,
@@ -1048,7 +1048,7 @@ impl Clean<Attributes> for [ast::Attribute] {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericBound {
     TraitBound(PolyTrait, hir::TraitBoundModifier),
     Outlives(Lifetime),
@@ -1231,7 +1231,7 @@ impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Lifetime(String);
 
 impl Lifetime {
@@ -1326,7 +1326,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
     BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
@@ -1464,7 +1464,7 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericParamDefKind {
     Lifetime,
     Type {
@@ -1498,7 +1498,7 @@ impl GenericParamDefKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct GenericParamDef {
     pub name: String,
 
@@ -1610,7 +1610,7 @@ impl Clean<GenericParamDef> for hir::GenericParam {
 }
 
 // maybe use a Generic enum and use Vec<Generic>?
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Default, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
 pub struct Generics {
     pub params: Vec<GenericParamDef>,
     pub where_predicates: Vec<WherePredicate>,
@@ -1874,7 +1874,7 @@ pub fn get_all_types(
     (all_types.into_iter().collect(), ret_types)
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Method {
     pub generics: Generics,
     pub decl: FnDecl,
@@ -1902,7 +1902,7 @@ impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId,
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct TyMethod {
     pub header: hir::FnHeader,
     pub decl: FnDecl,
@@ -1911,7 +1911,7 @@ pub struct TyMethod {
     pub ret_types: Vec<Type>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Function {
     pub decl: FnDecl,
     pub generics: Generics,
@@ -1952,7 +1952,7 @@ impl Clean<Item> for doctree::Function<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct FnDecl {
     pub inputs: Arguments,
     pub output: FunctionRetTy,
@@ -1989,7 +1989,7 @@ impl FnDecl {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Arguments {
     pub values: Vec<Argument>,
 }
@@ -2063,13 +2063,13 @@ impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Argument {
     pub type_: Type,
     pub name: String,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Debug)]
 pub enum SelfTy {
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
@@ -2093,7 +2093,7 @@ impl Argument {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum FunctionRetTy {
     Return(Type),
     DefaultReturn,
@@ -2117,7 +2117,7 @@ impl GetDefId for FunctionRetTy {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Trait {
     pub auto: bool,
     pub unsafety: hir::Unsafety,
@@ -2153,7 +2153,7 @@ impl Clean<Item> for doctree::Trait<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct TraitAlias {
     pub generics: Generics,
     pub bounds: Vec<GenericBound>,
@@ -2437,7 +2437,7 @@ impl Clean<Item> for ty::AssocItem {
 }
 
 /// A trait reference, which may have higher ranked lifetimes.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct PolyTrait {
     pub trait_: Type,
     pub generic_params: Vec<GenericParamDef>,
@@ -2446,7 +2446,7 @@ pub struct PolyTrait {
 /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
 /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
 /// importantly, it does not preserve mutability or boxes.
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum Type {
     /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
     ResolvedPath {
@@ -2469,7 +2469,6 @@ pub enum Type {
     Array(Box<Type>, String),
     Never,
     CVarArgs,
-    Unique(Box<Type>),
     RawPointer(Mutability, Box<Type>),
     BorrowedRef {
         lifetime: Option<Lifetime>,
@@ -2491,7 +2490,7 @@ pub enum Type {
     ImplTrait(Vec<GenericBound>),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
 pub enum PrimitiveType {
     Isize, I8, I16, I32, I64, I128,
     Usize, U8, U16, U32, U64, U128,
@@ -2510,7 +2509,7 @@ pub enum PrimitiveType {
     CVarArgs,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
+#[derive(Clone, Copy, Debug)]
 pub enum TypeKind {
     Enum,
     Function,
@@ -2520,7 +2519,6 @@ pub enum TypeKind {
     Struct,
     Union,
     Trait,
-    Variant,
     Typedef,
     Foreign,
     Macro,
@@ -3190,7 +3188,7 @@ impl Clean<Item> for ty::FieldDef {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Debug)]
 pub enum Visibility {
     Public,
     Inherited,
@@ -3219,7 +3217,7 @@ impl Clean<Option<Visibility>> for ty::Visibility {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Struct {
     pub struct_type: doctree::StructType,
     pub generics: Generics,
@@ -3227,7 +3225,7 @@ pub struct Struct {
     pub fields_stripped: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Union {
     pub struct_type: doctree::StructType,
     pub generics: Generics,
@@ -3278,7 +3276,7 @@ impl Clean<Item> for doctree::Union<'_> {
 /// This is a more limited form of the standard Struct, different in that
 /// it lacks the things most items have (name, id, parameterization). Found
 /// only as a variant in an enum.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct VariantStruct {
     pub struct_type: doctree::StructType,
     pub fields: Vec<Item>,
@@ -3295,7 +3293,7 @@ impl Clean<VariantStruct> for ::rustc::hir::VariantData {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Enum {
     pub variants: IndexVec<VariantIdx, Item>,
     pub generics: Generics,
@@ -3321,7 +3319,7 @@ impl Clean<Item> for doctree::Enum<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Variant {
     pub kind: VariantKind,
 }
@@ -3384,7 +3382,7 @@ impl Clean<Item> for ty::VariantDef {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum VariantKind {
     CLike,
     Tuple(Vec<Type>),
@@ -3402,7 +3400,7 @@ impl Clean<VariantKind> for hir::VariantData {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Span {
     pub filename: FileName,
     pub loline: usize,
@@ -3448,7 +3446,7 @@ impl Clean<Span> for syntax_pos::Span {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Path {
     pub global: bool,
     pub res: Res,
@@ -3471,7 +3469,7 @@ impl Clean<Path> for hir::Path {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArg {
     Lifetime(Lifetime),
     Type(Type),
@@ -3488,7 +3486,7 @@ impl fmt::Display for GenericArg {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArgs {
     AngleBracketed {
         args: Vec<GenericArg>,
@@ -3528,7 +3526,7 @@ impl Clean<GenericArgs> for hir::GenericArgs {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct PathSegment {
     pub name: String,
     pub args: GenericArgs,
@@ -3553,7 +3551,6 @@ fn strip_type(ty: Type) -> Type {
         }
         Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))),
         Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s),
-        Type::Unique(inner_ty) => Type::Unique(Box::new(strip_type(*inner_ty))),
         Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))),
         Type::BorrowedRef { lifetime, mutability, type_ } => {
             Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) }
@@ -3625,7 +3622,7 @@ impl Clean<String> for InternedString {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Typedef {
     pub type_: Type,
     pub generics: Generics,
@@ -3649,7 +3646,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Existential {
     pub bounds: Vec<GenericBound>,
     pub generics: Generics,
@@ -3673,7 +3670,7 @@ impl Clean<Item> for doctree::Existential<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct BareFunctionDecl {
     pub unsafety: hir::Unsafety,
     pub generic_params: Vec<GenericParamDef>,
@@ -3695,7 +3692,7 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Static {
     pub type_: Type,
     pub mutability: Mutability,
@@ -3725,7 +3722,7 @@ impl Clean<Item> for doctree::Static<'_> {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Constant {
     pub type_: Type,
     pub expr: String,
@@ -3749,7 +3746,7 @@ impl Clean<Item> for doctree::Constant<'_> {
     }
 }
 
-#[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
 pub enum Mutability {
     Mutable,
     Immutable,
@@ -3764,7 +3761,7 @@ impl Clean<Mutability> for hir::Mutability {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Copy, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Copy, Debug, Hash)]
 pub enum ImplPolarity {
     Positive,
     Negative,
@@ -3779,7 +3776,7 @@ impl Clean<ImplPolarity> for hir::ImplPolarity {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Impl {
     pub unsafety: hir::Unsafety,
     pub generics: Generics,
@@ -4003,7 +4000,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub enum Import {
     // use source as str;
     Simple(String, ImportSource),
@@ -4011,7 +4008,7 @@ pub enum Import {
     Glob(ImportSource)
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ImportSource {
     pub path: Path,
     pub did: Option<DefId>,
@@ -4227,7 +4224,7 @@ fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Macro {
     pub source: String,
     pub imported_from: Option<String>,
@@ -4256,7 +4253,7 @@ impl Clean<Item> for doctree::Macro<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct ProcMacro {
     pub kind: MacroKind,
     pub helpers: Vec<String>,
@@ -4280,7 +4277,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Stability {
     pub level: stability::StabilityLevel,
     pub feature: Option<String>,
@@ -4290,7 +4287,7 @@ pub struct Stability {
     pub issue: Option<u32>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Deprecation {
     pub since: Option<String>,
     pub note: Option<String>,
@@ -4340,13 +4337,13 @@ impl Clean<Deprecation> for attr::Deprecation {
 
 /// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: Send + Sync` in `Foo<A: Send + Sync>`).
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct TypeBinding {
     pub name: String,
     pub kind: TypeBindingKind,
 }
 
-#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum TypeBindingKind {
     Equality {
         ty: Type,
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 51deb4e9b97..2557b8d1627 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -78,7 +78,7 @@ impl Module<'hir> {
     }
 }
 
-#[derive(Debug, Clone, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Debug, Clone, Copy)]
 pub enum StructType {
     /// A braced struct
     Plain,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index fa3bc3f5f4f..9e5cc03b831 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -737,9 +737,6 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 }
             }
         }
-        clean::Unique(..) => {
-            panic!("should have been cleaned")
-        }
     }
 }
 
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index 3f3f4c85e81..5f1a1b31616 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -110,7 +110,6 @@ impl From<clean::TypeKind> for ItemType {
             clean::TypeKind::Module     => ItemType::Module,
             clean::TypeKind::Static     => ItemType::Static,
             clean::TypeKind::Const      => ItemType::Constant,
-            clean::TypeKind::Variant    => ItemType::Variant,
             clean::TypeKind::Typedef    => ItemType::Typedef,
             clean::TypeKind::Foreign    => ItemType::ForeignType,
             clean::TypeKind::Macro      => ItemType::Macro,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index f0aff961c67..2080637ecb4 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -5188,9 +5188,6 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> {
             clean::Type::Array(ty, _) => {
                 work.push_back(*ty);
             },
-            clean::Type::Unique(ty) => {
-                work.push_back(*ty);
-            },
             clean::Type::RawPointer(_, ty) => {
                 work.push_back(*ty);
             },
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 7a8b088020c..ba423300e02 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -42,8 +42,6 @@ extern crate test as testing;
 #[macro_use] extern crate log;
 extern crate rustc_errors as errors;
 
-extern crate serialize as rustc_serialize; // used by deriving
-
 use std::default::Default;
 use std::env;
 use std::panic;
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 9ef42063f94..797d85e941d 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/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fc206580e38..696b5f48385 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5734,9 +5734,12 @@ impl<'a> Parser<'a> {
     {
         let is_const_fn = self.eat_keyword(kw::Const);
         let const_span = self.prev_span;
-        let unsafety = self.parse_unsafety();
         let asyncness = self.parse_asyncness();
+        if let IsAsync::Async { .. } = asyncness {
+            self.ban_async_in_2015(self.prev_span);
+        }
         let asyncness = respan(self.prev_span, asyncness);
+        let unsafety = self.parse_unsafety();
         let (constness, unsafety, abi) = if is_const_fn {
             (respan(const_span, Constness::Const), unsafety, Abi::Rust)
         } else {
@@ -7254,13 +7257,7 @@ impl<'a> Parser<'a> {
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                if self.token.span.rust_2015() {
-                    self.diagnostic().struct_span_err_with_code(
-                        async_span,
-                        "`async fn` is not permitted in the 2015 edition",
-                        DiagnosticId::Error("E0670".into())
-                    ).emit();
-                }
+                self.ban_async_in_2015(async_span);
                 return Ok(Some(item));
             }
         }
@@ -7534,6 +7531,19 @@ impl<'a> Parser<'a> {
         self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
     }
 
+    /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
+    fn ban_async_in_2015(&self, async_span: Span) {
+        if async_span.rust_2015() {
+            self.diagnostic()
+                .struct_span_err_with_code(
+                    async_span,
+                    "`async fn` is not permitted in the 2015 edition",
+                    DiagnosticId::Error("E0670".into())
+                )
+                .emit();
+        }
+    }
+
     /// Parses a foreign item.
     crate fn parse_foreign_item(&mut self) -> PResult<'a, ForeignItem> {
         maybe_whole!(self, NtForeignItem, |ni| ni);
diff --git a/src/test/run-pass/issues/issue-30530.rs b/src/test/run-pass/issues/issue-30530.rs
index e837fc81721..111fb8aa506 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 ebe4f70378c..6badd203842 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/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs
index 38261ca4570..0eae1467fbf 100644
--- a/src/test/ui/async-await/async-await.rs
+++ b/src/test/ui/async-await/async-await.rs
@@ -134,11 +134,15 @@ trait Bar {
 }
 
 impl Foo {
-    async fn async_method(x: u8) -> u8 {
+    async fn async_assoc_item(x: u8) -> u8 {
         unsafe {
             unsafe_async_fn(x).await
         }
     }
+
+    async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 {
+        unsafe_async_fn(x).await
+    }
 }
 
 fn test_future_yields_once_then_returns<F, Fut>(f: F)
@@ -180,12 +184,17 @@ fn main() {
         async_fn,
         generic_async_fn,
         async_fn_with_internal_borrow,
-        Foo::async_method,
+        Foo::async_assoc_item,
         |x| {
             async move {
                 unsafe { unsafe_async_fn(x).await }
             }
         },
+        |x| {
+            async move {
+                unsafe { Foo::async_unsafe_assoc_item(x).await }
+            }
+        },
     }
     test_with_borrow! {
         async_block_with_borrow_named_lifetime,
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
index e1111f9e0e4..a5bc1810154 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
@@ -28,6 +28,12 @@ fn main() {
         async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
     }
 
+    accept_item! {
+        impl Foo {
+            async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
+        }
+    }
+
     let inside_closure = || {
         async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
     };
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index 05a06124dc2..efb4462095d 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -23,7 +23,19 @@ LL | async fn async_baz() {
    | ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:32:9
+  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^
+
+error[E0670]: `async fn` is not permitted in the 2015 edition
+  --> $DIR/edition-deny-async-fns-2015.rs:38:9
    |
 LL |         async fn bar() {}
    |         ^^^^^
@@ -35,10 +47,10 @@ LL |         async fn foo() {}
    |         ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+  --> $DIR/edition-deny-async-fns-2015.rs:33:13
    |
-LL |     async fn foo() {}
-   |     ^^^^^
+LL |             async fn bar() {}
+   |             ^^^^^
 
 error[E0706]: trait fns cannot be declared `async`
   --> $DIR/edition-deny-async-fns-2015.rs:20:5
@@ -46,12 +58,6 @@ error[E0706]: trait fns cannot be declared `async`
 LL |     async fn foo() {}
    |     ^^^^^^^^^^^^^^^^^
 
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:20:5
-   |
-LL |     async fn foo() {}
-   |     ^^^^^
-
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0670`.
diff --git a/src/test/ui/async-await/no-unsafe-async.rs b/src/test/ui/async-await/no-unsafe-async.rs
new file mode 100644
index 00000000000..81e0cd799ad
--- /dev/null
+++ b/src/test/ui/async-await/no-unsafe-async.rs
@@ -0,0 +1,11 @@
+// edition:2018
+
+struct S;
+
+impl S {
+    #[cfg(FALSE)]
+    unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found `async`
+}
+
+#[cfg(FALSE)]
+unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found `async`
diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr
new file mode 100644
index 00000000000..c339c7c3bf5
--- /dev/null
+++ b/src/test/ui/async-await/no-unsafe-async.stderr
@@ -0,0 +1,14 @@
+error: expected one of `extern` or `fn`, found `async`
+  --> $DIR/no-unsafe-async.rs:7:12
+   |
+LL |     unsafe async fn g() {}
+   |            ^^^^^ expected one of `extern` or `fn` here
+
+error: expected one of `extern`, `fn`, or `{`, found `async`
+  --> $DIR/no-unsafe-async.rs:11:8
+   |
+LL | unsafe async fn f() {}
+   |        ^^^^^ expected one of `extern`, `fn`, or `{` here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lint/must_use-array.rs b/src/test/ui/lint/must_use-array.rs
new file mode 100644
index 00000000000..97825dd2f6c
--- /dev/null
+++ b/src/test/ui/lint/must_use-array.rs
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+
+#[must_use]
+struct S;
+
+struct A;
+
+#[must_use]
+trait T {}
+
+impl T for A {}
+
+fn empty() -> [S; 0] {
+    []
+}
+
+fn singleton() -> [S; 1] {
+    [S]
+}
+
+fn many() -> [S; 4] {
+    [S, S, S, S]
+}
+
+fn array_of_impl_trait() -> [impl T; 2] {
+    [A, A]
+}
+
+fn impl_array() -> [(u8, Box<dyn T>); 2] {
+    [(0, Box::new(A)), (0, Box::new(A))]
+}
+
+fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
+    [[[S], [S]]]
+}
+
+fn main() {
+    empty(); // ok
+    singleton(); //~ ERROR unused array of `S` that must be used
+    many(); //~ ERROR unused array of `S` that must be used
+    ([S], 0, ()); //~ ERROR unused array of `S` in tuple element 0 that must be used
+    array_of_impl_trait(); //~ ERROR unused array of implementers of `T` that must be used
+    impl_array();
+    //~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
+    array_of_arrays_of_arrays();
+    //~^ ERROR unused array of arrays of arrays of `S` that must be used
+}
diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/must_use-array.stderr
new file mode 100644
index 00000000000..a6dbd8e93d4
--- /dev/null
+++ b/src/test/ui/lint/must_use-array.stderr
@@ -0,0 +1,44 @@
+error: unused array of `S` that must be used
+  --> $DIR/must_use-array.rs:39:5
+   |
+LL |     singleton();
+   |     ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/must_use-array.rs:1:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+
+error: unused array of `S` that must be used
+  --> $DIR/must_use-array.rs:40:5
+   |
+LL |     many();
+   |     ^^^^^^^
+
+error: unused array of `S` in tuple element 0 that must be used
+  --> $DIR/must_use-array.rs:41:6
+   |
+LL |     ([S], 0, ());
+   |      ^^^
+
+error: unused array of implementers of `T` that must be used
+  --> $DIR/must_use-array.rs:42:5
+   |
+LL |     array_of_impl_trait();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused array of boxed `T` trait objects in tuple element 1 that must be used
+  --> $DIR/must_use-array.rs:43:5
+   |
+LL |     impl_array();
+   |     ^^^^^^^^^^^^^
+
+error: unused array of arrays of arrays of `S` that must be used
+  --> $DIR/must_use-array.rs:45:5
+   |
+LL |     array_of_arrays_of_arrays();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs
index 23df4fa6132..0aa751443a0 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 7e2b2f67964..be74362e29d 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
-Subproject 945f007c0d305c3ec069b5e5d911ef783f6d70e
+Subproject 72b2e1045d642c517347c421b1db92e34c22a70