about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs23
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs10
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs25
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs27
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs1
-rw-r--r--compiler/rustc_hir/src/hir.rs20
-rw-r--r--compiler/rustc_hir/src/intravisit.rs14
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs9
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs23
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs42
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs41
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp8
-rw-r--r--compiler/rustc_macros/src/serialize.rs26
-rw-r--r--compiler/rustc_middle/Cargo.toml2
-rw-r--r--compiler/rustc_middle/src/mir/generic_graph.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs5
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs9
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs14
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs9
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs9
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs14
-rw-r--r--compiler/rustc_query_system/src/ich/impls_hir.rs25
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs28
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs4
-rw-r--r--compiler/rustc_serialize/src/opaque.rs23
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs10
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs4
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs7
-rw-r--r--compiler/rustc_typeck/src/collect.rs18
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs6
-rw-r--r--library/alloc/src/alloc.rs23
-rw-r--r--library/alloc/src/boxed.rs92
-rw-r--r--library/alloc/src/lib.rs16
-rw-r--r--library/alloc/tests/boxed.rs114
-rw-r--r--library/alloc/tests/lib.rs12
-rw-r--r--library/core/src/fmt/mod.rs23
-rw-r--r--library/core/src/macros/mod.rs13
-rw-r--r--library/core/src/ops/unsize.rs33
-rw-r--r--library/core/src/option.rs300
-rw-r--r--library/core/src/prelude/v1.rs15
-rw-r--r--library/core/src/result.rs749
-rw-r--r--library/std/src/prelude/v1.rs19
-rw-r--r--library/std/src/sync/mpsc/mod.rs3
-rw-r--r--library/std/src/sys/windows/stdio.rs72
-rw-r--r--library/test/src/lib.rs18
-rw-r--r--library/test/src/stats.rs1
-rw-r--r--library/test/src/types.rs7
-rw-r--r--src/bootstrap/bootstrap.py3
-rw-r--r--src/bootstrap/builder.rs16
-rw-r--r--src/bootstrap/flags.rs34
m---------src/doc/book0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/librustdoc/clean/mod.rs28
-rw-r--r--src/librustdoc/clean/types.rs25
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css111
-rw-r--r--src/test/incremental/change_private_fn/struct_point.rs6
-rw-r--r--src/test/incremental/hash-module-order.rs28
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs12
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr9
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/array-repeat-expr.rs13
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/infer-arg-test.rs (renamed from src/test/ui/inference/infer-arg-test.rs)2
-rw-r--r--src/test/ui/const-generics/generic_arg_infer/infer-arg-test.stderr (renamed from src/test/ui/inference/infer-arg-test.stderr)14
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr37
-rw-r--r--src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs10
-rw-r--r--src/test/ui/inference/char-as-str-multi.rs6
-rw-r--r--src/test/ui/inference/char-as-str-multi.stderr11
-rw-r--r--src/test/ui/inference/char-as-str-single.fixed11
-rw-r--r--src/test/ui/inference/char-as-str-single.rs11
-rw-r--r--src/test/ui/inference/char-as-str-single.stderr29
-rw-r--r--src/test/ui/inference/str-as-char.fixed8
-rw-r--r--src/test/ui/inference/str-as-char.rs8
-rw-r--r--src/test/ui/inference/str-as-char.stderr16
-rw-r--r--src/test/ui/issues/issue-23589.stderr5
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr1
-rw-r--r--src/test/ui/macros/stringify.rs8
-rw-r--r--src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs2
-rw-r--r--src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr20
-rw-r--r--src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs4
-rw-r--r--src/test/ui/suggestions/while-let-typo.rs9
-rw-r--r--src/test/ui/suggestions/while-let-typo.stderr45
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/inspector.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs39
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs1
-rw-r--r--src/tools/clippy/tests/ui/author/repeat.stdout3
107 files changed, 1661 insertions, 1004 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a912eee97db..1fe03a06c79 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1505,9 +1505,9 @@ dependencies = [
 
 [[package]]
 name = "gsgdt"
-version = "0.1.3"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb958139bb971f37d2f5423436f137768f88b9c616b4c21d4f634dd129508d60"
+checksum = "a0d876ce7262df96262a2a19531da6ff9a86048224d49580a585fc5c04617825"
 dependencies = [
  "serde",
 ]
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 6ee1dbe4ae3..75f384405bb 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -34,7 +34,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Repeat(ref expr, ref count) => {
                     let expr = self.lower_expr(expr);
-                    let count = self.lower_anon_const(count);
+                    let count = self.lower_array_length(count);
                     hir::ExprKind::Repeat(expr, count)
                 }
                 ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 77738b2c5cc..35eb716949a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -56,6 +56,7 @@ use rustc_hir::{ConstArg, GenericArg, ParamName};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::lint::LintBuffer;
+use rustc_session::parse::feature_err;
 use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
 use rustc_session::Session;
 use rustc_span::hygiene::ExpnId;
@@ -1248,7 +1249,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 ))
             }
             TyKind::Array(ref ty, ref length) => {
-                hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
+                hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
             }
             TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
             TyKind::TraitObject(ref bounds, kind) => {
@@ -2039,6 +2040,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.expr_block(block, AttrVec::new())
     }
 
+    fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
+        match c.value.kind {
+            ExprKind::Underscore => {
+                if self.sess.features_untracked().generic_arg_infer {
+                    hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
+                } else {
+                    feature_err(
+                        &self.sess.parse_sess,
+                        sym::generic_arg_infer,
+                        c.value.span,
+                        "using `_` for array lengths is unstable",
+                    )
+                    .emit();
+                    hir::ArrayLen::Body(self.lower_anon_const(c))
+                }
+            }
+            _ => hir::ArrayLen::Body(self.lower_anon_const(c)),
+        }
+    }
+
     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
         self.with_new_scopes(|this| hir::AnonConst {
             hir_id: this.lower_node_id(c.id),
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b87dd449a1e..91fa4595241 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -2461,7 +2461,11 @@ impl<'a> State<'a> {
                     self.print_path(path, true, 0);
                 }
                 self.nbsp();
-                self.word_space("{");
+                self.word("{");
+                let empty = fields.is_empty() && !etc;
+                if !empty {
+                    self.space();
+                }
                 self.commasep_cmnt(
                     Consistent,
                     &fields,
@@ -2482,7 +2486,9 @@ impl<'a> State<'a> {
                     }
                     self.word("..");
                 }
-                self.space();
+                if !empty {
+                    self.space();
+                }
                 self.word("}");
             }
             PatKind::Tuple(ref elts) => {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 63ffcb3ec45..fe34d6e7ca9 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1394,10 +1394,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
             Rvalue::NullaryOp(_op, _ty) => {
                 // nullary ops take no dynamic input; no borrowck effect.
-                //
-                // FIXME: is above actually true? Do we want to track
-                // the fact that uninitialized data can be created via
-                // `NullOp::Box`?
             }
 
             Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index fc2f04f146e..b16f5af66f2 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -715,30 +715,6 @@ fn codegen_stmt<'tcx>(
                     let operand = operand.load_scalar(fx);
                     lval.write_cvalue(fx, CValue::by_val(operand, box_layout));
                 }
-                Rvalue::NullaryOp(NullOp::Box, content_ty) => {
-                    let usize_type = fx.clif_type(fx.tcx.types.usize).unwrap();
-                    let content_ty = fx.monomorphize(content_ty);
-                    let layout = fx.layout_of(content_ty);
-                    let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64);
-                    let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64);
-                    let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty));
-
-                    // Allocate space:
-                    let def_id =
-                        match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) {
-                            Ok(id) => id,
-                            Err(s) => {
-                                fx.tcx
-                                    .sess
-                                    .fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
-                            }
-                        };
-                    let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
-                    let func_ref = fx.get_function_ref(instance);
-                    let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]);
-                    let ptr = fx.bcx.inst_results(call)[0];
-                    lval.write_cvalue(fx, CValue::by_val(ptr, box_layout));
-                }
                 Rvalue::NullaryOp(null_op, ty) => {
                     assert!(
                         lval.layout()
@@ -749,7 +725,6 @@ fn codegen_stmt<'tcx>(
                     let val = match null_op {
                         NullOp::SizeOf => layout.size.bytes(),
                         NullOp::AlignOf => layout.align.abi.bytes(),
-                        NullOp::Box => unreachable!(),
                     };
                     let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
                     lval.write_cvalue(fx, val);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 3e7371179cc..01f7868df34 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -160,17 +160,17 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
         // the values should match the ones in the DWARF standard anyway.
         let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
         let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() };
-        let mut addr_ops = SmallVec::<[_; 8]>::new();
+        let mut addr_ops = SmallVec::<[u64; 8]>::new();
 
         if direct_offset.bytes() > 0 {
             addr_ops.push(op_plus_uconst());
-            addr_ops.push(direct_offset.bytes() as i64);
+            addr_ops.push(direct_offset.bytes() as u64);
         }
         for &offset in indirect_offsets {
             addr_ops.push(op_deref());
             if offset.bytes() > 0 {
                 addr_ops.push(op_plus_uconst());
-                addr_ops.push(offset.bytes() as i64);
+                addr_ops.push(offset.bytes() as u64);
             }
         }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 6450b7490bd..f2782f84f55 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2108,7 +2108,7 @@ extern "C" {
         Builder: &DIBuilder<'a>,
         Val: &'a Value,
         VarInfo: &'a DIVariable,
-        AddrOps: *const i64,
+        AddrOps: *const u64,
         AddrOpsCount: c_uint,
         DL: &'a DILocation,
         InsertAtEnd: &'a BasicBlock,
@@ -2199,8 +2199,8 @@ extern "C" {
         Scope: &'a DIScope,
         InlinedAt: Option<&'a DILocation>,
     ) -> &'a DILocation;
-    pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
-    pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
+    pub fn LLVMRustDIBuilderCreateOpDeref() -> u64;
+    pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> u64;
 
     #[allow(improper_ctypes)]
     pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString);
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 7c97143e807..79c24f0f172 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -6,8 +6,8 @@ use std::path::Path;
 
 use object::write::{self, StandardSegment, Symbol, SymbolSection};
 use object::{
-    elf, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, SectionFlags,
-    SectionKind, SymbolFlags, SymbolKind, SymbolScope,
+    elf, pe, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection,
+    SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
 };
 
 use snap::write::FrameEncoder;
@@ -216,13 +216,12 @@ pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> Vec<u8> {
     );
     match file.format() {
         BinaryFormat::Coff => {
-            const IMAGE_SCN_LNK_REMOVE: u32 = 0;
             file.section_mut(section).flags =
-                SectionFlags::Coff { characteristics: IMAGE_SCN_LNK_REMOVE };
+                SectionFlags::Coff { characteristics: pe::IMAGE_SCN_LNK_REMOVE };
         }
         BinaryFormat::Elf => {
-            const SHF_EXCLUDE: u64 = 0x80000000;
-            file.section_mut(section).flags = SectionFlags::Elf { sh_flags: SHF_EXCLUDE };
+            file.section_mut(section).flags =
+                SectionFlags::Elf { sh_flags: elf::SHF_EXCLUDE as u64 };
         }
         _ => {}
     };
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6f960ca44cd..679c4576701 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -8,7 +8,6 @@ use crate::traits::*;
 use crate::MemFlags;
 
 use rustc_apfloat::{ieee, Float, Round, Status};
-use rustc_hir::lang_items::LangItem;
 use rustc_middle::mir;
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
@@ -486,31 +485,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 )
             }
 
-            mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
-                let content_ty = self.monomorphize(content_ty);
-                let content_layout = bx.cx().layout_of(content_ty);
-                let llsize = bx.cx().const_usize(content_layout.size.bytes());
-                let llalign = bx.cx().const_usize(content_layout.align.abi.bytes());
-                let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty));
-                let llty_ptr = bx.cx().backend_type(box_layout);
-
-                // Allocate space:
-                let def_id = match bx.tcx().lang_items().require(LangItem::ExchangeMalloc) {
-                    Ok(id) => id,
-                    Err(s) => {
-                        bx.cx().sess().fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
-                    }
-                };
-                let instance = ty::Instance::mono(bx.tcx(), def_id);
-                let r = bx.cx().get_fn_addr(instance);
-                let ty = bx.type_func(&[bx.type_isize(), bx.type_isize()], bx.type_i8p());
-                let call = bx.call(ty, r, &[llsize, llalign], None);
-                let val = bx.pointercast(call, llty_ptr);
-
-                let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout };
-                (bx, operand)
-            }
-
             mir::Rvalue::NullaryOp(null_op, ty) => {
                 let ty = self.monomorphize(ty);
                 assert!(bx.cx().type_is_sized(ty));
@@ -518,7 +492,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
                     mir::NullOp::AlignOf => layout.align.abi.bytes(),
-                    mir::NullOp::Box => unreachable!(),
                 };
                 let val = bx.cx().const_usize(val);
                 let tcx = self.cx.tcx();
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index c5412affafe..3ec9f3ca3b8 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -63,7 +63,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
         cid.instance,
         body,
         Some(&ret.into()),
-        StackPopCleanup::None { cleanup: false },
+        StackPopCleanup::Root { cleanup: false },
     )?;
 
     // The main interpreter loop.
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index fef0e00e507..30e9cbe4403 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -398,13 +398,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
         Err(ConstEvalErrKind::NeedsRfc("pointer arithmetic or comparison".to_string()).into())
     }
 
-    fn box_alloc(
-        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _dest: &PlaceTy<'tcx>,
-    ) -> InterpResult<'tcx> {
-        Err(ConstEvalErrKind::NeedsRfc("heap allocations via `box` keyword".to_string()).into())
-    }
-
     fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         // The step limit has already been hit in a previous call to `before_terminator`.
         if ecx.machine.steps_remaining == 0 {
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 246807a112a..0a8112da2ab 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -156,11 +156,11 @@ pub enum StackPopCleanup {
     /// `ret` stores the block we jump to on a normal return, while `unwind`
     /// stores the block used for cleanup during unwinding.
     Goto { ret: Option<mir::BasicBlock>, unwind: StackPopUnwind },
-    /// Just do nothing: Used by Main and for the `box_alloc` hook in miri.
+    /// The root frame of the stack: nowhere else to jump to.
     /// `cleanup` says whether locals are deallocated. Static computation
     /// wants them leaked to intern what they need (and just throw away
     /// the entire `ecx` when it is done).
-    None { cleanup: bool },
+    Root { cleanup: bool },
 }
 
 /// State of a local variable including a memoized layout
@@ -849,7 +849,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // because this is CTFE and the final value will be thoroughly validated anyway.
         let cleanup = match return_to_block {
             StackPopCleanup::Goto { .. } => true,
-            StackPopCleanup::None { cleanup, .. } => cleanup,
+            StackPopCleanup::Root { cleanup, .. } => cleanup,
         };
 
         if !cleanup {
@@ -874,8 +874,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Follow the unwind edge.
             let unwind = match return_to_block {
                 StackPopCleanup::Goto { unwind, .. } => unwind,
-                StackPopCleanup::None { .. } => {
-                    panic!("Encountered StackPopCleanup::None when unwinding!")
+                StackPopCleanup::Root { .. } => {
+                    panic!("encountered StackPopCleanup::Root when unwinding!")
                 }
             };
             self.unwind_to_block(unwind)
@@ -883,7 +883,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Follow the normal return edge.
             match return_to_block {
                 StackPopCleanup::Goto { ret, .. } => self.return_to_block(ret),
-                StackPopCleanup::None { .. } => Ok(()),
+                StackPopCleanup::Root { .. } => {
+                    assert!(
+                        self.stack().is_empty(),
+                        "only the topmost frame can have StackPopCleanup::Root"
+                    );
+                    Ok(())
+                }
             }
         }
     }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 6a03b699d47..23ec3875cbc 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -212,12 +212,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
         right: &ImmTy<'tcx, Self::PointerTag>,
     ) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool, Ty<'tcx>)>;
 
-    /// Heap allocations via the `box` keyword.
-    fn box_alloc(
-        ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        dest: &PlaceTy<'tcx, Self::PointerTag>,
-    ) -> InterpResult<'tcx>;
-
     /// Called to read the specified `local` from the `frame`.
     /// Since reading a ZST is not actually accessing memory or locals, this is never invoked
     /// for ZST reads.
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 6e37aae0f5e..3daa1d3c2b3 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -271,10 +271,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_immediate(place.to_ref(self), &dest)?;
             }
 
-            NullaryOp(mir::NullOp::Box, _) => {
-                M::box_alloc(self, &dest)?;
-            }
-
             NullaryOp(null_op, ty) => {
                 let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
                 let layout = self.layout_of(ty)?;
@@ -289,7 +285,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
                     mir::NullOp::AlignOf => layout.align.abi.bytes(),
-                    mir::NullOp::Box => unreachable!(),
                 };
                 self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?;
             }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 1d5f4630152..dd749c03934 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -632,7 +632,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             }
 
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
-            Rvalue::NullaryOp(NullOp::Box, _) => self.check_op(ops::HeapAllocation),
             Rvalue::ShallowInitBox(_, _) => {}
 
             Rvalue::UnaryOp(_, ref operand) => {
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 1537de993d1..55fba5d7ddf 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -508,7 +508,6 @@ impl<'tcx> Validator<'_, 'tcx> {
             }
 
             Rvalue::NullaryOp(op, _) => match op {
-                NullOp::Box => return Err(Unpromotable),
                 NullOp::SizeOf => {}
                 NullOp::AlignOf => {}
             },
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 69572807e7c..d59756239d9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1407,6 +1407,20 @@ impl fmt::Display for ConstContext {
 /// A literal.
 pub type Lit = Spanned<LitKind>;
 
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
+pub enum ArrayLen {
+    Infer(HirId, Span),
+    Body(AnonConst),
+}
+
+impl ArrayLen {
+    pub fn hir_id(&self) -> HirId {
+        match self {
+            &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, body: _ }) => hir_id,
+        }
+    }
+}
+
 /// A constant (expression) that's not an item or associated item,
 /// but needs its own `DefId` for type-checking, const-eval, etc.
 /// These are usually found nested inside types (e.g., array lengths)
@@ -1756,7 +1770,7 @@ pub enum ExprKind<'hir> {
     ///
     /// E.g., `[1; 5]`. The first expression is the element
     /// to be repeated; the second is the number of times to repeat it.
-    Repeat(&'hir Expr<'hir>, AnonConst),
+    Repeat(&'hir Expr<'hir>, ArrayLen),
 
     /// A suspension point for generators (i.e., `yield <expr>`).
     Yield(&'hir Expr<'hir>, YieldSource),
@@ -2266,7 +2280,7 @@ pub enum TyKind<'hir> {
     /// A variable length slice (i.e., `[T]`).
     Slice(&'hir Ty<'hir>),
     /// A fixed length array (i.e., `[T; n]`).
-    Array(&'hir Ty<'hir>, AnonConst),
+    Array(&'hir Ty<'hir>, ArrayLen),
     /// A raw pointer (i.e., `*const T` or `*mut T`).
     Ptr(MutTy<'hir>),
     /// A reference (i.e., `&'a T` or `&'a mut T`).
@@ -2484,7 +2498,7 @@ impl FnRetTy<'_> {
     }
 }
 
-#[derive(Encodable, Debug)]
+#[derive(Encodable, Debug, HashStable_Generic)]
 pub struct Mod<'hir> {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 0fab7cbfeea..d0eee422202 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -383,6 +383,9 @@ pub trait Visitor<'v>: Sized {
     fn visit_pat(&mut self, p: &'v Pat<'v>) {
         walk_pat(self, p)
     }
+    fn visit_array_length(&mut self, len: &'v ArrayLen) {
+        walk_array_len(self, len)
+    }
     fn visit_anon_const(&mut self, c: &'v AnonConst) {
         walk_anon_const(self, c)
     }
@@ -753,7 +756,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
         }
         TyKind::Array(ref ty, ref length) => {
             visitor.visit_ty(ty);
-            visitor.visit_anon_const(length)
+            visitor.visit_array_length(length)
         }
         TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
             for bound in bounds {
@@ -1124,6 +1127,13 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
     }
 }
 
+pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
+    match len {
+        &ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id),
+        ArrayLen::Body(c) => visitor.visit_anon_const(c),
+    }
+}
+
 pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
     visitor.visit_id(constant.hir_id);
     visitor.visit_nested_body(constant.body);
@@ -1147,7 +1157,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const),
         ExprKind::Repeat(ref element, ref count) => {
             visitor.visit_expr(element);
-            visitor.visit_anon_const(count)
+            visitor.visit_array_length(count)
         }
         ExprKind::Struct(ref qpath, fields, ref optional_base) => {
             visitor.visit_qpath(qpath, expression.hir_id, expression.span);
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index c8d729a999e..a43c1f9d9ae 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHas
 
 use crate::hir::{
     AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item,
-    ItemId, Mod, OwnerNodes, TraitCandidate, TraitItem, TraitItemId, Ty, VisibilityKind,
+    ItemId, OwnerNodes, TraitCandidate, TraitItem, TraitItemId, Ty, VisibilityKind,
 };
 use crate::hir_id::{HirId, ItemLocalId};
 use rustc_span::def_id::DefPathHash;
@@ -16,7 +16,6 @@ pub trait HashStableContext:
     fn hash_hir_id(&mut self, _: HirId, hasher: &mut StableHasher);
     fn hash_body_id(&mut self, _: BodyId, hasher: &mut StableHasher);
     fn hash_reference_to_item(&mut self, _: HirId, hasher: &mut StableHasher);
-    fn hash_hir_mod(&mut self, _: &Mod<'_>, hasher: &mut StableHasher);
     fn hash_hir_expr(&mut self, _: &Expr<'_>, hasher: &mut StableHasher);
     fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
     fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
@@ -132,12 +131,6 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItemId {
     }
 }
 
-impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Mod<'_> {
-    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
-        hcx.hash_hir_mod(self, hasher)
-    }
-}
-
 impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Expr<'_> {
     fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
         hcx.hash_hir_expr(self, hasher)
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index fb11aaf24c4..4c9e2d7fe42 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -358,7 +358,7 @@ impl<'a> State<'a> {
                 self.word("[");
                 self.print_type(&ty);
                 self.word("; ");
-                self.print_anon_const(length);
+                self.print_array_length(length);
                 self.word("]");
             }
             hir::TyKind::Typeof(ref e) => {
@@ -1065,6 +1065,13 @@ impl<'a> State<'a> {
         self.print_else(elseopt)
     }
 
+    pub fn print_array_length(&mut self, len: &hir::ArrayLen) {
+        match len {
+            hir::ArrayLen::Infer(_, _) => self.word("_"),
+            hir::ArrayLen::Body(ct) => self.print_anon_const(ct),
+        }
+    }
+
     pub fn print_anon_const(&mut self, constant: &hir::AnonConst) {
         self.ann.nested(self, Nested::Body(constant.body))
     }
@@ -1140,12 +1147,12 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::AnonConst) {
+    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ArrayLen) {
         self.ibox(INDENT_UNIT);
         self.word("[");
         self.print_expr(element);
         self.word_space(";");
-        self.print_anon_const(count);
+        self.print_array_length(count);
         self.word("]");
         self.end()
     }
@@ -1874,7 +1881,11 @@ impl<'a> State<'a> {
             PatKind::Struct(ref qpath, ref fields, etc) => {
                 self.print_qpath(qpath, true);
                 self.nbsp();
-                self.word_space("{");
+                self.word("{");
+                let empty = fields.is_empty() && !etc;
+                if !empty {
+                    self.space();
+                }
                 self.commasep_cmnt(
                     Consistent,
                     &fields,
@@ -1895,7 +1906,9 @@ impl<'a> State<'a> {
                     }
                     self.word("..");
                 }
-                self.space();
+                if !empty {
+                    self.space();
+                }
                 self.word("}");
             }
             PatKind::Or(ref pats) => {
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 7ac00b4609a..88795679943 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -9,6 +9,13 @@
 //! - `#[rustc_clean(cfg="rev2")]` same as above, except that the
 //!   fingerprints must be the SAME (along with all other fingerprints).
 //!
+//! - `#[rustc_clean(cfg="rev2", loaded_from_disk='typeck")]` asserts that
+//!   the query result for `DepNode::typeck(X)` was actually
+//!   loaded from disk (not just marked green). This can be useful
+//!   to ensure that a test is actually exercising the deserialization
+//!   logic for a particular query result. This can be combined with
+//!   `except`
+//!
 //! Errors are reported if we are in the suitable configuration but
 //! the required condition is not met.
 
@@ -28,6 +35,7 @@ use rustc_span::Span;
 use std::iter::FromIterator;
 use std::vec::Vec;
 
+const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk;
 const EXCEPT: Symbol = sym::except;
 const CFG: Symbol = sym::cfg;
 
@@ -124,6 +132,7 @@ type Labels = FxHashSet<String>;
 struct Assertion {
     clean: Labels,
     dirty: Labels,
+    loaded_from_disk: Labels,
 }
 
 pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
@@ -174,6 +183,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
     fn assertion_auto(&mut self, item_id: LocalDefId, attr: &Attribute) -> Assertion {
         let (name, mut auto) = self.auto_labels(item_id, attr);
         let except = self.except(attr);
+        let loaded_from_disk = self.loaded_from_disk(attr);
         for e in except.iter() {
             if !auto.remove(e) {
                 let msg = format!(
@@ -183,7 +193,19 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
                 self.tcx.sess.span_fatal(attr.span, &msg);
             }
         }
-        Assertion { clean: auto, dirty: except }
+        Assertion { clean: auto, dirty: except, loaded_from_disk }
+    }
+
+    /// `loaded_from_disk=` attribute value
+    fn loaded_from_disk(&self, attr: &Attribute) -> Labels {
+        for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+            if item.has_name(LOADED_FROM_DISK) {
+                let value = expect_associated_value(self.tcx, &item);
+                return self.resolve_labels(&item, value);
+            }
+        }
+        // If `loaded_from_disk=` is not specified, don't assert anything
+        Labels::default()
     }
 
     /// `except=` attribute value
@@ -332,6 +354,18 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
         }
     }
 
+    fn assert_loaded_from_disk(&self, item_span: Span, dep_node: DepNode) {
+        debug!("assert_loaded_from_disk({:?})", dep_node);
+
+        if !self.tcx.dep_graph.debug_was_loaded_from_disk(dep_node) {
+            let dep_node_str = self.dep_node_str(&dep_node);
+            self.tcx.sess.span_err(
+                item_span,
+                &format!("`{}` should have been loaded from disk but it was not", dep_node_str),
+            );
+        }
+    }
+
     fn check_item(&mut self, item_id: LocalDefId, item_span: Span) {
         let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id());
         for attr in self.tcx.get_attrs(item_id.to_def_id()).iter() {
@@ -348,6 +382,10 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
                 let dep_node = DepNode::from_label_string(self.tcx, &label, def_path_hash).unwrap();
                 self.assert_dirty(item_span, dep_node);
             }
+            for label in assertion.loaded_from_disk {
+                let dep_node = DepNode::from_label_string(self.tcx, &label, def_path_hash).unwrap();
+                self.assert_loaded_from_disk(item_span, dep_node);
+            }
         }
     }
 }
@@ -382,7 +420,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
             let value = expect_associated_value(tcx, &item);
             debug!("check_config: searching for cfg {:?}", value);
             cfg = Some(config.contains(&(value, None)));
-        } else if !item.has_name(EXCEPT) {
+        } else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
             tcx.sess.span_err(attr.span, &format!("unknown item `{}`", item.name_or_empty()));
         }
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 9a76c05e4f6..f0c73d0c2f3 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2041,11 +2041,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 if let ValuePairs::Types(ty::error::ExpectedFound { expected, found }) =
                     trace.values
                 {
-                    // If a tuple of length one was expected and the found expression has
-                    // parentheses around it, perhaps the user meant to write `(expr,)` to
-                    // build a tuple (issue #86100)
                     match (expected.kind(), found.kind()) {
                         (ty::Tuple(_), ty::Tuple(_)) => {}
+                        // If a tuple of length one was expected and the found expression has
+                        // parentheses around it, perhaps the user meant to write `(expr,)` to
+                        // build a tuple (issue #86100)
                         (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
                             if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
                                 if let Some(code) =
@@ -2060,6 +2060,41 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                 }
                             }
                         }
+                        // If a character was expected and the found expression is a string literal
+                        // containing a single character, perhaps the user meant to write `'c'` to
+                        // specify a character literal (issue #92479)
+                        (ty::Char, ty::Ref(_, r, _)) if r.is_str() => {
+                            if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
+                                if let Some(code) =
+                                    code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
+                                {
+                                    if code.chars().nth(1).is_none() {
+                                        err.span_suggestion(
+                                            span,
+                                            "if you meant to write a `char` literal, use single quotes",
+                                            format!("'{}'", code),
+                                            Applicability::MachineApplicable,
+                                        );
+                                    }
+                                }
+                            }
+                        }
+                        // If a string was expected and the found expression is a character literal,
+                        // perhaps the user meant to write `"s"` to specify a string literal.
+                        (ty::Ref(_, r, _), ty::Char) if r.is_str() => {
+                            if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
+                                if let Some(code) =
+                                    code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
+                                {
+                                    err.span_suggestion(
+                                        span,
+                                        "if you meant to write a `str` literal, use double quotes",
+                                        format!("\"{}\"", code),
+                                        Applicability::MachineApplicable,
+                                    );
+                                }
+                            }
+                        }
                         _ => {}
                     }
                 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 025a0ee376e..2a0f4fdc774 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -979,11 +979,11 @@ LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
 
 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
     LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
-    int64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
+    uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL,
     LLVMBasicBlockRef InsertAtEnd) {
   return wrap(Builder->insertDeclare(
       unwrap(V), unwrap<DILocalVariable>(VarInfo),
-      Builder->createExpression(llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
+      Builder->createExpression(llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
       DebugLoc(cast<MDNode>(unwrap(DL))),
       unwrap(InsertAtEnd)));
 }
@@ -1057,11 +1057,11 @@ LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
   return wrap(Loc);
 }
 
-extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() {
+extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
   return dwarf::DW_OP_deref;
 }
 
-extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() {
+extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
   return dwarf::DW_OP_plus_uconst;
 }
 
diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs
index 66e6b571beb..3351564299c 100644
--- a/compiler/rustc_macros/src/serialize.rs
+++ b/compiler/rustc_macros/src/serialize.rs
@@ -1,6 +1,7 @@
 use proc_macro2::TokenStream;
-use quote::quote;
+use quote::{quote, quote_spanned};
 use syn::parse_quote;
+use syn::spanned::Spanned;
 
 pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
     let decoder_ty = quote! { __D };
@@ -104,6 +105,8 @@ fn decodable_body(
 }
 
 fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro2::TokenStream {
+    let field_span = field.ident.as_ref().map_or(field.ty.span(), |ident| ident.span());
+
     let decode_inner_method = if let syn::Type::Reference(_) = field.ty {
         quote! { ::rustc_middle::ty::codec::RefDecodable::decode }
     } else {
@@ -111,20 +114,21 @@ fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro
     };
     let (decode_method, opt_field_name) = if is_struct {
         let field_name = field.ident.as_ref().map_or_else(|| index.to_string(), |i| i.to_string());
-        (
-            proc_macro2::Ident::new("read_struct_field", proc_macro2::Span::call_site()),
-            quote! { #field_name, },
-        )
+        (proc_macro2::Ident::new("read_struct_field", field_span), quote! { #field_name, })
     } else {
-        (
-            proc_macro2::Ident::new("read_enum_variant_arg", proc_macro2::Span::call_site()),
-            quote! {},
-        )
+        (proc_macro2::Ident::new("read_enum_variant_arg", field_span), quote! {})
+    };
+
+    let __decoder = quote! { __decoder };
+    // Use the span of the field for the method call, so
+    // that backtraces will point to the field.
+    let decode_call = quote_spanned! {field_span=>
+        ::rustc_serialize::Decoder::#decode_method(
+                #__decoder, #opt_field_name #decode_inner_method)
     };
 
     quote! {
-        match ::rustc_serialize::Decoder::#decode_method(
-            __decoder, #opt_field_name #decode_inner_method) {
+        match #decode_call  {
             ::std::result::Result::Ok(__res) => __res,
             ::std::result::Result::Err(__err) => return ::std::result::Result::Err(__err),
         }
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index f8d3fb6c48d..a9db8469384 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -10,7 +10,7 @@ doctest = false
 rustc_arena = { path = "../rustc_arena" }
 bitflags = "1.2.1"
 either = "1.5.0"
-gsgdt = "0.1.3"
+gsgdt = "0.1.2"
 tracing = "0.1"
 rustc-rayon = "0.3.1"
 rustc-rayon-core = "0.3.1"
diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs
index 44d0ce935df..770b52a4d4b 100644
--- a/compiler/rustc_middle/src/mir/generic_graph.rs
+++ b/compiler/rustc_middle/src/mir/generic_graph.rs
@@ -55,7 +55,7 @@ fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node
     data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
     stmts.push(terminator_head);
 
-    Node::from_list(stmts, label, title, style)
+    Node::new(stmts, label, title, style)
 }
 
 // Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index c7c306e7d06..52ef380001c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2336,8 +2336,6 @@ pub enum NullOp {
     SizeOf,
     /// Returns the minimum alignment of a type
     AlignOf,
-    /// Creates a new uninitialized box for a value of that type
-    Box,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index e577df48205..dc53dc8de9d 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -195,7 +195,6 @@ impl<'tcx> Rvalue<'tcx> {
             }
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
-            Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64),
@@ -215,9 +214,7 @@ impl<'tcx> Rvalue<'tcx> {
     /// whether its only shallowly initialized (`Rvalue::Box`).
     pub fn initialization_state(&self) -> RvalueInitializationState {
         match *self {
-            Rvalue::NullaryOp(NullOp::Box, _) | Rvalue::ShallowInitBox(_, _) => {
-                RvalueInitializationState::Shallow
-            }
+            Rvalue::ShallowInitBox(_, _) => RvalueInitializationState::Shallow,
             _ => RvalueInitializationState::Deep,
         }
     }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 092fe131174..bdde6b4a356 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -583,9 +583,12 @@ impl<'tcx> Cx<'tcx> {
                 ExprKind::ConstBlock { value }
             }
             // Now comes the rote stuff:
-            hir::ExprKind::Repeat(ref v, ref count) => {
-                let count_def_id = self.tcx.hir().local_def_id(count.hir_id);
-                let count = ty::Const::from_anon_const(self.tcx, count_def_id);
+            hir::ExprKind::Repeat(ref v, _) => {
+                let ty = self.typeck_results().expr_ty(expr);
+                let count = match ty.kind() {
+                    ty::Array(_, ct) => ct,
+                    _ => span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty),
+                };
 
                 ExprKind::Repeat { value: self.mirror_expr(v), count }
             }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index feb85d4ffdf..2e00b4f9a5e 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -343,19 +343,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             | Rvalue::AddressOf(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Len(..)
-            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
-            | Rvalue::NullaryOp(NullOp::Box, _) => {
-                // This returns an rvalue with uninitialized contents. We can't
-                // move out of it here because it is an rvalue - assignments always
-                // completely initialize their place.
-                //
-                // However, this does not matter - MIR building is careful to
-                // only emit a shallow free for the partially-initialized
-                // temporary.
-                //
-                // In any case, if we want to fix this, we have to register a
-                // special move and change the `statement_effect` functions.
-            }
+            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 7e56e062fc9..e3ff6ad4549 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -239,13 +239,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
         throw_machine_stop_str!("pointer arithmetic or comparisons aren't supported in ConstProp")
     }
 
-    fn box_alloc(
-        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _dest: &PlaceTy<'tcx>,
-    ) -> InterpResult<'tcx> {
-        throw_machine_stop_str!("can't const prop heap allocations")
-    }
-
     fn access_local(
         _ecx: &InterpCx<'mir, 'tcx, Self>,
         frame: &Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>,
@@ -413,7 +406,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             Instance::new(def_id, substs),
             dummy_body,
             ret.as_ref(),
-            StackPopCleanup::None { cleanup: false },
+            StackPopCleanup::Root { cleanup: false },
         )
         .expect("failed to push initial stack frame");
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index b1fa9041342..b70c24b76d5 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -688,15 +688,6 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                     _ => bug!(),
                 }
             }
-            mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => {
-                let tcx = self.tcx;
-                let exchange_malloc_fn_def_id =
-                    tcx.require_lang_item(LangItem::ExchangeMalloc, None);
-                let instance = Instance::mono(tcx, exchange_malloc_fn_def_id);
-                if should_codegen_locally(tcx, &instance) {
-                    self.output.push(create_fn_mono_item(self.tcx, instance, span));
-                }
-            }
             mir::Rvalue::ThreadLocalRef(def_id) => {
                 assert!(self.tcx.is_thread_local_static(def_id));
                 let instance = Instance::mono(self.tcx, def_id);
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index a8be1ca34c0..7bc3fd718e0 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -88,6 +88,11 @@ struct DepGraphData<K: DepKind> {
     previous_work_products: FxHashMap<WorkProductId, WorkProduct>,
 
     dep_node_debug: Lock<FxHashMap<DepNode<K>, String>>,
+
+    /// Used by incremental compilation tests to assert that
+    /// a particular query result was decoded from disk
+    /// (not just marked green)
+    debug_loaded_from_disk: Lock<FxHashSet<DepNode<K>>>,
 }
 
 pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Fingerprint
@@ -135,6 +140,7 @@ impl<K: DepKind> DepGraph<K> {
                 processed_side_effects: Default::default(),
                 previous: prev_graph,
                 colors: DepNodeColorMap::new(prev_graph_node_count),
+                debug_loaded_from_disk: Default::default(),
             })),
             virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
         }
@@ -438,6 +444,14 @@ impl<K: DepKind> DepGraph<K> {
         &self.data.as_ref().unwrap().previous_work_products
     }
 
+    pub fn mark_debug_loaded_from_disk(&self, dep_node: DepNode<K>) {
+        self.data.as_ref().unwrap().debug_loaded_from_disk.lock().insert(dep_node);
+    }
+
+    pub fn debug_was_loaded_from_disk(&self, dep_node: DepNode<K>) -> bool {
+        self.data.as_ref().unwrap().debug_loaded_from_disk.lock().contains(&dep_node)
+    }
+
     #[inline(always)]
     pub fn register_dep_node_debug_str<F>(&self, dep_node: DepNode<K>, debug_str_gen: F)
     where
diff --git a/compiler/rustc_query_system/src/ich/impls_hir.rs b/compiler/rustc_query_system/src/ich/impls_hir.rs
index 3a0aab81fdb..3117140a5b6 100644
--- a/compiler/rustc_query_system/src/ich/impls_hir.rs
+++ b/compiler/rustc_query_system/src/ich/impls_hir.rs
@@ -3,8 +3,7 @@
 
 use crate::ich::hcx::BodyResolver;
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
-use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir as hir;
 use std::mem;
 
@@ -47,28 +46,6 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
         })
     }
 
-    #[inline]
-    fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
-        let hcx = self;
-        let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
-
-        inner_span.hash_stable(hcx, hasher);
-
-        // Combining the `DefPathHash`s directly is faster than feeding them
-        // into the hasher. Because we use a commutative combine, we also don't
-        // have to sort the array.
-        let item_ids_hash = item_ids
-            .iter()
-            .map(|id| {
-                let def_path_hash = id.to_stable_hash_key(hcx);
-                def_path_hash.0
-            })
-            .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
-
-        item_ids.len().hash_stable(hcx, hasher);
-        item_ids_hash.hash_stable(hcx, hasher);
-    }
-
     fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
         self.while_hashing_hir_bodies(true, |hcx| {
             let hir::Expr { hir_id: _, ref span, ref kind } = *expr;
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index b08db39e245..33732f9df73 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -519,6 +519,10 @@ where
         prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
         if let Some(result) = result {
+            if unlikely!(tcx.dep_context().sess().opts.debugging_opts.query_dep_graph) {
+                dep_graph.mark_debug_loaded_from_disk(*dep_node)
+            }
+
             let prev_fingerprint = tcx
                 .dep_context()
                 .dep_graph()
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 5098cef11e8..57305023138 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2379,7 +2379,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             ExprKind::While(ref cond, ref block, label) => {
                 self.with_resolved_label(label, expr.id, |this| {
                     this.with_rib(ValueNS, NormalRibKind, |this| {
+                        let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                         this.visit_expr(cond);
+                        this.diagnostic_metadata.in_if_condition = old;
                         this.visit_block(block);
                     })
                 });
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index f1a5282b088..23f5b17fa78 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -1326,12 +1326,18 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 }
                 intravisit::walk_qpath(self, path, t.hir_id, t.span);
             }
-            hir::TyKind::Array(ref ty, ref anon_const) => {
+            hir::TyKind::Array(ref ty, ref length) => {
                 self.visit_ty(ty);
                 let map = self.tcx.hir();
-                self.nest_typeck_results(self.tcx.hir().local_def_id(anon_const.hir_id), |v| {
-                    v.visit_expr(&map.body(anon_const.body).value)
-                });
+                match length {
+                    // FIXME(generic_arg_infer): We probably want to
+                    // output the inferred type here? :shrug:
+                    hir::ArrayLen::Infer(..) => {}
+                    hir::ArrayLen::Body(anon_const) => self
+                        .nest_typeck_results(self.tcx.hir().local_def_id(anon_const.hir_id), |v| {
+                            v.visit_expr(&map.body(anon_const.body).value)
+                        }),
+                }
             }
             hir::TyKind::OpaqueDef(item_id, _) => {
                 let item = self.tcx.hir().item(item_id);
@@ -1390,12 +1396,18 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                     v.visit_expr(&body.value)
                 });
             }
-            hir::ExprKind::Repeat(ref expr, ref anon_const) => {
+            hir::ExprKind::Repeat(ref expr, ref length) => {
                 self.visit_expr(expr);
                 let map = self.tcx.hir();
-                self.nest_typeck_results(self.tcx.hir().local_def_id(anon_const.hir_id), |v| {
-                    v.visit_expr(&map.body(anon_const.body).value)
-                });
+                match length {
+                    // FIXME(generic_arg_infer): We probably want to
+                    // output the inferred type here? :shrug:
+                    hir::ArrayLen::Infer(..) => {}
+                    hir::ArrayLen::Body(anon_const) => self
+                        .nest_typeck_results(self.tcx.hir().local_def_id(anon_const.hir_id), |v| {
+                            v.visit_expr(&map.body(anon_const.body).value)
+                        }),
+                }
             }
             // In particular, we take this branch for call and path expressions,
             // where we'll index the idents involved just by continuing to walk.
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index e43344ad6d9..4971bb6d1aa 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -310,9 +310,9 @@ impl<'hir> Sig for hir::Ty<'hir> {
                 let nested = bounds_to_string(&bounds);
                 Ok(text_sig(nested))
             }
-            hir::TyKind::Array(ref ty, ref anon_const) => {
+            hir::TyKind::Array(ref ty, ref length) => {
                 let nested_ty = ty.make(offset + 1, id, scx)?;
-                let expr = id_to_string(&scx.tcx.hir(), anon_const.body.hir_id).replace('\n', " ");
+                let expr = id_to_string(&scx.tcx.hir(), length.hir_id()).replace('\n', " ");
                 let text = format!("[{}; {}]", nested_ty.text, expr);
                 Ok(replace_text(nested_ty, text))
             }
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index cc1216418ae..f2ef1481681 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -92,7 +92,8 @@ impl serialize::Encoder for Encoder {
 
     #[inline]
     fn emit_u16(&mut self, v: u16) -> EncodeResult {
-        write_leb128!(self, v, u16, write_u16_leb128)
+        self.data.extend_from_slice(&v.to_le_bytes());
+        Ok(())
     }
 
     #[inline]
@@ -123,7 +124,8 @@ impl serialize::Encoder for Encoder {
 
     #[inline]
     fn emit_i16(&mut self, v: i16) -> EncodeResult {
-        write_leb128!(self, v, i16, write_i16_leb128)
+        self.data.extend_from_slice(&v.to_le_bytes());
+        Ok(())
     }
 
     #[inline]
@@ -446,7 +448,7 @@ impl serialize::Encoder for FileEncoder {
 
     #[inline]
     fn emit_u16(&mut self, v: u16) -> FileEncodeResult {
-        file_encoder_write_leb128!(self, v, u16, write_u16_leb128)
+        self.write_all(&v.to_le_bytes())
     }
 
     #[inline]
@@ -476,13 +478,12 @@ impl serialize::Encoder for FileEncoder {
 
     #[inline]
     fn emit_i16(&mut self, v: i16) -> FileEncodeResult {
-        file_encoder_write_leb128!(self, v, i16, write_i16_leb128)
+        self.write_all(&v.to_le_bytes())
     }
 
     #[inline]
     fn emit_i8(&mut self, v: i8) -> FileEncodeResult {
-        let as_u8: u8 = unsafe { std::mem::transmute(v) };
-        self.emit_u8(as_u8)
+        self.emit_u8(v as u8)
     }
 
     #[inline]
@@ -591,7 +592,10 @@ impl<'a> serialize::Decoder for Decoder<'a> {
 
     #[inline]
     fn read_u16(&mut self) -> Result<u16, Self::Error> {
-        read_leb128!(self, read_u16_leb128)
+        let bytes = [self.data[self.position], self.data[self.position + 1]];
+        let value = u16::from_le_bytes(bytes);
+        self.position += 2;
+        Ok(value)
     }
 
     #[inline]
@@ -623,7 +627,10 @@ impl<'a> serialize::Decoder for Decoder<'a> {
 
     #[inline]
     fn read_i16(&mut self) -> Result<i16, Self::Error> {
-        read_leb128!(self, read_i16_leb128)
+        let bytes = [self.data[self.position], self.data[self.position + 1]];
+        let value = i16::from_le_bytes(bytes);
+        self.position += 2;
+        Ok(value)
     }
 
     #[inline]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 51a7a2644f6..84cf8878af8 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -788,6 +788,7 @@ symbols! {
         literal,
         llvm_asm,
         load,
+        loaded_from_disk,
         local,
         local_inner_macros,
         log10f32,
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index caa5c71e21c..956696546da 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -104,7 +104,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
                 GenericParamDefKind::Const { .. },
             ) if tcx.type_of(param.def_id) == tcx.types.usize => {
-                let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id));
+                let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id()));
                 if let Ok(snippet) = snippet {
                     err.span_suggestion(
                         arg.span(),
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 8db706c3709..8226ffbccc4 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2363,8 +2363,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 self.normalize_ty(span, tcx.at(span).type_of(def_id).subst(tcx, substs))
             }
             hir::TyKind::Array(ref ty, ref length) => {
-                let length_def_id = tcx.hir().local_def_id(length.hir_id);
-                let length = ty::Const::from_anon_const(tcx, length_def_id);
+                let length = match length {
+                    &hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
+                    hir::ArrayLen::Body(constant) => {
+                        let length_def_id = tcx.hir().local_def_id(constant.hir_id);
+                        ty::Const::from_anon_const(tcx, length_def_id)
+                    }
+                };
+
                 let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length));
                 self.normalize_ty(ast_ty.span, array_ty)
             }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 8d370e440ea..621938c9b78 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1238,12 +1238,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_expr_repeat(
         &self,
         element: &'tcx hir::Expr<'tcx>,
-        count: &'tcx hir::AnonConst,
+        count: &'tcx hir::ArrayLen,
         expected: Expectation<'tcx>,
         _expr: &'tcx hir::Expr<'tcx>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let count = self.to_const(count);
+        let count = self.array_length_to_const(count);
 
         let uty = match expected {
             ExpectHasType(uty) => match *uty.kind() {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 67630fd4e58..1aca2911533 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -498,6 +498,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ty
     }
 
+    pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> &'tcx ty::Const<'tcx> {
+        match length {
+            &hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span),
+            hir::ArrayLen::Body(anon_const) => self.to_const(anon_const),
+        }
+    }
+
     pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
         let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
         let c = ty::Const::from_anon_const(self.tcx, const_def_id);
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 2fb5590016e..e1fef84d9d9 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -182,7 +182,7 @@ crate fn placeholder_type_error<'tcx>(
         sugg.push((span, format!(", {}", type_name)));
     }
 
-    let mut err = bad_placeholder_type(tcx, placeholder_types, kind);
+    let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
 
     // Suggest, but only if it is not a function in const or static
     if suggest {
@@ -314,8 +314,9 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Utility types and common code for the above passes.
 
-fn bad_placeholder_type<'tcx>(
+fn bad_placeholder<'tcx>(
     tcx: TyCtxt<'tcx>,
+    placeholder_kind: &'static str,
     mut spans: Vec<Span>,
     kind: &'static str,
 ) -> rustc_errors::DiagnosticBuilder<'tcx> {
@@ -326,7 +327,8 @@ fn bad_placeholder_type<'tcx>(
         tcx.sess,
         spans.clone(),
         E0121,
-        "the type placeholder `_` is not allowed within types on item signatures for {}",
+        "the {} placeholder `_` is not allowed within types on item signatures for {}",
+        placeholder_kind,
         kind
     );
     for span in spans {
@@ -393,7 +395,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
         _: Option<&ty::GenericParamDef>,
         span: Span,
     ) -> &'tcx Const<'tcx> {
-        bad_placeholder_type(self.tcx(), vec![span], "generic").emit();
+        bad_placeholder(self.tcx(), "const", vec![span], "generic").emit();
         // Typeck doesn't expect erased regions to be returned from `type_of`.
         let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
             ty::ReErased => self.tcx.lifetimes.re_static,
@@ -1482,7 +1484,11 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                     // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
                     // as they shouldn't be able to cause query cycle errors.
                     Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
-                    | Node::Variant(Variant { disr_expr: Some(ref constant), .. })
+                        if constant.hir_id() == hir_id =>
+                    {
+                        Some(parent_def_id.to_def_id())
+                    }
+                    Node::Variant(Variant { disr_expr: Some(ref constant), .. })
                         if constant.hir_id == hir_id =>
                     {
                         Some(parent_def_id.to_def_id())
@@ -1788,7 +1794,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
 
                     let mut visitor = PlaceholderHirTyCollector::default();
                     visitor.visit_ty(ty);
-                    let mut diag = bad_placeholder_type(tcx, visitor.0, "return type");
+                    let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
                     let ret_ty = fn_sig.skip_binder().output();
                     if !ret_ty.references_error() {
                         if !ret_ty.is_closure() {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 99fddcb00ce..04e887bf742 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -13,7 +13,7 @@ use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
 use super::ItemCtxt;
-use super::{bad_placeholder_type, is_suggestable_infer_ty};
+use super::{bad_placeholder, is_suggestable_infer_ty};
 
 /// Computes the relevant generic parameter for a potential generic const argument.
 ///
@@ -490,7 +490,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             match parent_node {
                 Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
                 | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
-                    if constant.hir_id == hir_id =>
+                    if constant.hir_id() == hir_id =>
                 {
                     tcx.types.usize
                 }
@@ -788,7 +788,7 @@ fn infer_placeholder_type<'a>(
             err.emit();
         }
         None => {
-            let mut diag = bad_placeholder_type(tcx, vec![span], kind);
+            let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
 
             if !ty.references_error() {
                 let mut mk_nameable = MakeNameable::new(tcx);
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 66ef92558d8..d075658f51a 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -323,17 +323,21 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 
 #[cfg_attr(not(test), lang = "box_free")]
 #[inline]
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
 // This signature has to be the same as `Box`, otherwise an ICE will happen.
 // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
 // well.
 // For example if `Box` is changed to  `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
 // this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
-pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
+pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Drop>(
+    ptr: Unique<T>,
+    alloc: A,
+) {
     unsafe {
         let size = size_of_val(ptr.as_ref());
         let align = min_align_of_val(ptr.as_ref());
         let layout = Layout::from_size_align_unchecked(size, align);
-        alloc.deallocate(ptr.cast().into(), layout)
+        alloc.deallocate(From::from(ptr.cast()), layout)
     }
 }
 
@@ -361,13 +365,22 @@ extern "Rust" {
 /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
 /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
 #[stable(feature = "global_alloc", since = "1.28.0")]
+#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
 #[cfg(all(not(no_global_oom_handling), not(test)))]
 #[rustc_allocator_nounwind]
 #[cold]
-pub fn handle_alloc_error(layout: Layout) -> ! {
-    unsafe {
-        __rust_alloc_error_handler(layout.size(), layout.align());
+pub const fn handle_alloc_error(layout: Layout) -> ! {
+    const fn ct_error(_: Layout) -> ! {
+        panic!("allocation failed");
     }
+
+    fn rt_error(layout: Layout) -> ! {
+        unsafe {
+            __rust_alloc_error_handler(layout.size(), layout.align());
+        }
+    }
+
+    unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
 }
 
 // For alloc test `std::alloc::handle_alloc_error` can be used directly.
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index ab41f5646e5..aa7344ba405 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -346,9 +346,13 @@ impl<T, A: Allocator> Box<T, A> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[must_use]
     #[inline]
-    pub fn new_in(x: T, alloc: A) -> Self {
+    pub const fn new_in(x: T, alloc: A) -> Self
+    where
+        A: ~const Allocator + ~const Drop,
+    {
         let mut boxed = Self::new_uninit_in(alloc);
         unsafe {
             boxed.as_mut_ptr().write(x);
@@ -372,8 +376,13 @@ impl<T, A: Allocator> Box<T, A> {
     /// # Ok::<(), std::alloc::AllocError>(())
     /// ```
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
+    pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
+    where
+        T: ~const Drop,
+        A: ~const Allocator + ~const Drop,
+    {
         let mut boxed = Self::try_new_uninit_in(alloc)?;
         unsafe {
             boxed.as_mut_ptr().write(x);
@@ -402,10 +411,14 @@ impl<T, A: Allocator> Box<T, A> {
     /// assert_eq!(*five, 5)
     /// ```
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[cfg(not(no_global_oom_handling))]
     #[must_use]
     // #[unstable(feature = "new_uninit", issue = "63291")]
-    pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
+    pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
+    where
+        A: ~const Allocator + ~const Drop,
+    {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
         // That would make code size bigger.
@@ -439,7 +452,11 @@ impl<T, A: Allocator> Box<T, A> {
     /// ```
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
-    pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
+    pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
+    where
+        A: ~const Allocator + ~const Drop,
+    {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         let ptr = alloc.allocate(layout)?.cast();
         unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -466,10 +483,14 @@ impl<T, A: Allocator> Box<T, A> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[cfg(not(no_global_oom_handling))]
     // #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
-    pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
+    pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
+    where
+        A: ~const Allocator + ~const Drop,
+    {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
         // That would make code size bigger.
@@ -503,7 +524,11 @@ impl<T, A: Allocator> Box<T, A> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
-    pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
+    pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
+    where
+        A: ~const Allocator + ~const Drop,
+    {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         let ptr = alloc.allocate_zeroed(layout)?.cast();
         unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -513,20 +538,22 @@ impl<T, A: Allocator> Box<T, A> {
     /// `x` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[must_use]
     #[inline(always)]
-    pub fn pin_in(x: T, alloc: A) -> Pin<Self>
+    pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
     where
-        A: 'static,
+        A: 'static + ~const Allocator + ~const Drop,
     {
-        Self::new_in(x, alloc).into()
+        Self::into_pin(Self::new_in(x, alloc))
     }
 
     /// Converts a `Box<T>` into a `Box<[T]>`
     ///
     /// This conversion does not allocate on the heap and happens in place.
     #[unstable(feature = "box_into_boxed_slice", issue = "71582")]
-    pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
+    pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
         let (raw, alloc) = Box::into_raw_with_allocator(boxed);
         unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
     }
@@ -543,8 +570,12 @@ impl<T, A: Allocator> Box<T, A> {
     /// assert_eq!(Box::into_inner(c), 5);
     /// ```
     #[unstable(feature = "box_into_inner", issue = "80437")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn into_inner(boxed: Self) -> T {
+    pub const fn into_inner(boxed: Self) -> T
+    where
+        Self: ~const Drop,
+    {
         *boxed
     }
 }
@@ -758,8 +789,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     /// assert_eq!(*five, 5)
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub unsafe fn assume_init(self) -> Box<T, A> {
+    pub const unsafe fn assume_init(self) -> Box<T, A> {
         let (raw, alloc) = Box::into_raw_with_allocator(self);
         unsafe { Box::from_raw_in(raw as *mut T, alloc) }
     }
@@ -792,8 +824,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     /// }
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
+    pub const fn write(mut boxed: Self, value: T) -> Box<T, A> {
         unsafe {
             (*boxed).write(value);
             boxed.assume_init()
@@ -938,8 +971,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
     /// [memory layout]: self#memory-layout
     /// [`Layout`]: crate::Layout
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
+    pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
         Box(unsafe { Unique::new_unchecked(raw) }, alloc)
     }
 
@@ -1035,8 +1069,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
     ///
     /// [memory layout]: self#memory-layout
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
+    pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
         let (leaked, alloc) = Box::into_unique(b);
         (leaked.as_ptr(), alloc)
     }
@@ -1046,9 +1081,10 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
         issue = "none",
         reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
     )]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
     #[doc(hidden)]
-    pub fn into_unique(b: Self) -> (Unique<T>, A) {
+    pub const fn into_unique(b: Self) -> (Unique<T>, A) {
         // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
         // raw pointer for the type system. Turning it directly into a raw pointer would not be
         // recognized as "releasing" the unique pointer to permit aliased raw accesses,
@@ -1064,8 +1100,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
     /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This
     /// is so that there is no conflict with a method on the inner type.
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn allocator(b: &Self) -> &A {
+    pub const fn allocator(b: &Self) -> &A {
         &b.1
     }
 
@@ -1105,8 +1142,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
     /// assert_eq!(*static_ref, [4, 2, 3]);
     /// ```
     #[stable(feature = "box_leak", since = "1.26.0")]
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    pub fn leak<'a>(b: Self) -> &'a mut T
+    pub const fn leak<'a>(b: Self) -> &'a mut T
     where
         A: 'a,
     {
@@ -1119,7 +1157,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
     ///
     /// This is also available via [`From`].
     #[unstable(feature = "box_into_pin", issue = "62370")]
-    pub fn into_pin(boxed: Self) -> Pin<Self>
+    #[rustc_const_unstable(feature = "const_box", issue = "92521")]
+    pub const fn into_pin(boxed: Self) -> Pin<Self>
     where
         A: 'static,
     {
@@ -1131,7 +1170,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
+unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> const Drop for Box<T, A> {
     fn drop(&mut self) {
         // FIXME: Do nothing, drop is currently performed by compiler.
     }
@@ -1341,7 +1381,8 @@ impl<T> From<T> for Box<T> {
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
+impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
 where
     A: 'static,
 {
@@ -1720,7 +1761,8 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
+impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> {
     type Target = T;
 
     fn deref(&self) -> &T {
@@ -1729,7 +1771,8 @@ impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
+impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> {
     fn deref_mut(&mut self) -> &mut T {
         &mut **self
     }
@@ -1908,7 +1951,8 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
  *  could have a method to project a Pin<T> from it.
  */
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
+#[rustc_const_unstable(feature = "const_box", issue = "92521")]
+impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static {}
 
 #[unstable(feature = "generator_trait", issue = "43122")]
 impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 600862c4224..7e663fab16a 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -96,9 +96,20 @@
 #![feature(array_windows)]
 #![feature(async_stream)]
 #![feature(coerce_unsized)]
+#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
+#![feature(const_box)]
 #![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
 #![feature(const_cow_is_borrowed)]
+#![feature(const_convert)]
+#![feature(const_size_of_val)]
+#![feature(const_align_of_val)]
+#![feature(const_ptr_read)]
+#![feature(const_maybe_uninit_write)]
+#![feature(const_maybe_uninit_as_mut_ptr)]
+#![feature(const_refs_to_cell)]
 #![feature(core_intrinsics)]
+#![feature(const_eval_select)]
+#![feature(const_pin)]
 #![feature(dispatch_from_dyn)]
 #![feature(exact_size_is_empty)]
 #![feature(extend_one)]
@@ -134,8 +145,13 @@
 #![feature(box_syntax)]
 #![feature(cfg_sanitize)]
 #![feature(cfg_target_has_atomic)]
+#![feature(const_deref)]
 #![feature(const_fn_trait_bound)]
+#![feature(const_mut_refs)]
+#![feature(const_ptr_write)]
+#![feature(const_precise_live_drops)]
 #![feature(const_trait_impl)]
+#![feature(const_try)]
 #![cfg_attr(bootstrap, feature(destructuring_assignment))]
 #![feature(dropck_eyepatch)]
 #![feature(exclusive_range_pattern)]
diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs
index bfe66b2687e..0d7acfed8c6 100644
--- a/library/alloc/tests/boxed.rs
+++ b/library/alloc/tests/boxed.rs
@@ -1,6 +1,7 @@
-use std::cell::Cell;
-use std::mem::MaybeUninit;
-use std::ptr::NonNull;
+use core::alloc::{AllocError, Allocator, Layout};
+use core::cell::Cell;
+use core::mem::MaybeUninit;
+use core::ptr::NonNull;
 
 #[test]
 fn uninitialized_zero_size_box() {
@@ -57,3 +58,110 @@ fn box_deref_lval() {
     x.set(1000);
     assert_eq!(x.get(), 1000);
 }
+
+pub struct ConstAllocator;
+
+unsafe impl const Allocator for ConstAllocator {
+    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+        match layout.size() {
+            0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)),
+            _ => unsafe {
+                let ptr = core::intrinsics::const_allocate(layout.size(), layout.align());
+                Ok(NonNull::new_unchecked(ptr as *mut [u8; 0] as *mut [u8]))
+            },
+        }
+    }
+
+    unsafe fn deallocate(&self, _ptr: NonNull<u8>, layout: Layout) {
+        match layout.size() {
+            0 => { /* do nothing */ }
+            _ => { /* do nothing too */ }
+        }
+    }
+
+    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+        let ptr = self.allocate(layout)?;
+        if layout.size() > 0 {
+            unsafe {
+                ptr.as_mut_ptr().write_bytes(0, layout.size());
+            }
+        }
+        Ok(ptr)
+    }
+
+    unsafe fn grow(
+        &self,
+        ptr: NonNull<u8>,
+        old_layout: Layout,
+        new_layout: Layout,
+    ) -> Result<NonNull<[u8]>, AllocError> {
+        debug_assert!(
+            new_layout.size() >= old_layout.size(),
+            "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
+        );
+
+        let new_ptr = self.allocate(new_layout)?;
+        if new_layout.size() > 0 {
+            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
+            self.deallocate(ptr, old_layout);
+        }
+        Ok(new_ptr)
+    }
+
+    unsafe fn grow_zeroed(
+        &self,
+        ptr: NonNull<u8>,
+        old_layout: Layout,
+        new_layout: Layout,
+    ) -> Result<NonNull<[u8]>, AllocError> {
+        let new_ptr = self.grow(ptr, old_layout, new_layout)?;
+        if new_layout.size() > 0 {
+            let old_size = old_layout.size();
+            let new_size = new_layout.size();
+            let raw_ptr = new_ptr.as_mut_ptr();
+            raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+        }
+        Ok(new_ptr)
+    }
+
+    unsafe fn shrink(
+        &self,
+        ptr: NonNull<u8>,
+        old_layout: Layout,
+        new_layout: Layout,
+    ) -> Result<NonNull<[u8]>, AllocError> {
+        debug_assert!(
+            new_layout.size() <= old_layout.size(),
+            "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
+        );
+
+        let new_ptr = self.allocate(new_layout)?;
+        if new_layout.size() > 0 {
+            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
+            self.deallocate(ptr, old_layout);
+        }
+        Ok(new_ptr)
+    }
+
+    fn by_ref(&self) -> &Self
+    where
+        Self: Sized,
+    {
+        self
+    }
+}
+
+#[test]
+fn const_box() {
+    const VALUE: u32 = {
+        let mut boxed = Box::new_in(1u32, ConstAllocator);
+        assert!(*boxed == 1);
+
+        *boxed = 42;
+        assert!(*boxed == 42);
+
+        *boxed
+    };
+
+    assert!(VALUE == 42);
+}
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 68e48348b07..eec24a5c3f7 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -1,8 +1,19 @@
 #![feature(allocator_api)]
+#![feature(alloc_layout_extra)]
 #![feature(assert_matches)]
 #![feature(box_syntax)]
 #![feature(cow_is_borrowed)]
+#![feature(const_box)]
+#![feature(const_convert)]
 #![feature(const_cow_is_borrowed)]
+#![feature(const_heap)]
+#![feature(const_intrinsic_copy)]
+#![feature(const_mut_refs)]
+#![feature(const_nonnull_slice_from_raw_parts)]
+#![feature(const_ptr_offset)]
+#![feature(const_ptr_write)]
+#![feature(const_try)]
+#![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
 #![feature(new_uninit)]
@@ -26,6 +37,7 @@
 #![feature(const_default_impls)]
 #![feature(const_trait_impl)]
 #![feature(const_str_from_utf8)]
+#![feature(nonnull_slice_from_raw_parts)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 6fc3cd0b7c4..8a2a64f8dc9 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -570,11 +570,30 @@ impl Display for Arguments<'_> {
 /// There are a number of helper methods on the [`Formatter`] struct to help you with manual
 /// implementations, such as [`debug_struct`].
 ///
+/// [`debug_struct`]: Formatter::debug_struct
+///
+/// Types that do not wish to use the standard suite of debug representations
+/// provided by the `Formatter` trait (`debug_struct`, `debug_tuple`,
+/// `debut_list`, `debug_set`, `debug_map`) can do something totally custom by
+/// manually writing an arbitrary representation to the `Formatter`.
+///
+/// ```
+/// # use std::fmt;
+/// # struct Point {
+/// #     x: i32,
+/// #     y: i32,
+/// # }
+/// #
+/// impl fmt::Debug for Point {
+///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+///         write!(f, "Point [{} {}]", self.x, self.y)
+///     }
+/// }
+/// ```
+///
 /// `Debug` implementations using either `derive` or the debug builder API
 /// on [`Formatter`] support pretty-printing using the alternate flag: `{:#?}`.
 ///
-/// [`debug_struct`]: Formatter::debug_struct
-///
 /// Pretty-printing with `#?`:
 ///
 /// ```
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index d9389892c0c..d8f6c85e428 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -866,7 +866,6 @@ pub(crate) mod builtin {
                   language use and is subject to change"
     )]
     #[allow_internal_unstable(fmt_internals)]
-    #[doc(hidden)]
     #[rustc_builtin_macro]
     #[macro_export]
     macro_rules! format_args_nl {
@@ -1428,6 +1427,10 @@ pub(crate) mod builtin {
     }
 
     /// Attribute macro used to apply derive macros.
+    ///
+    /// See [the reference] for more info.
+    ///
+    /// [the reference]: ../../../reference/attributes/derive.html
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_builtin_macro]
     pub macro derive($item:item) {
@@ -1435,6 +1438,10 @@ pub(crate) mod builtin {
     }
 
     /// Attribute macro applied to a function to turn it into a unit test.
+    ///
+    /// See [the reference] for more info.
+    ///
+    /// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
@@ -1469,7 +1476,7 @@ pub(crate) mod builtin {
 
     /// Attribute macro applied to a static to register it as a global allocator.
     ///
-    /// See also [`std::alloc::GlobalAlloc`](../std/alloc/trait.GlobalAlloc.html).
+    /// See also [`std::alloc::GlobalAlloc`](../../../std/alloc/trait.GlobalAlloc.html).
     #[stable(feature = "global_allocator", since = "1.28.0")]
     #[allow_internal_unstable(rustc_attrs)]
     #[rustc_builtin_macro]
@@ -1507,6 +1514,7 @@ pub(crate) mod builtin {
         since = "1.52.0",
         reason = "rustc-serialize is deprecated and no longer supported"
     )]
+    #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
     pub macro RustcDecodable($item:item) {
         /* compiler built-in */
     }
@@ -1519,6 +1527,7 @@ pub(crate) mod builtin {
         since = "1.52.0",
         reason = "rustc-serialize is deprecated and no longer supported"
     )]
+    #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it.
     pub macro RustcEncodable($item:item) {
         /* compiler built-in */
     }
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
index 483362023b2..a920b9165c1 100644
--- a/library/core/src/ops/unsize.rs
+++ b/library/core/src/ops/unsize.rs
@@ -68,7 +68,38 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
 
-/// This is used for object safety, to check that a method's receiver type can be dispatched on.
+/// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
+/// arbitrary self types), to guarantee that a method's receiver type can be dispatched on.
+///
+/// Note: `DispatchFromDyn` was briefly named `CoerceSized` (and had a slightly different
+/// interpretation).
+///
+/// Imagine we have a trait object `t` with type `&dyn Tr`, where `Tr` is some trait with a method
+/// `m` defined as `fn m(&self);`. When calling `t.m()`, the receiver `t` is a wide pointer, but an
+/// implementation of `m` will expect a narrow pointer as `&self` (a reference to the concrete
+/// type). The compiler must generate an implicit conversion from the trait object/wide pointer to
+/// the concrete reference/narrow pointer. Implementing `DispatchFromDyn` indicates that that
+/// conversion is allowed and thus that the type implementing `DispatchFromDyn` is safe to use as
+/// the self type in an object-safe method. (in the above example, the compiler will require
+/// `DispatchFromDyn` is implemented for `&'a U`).
+///
+/// `DispatchFromDyn` does not specify the conversion from wide pointer to narrow pointer; the
+/// conversion is hard-wired into the compiler. For the conversion to work, the following
+/// properties must hold (i.e., it is only safe to implement `DispatchFromDyn` for types which have
+/// these properties, these are also checked by the compiler):
+///
+/// * EITHER `Self` and `T` are either both references or both raw pointers; in either case, with
+///   the same mutability.
+/// * OR, all of the following hold
+///   - `Self` and `T` must have the same type constructor, and only vary in a single type parameter
+///     formal (the *coerced type*, e.g., `impl DispatchFromDyn<Rc<T>> for Rc<U>` is ok and the
+///     single type parameter (instantiated with `T` or `U`) is the coerced type,
+///     `impl DispatchFromDyn<Arc<T>> for Rc<U>` is not ok).
+///   - The definition for `Self` must be a struct.
+///   - The definition for `Self` must not be `#[repr(packed)]` or `#[repr(C)]`.
+///   - Other than one-aligned, zero-sized fields, the definition for `Self` must have exactly one
+///     field and that field's type must be the coerced type. Furthermore, `Self`'s field type must
+///     implement `DispatchFromDyn<F>` where `F` is the type of `T`'s field type.
 ///
 /// An example implementation of the trait:
 ///
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index e6312b8b2d9..1ec119a71e4 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -571,36 +571,6 @@ impl<T> Option<T> {
         !self.is_some()
     }
 
-    /// Returns `true` if the option is a [`Some`] value containing the given value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(option_result_contains)]
-    ///
-    /// let x: Option<u32> = Some(2);
-    /// assert_eq!(x.contains(&2), true);
-    ///
-    /// let x: Option<u32> = Some(3);
-    /// assert_eq!(x.contains(&2), false);
-    ///
-    /// let x: Option<u32> = None;
-    /// assert_eq!(x.contains(&2), false);
-    /// ```
-    #[must_use]
-    #[inline]
-    #[unstable(feature = "option_result_contains", issue = "62358")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    pub const fn contains<U>(&self, x: &U) -> bool
-    where
-        U: ~const PartialEq<T>,
-    {
-        match self {
-            Some(y) => x.eq(y),
-            None => false,
-        }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Adapter for working with references
     /////////////////////////////////////////////////////////////////////////
@@ -810,6 +780,45 @@ impl<T> Option<T> {
         }
     }
 
+    /// Returns the contained [`Some`] value or a default.
+    ///
+    /// Consumes the `self` argument then, if [`Some`], returns the contained
+    /// value, otherwise if [`None`], returns the [default value] for that
+    /// type.
+    ///
+    /// # Examples
+    ///
+    /// Converts a string to an integer, turning poorly-formed strings
+    /// into 0 (the default value for integers). [`parse`] converts
+    /// a string to any other type that implements [`FromStr`], returning
+    /// [`None`] on error.
+    ///
+    /// ```
+    /// let good_year_from_input = "1909";
+    /// let bad_year_from_input = "190blarg";
+    /// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
+    /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
+    ///
+    /// assert_eq!(1909, good_year);
+    /// assert_eq!(0, bad_year);
+    /// ```
+    ///
+    /// [default value]: Default::default
+    /// [`parse`]: str::parse
+    /// [`FromStr`]: crate::str::FromStr
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    pub const fn unwrap_or_default(self) -> T
+    where
+        T: ~const Default,
+    {
+        match self {
+            Some(x) => x,
+            None => Default::default(),
+        }
+    }
+
     /// Returns the contained [`Some`] value, consuming the `self` value,
     /// without checking that the value is not [`None`].
     ///
@@ -1033,6 +1042,58 @@ impl<T> Option<T> {
         }
     }
 
+    /// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
+    ///
+    /// Leaves the original Option in-place, creating a new one with a reference
+    /// to the original one, additionally coercing the contents via [`Deref`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x: Option<String> = Some("hey".to_owned());
+    /// assert_eq!(x.as_deref(), Some("hey"));
+    ///
+    /// let x: Option<String> = None;
+    /// assert_eq!(x.as_deref(), None);
+    /// ```
+    #[stable(feature = "option_deref", since = "1.40.0")]
+    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    pub const fn as_deref(&self) -> Option<&T::Target>
+    where
+        T: ~const Deref,
+    {
+        match self.as_ref() {
+            Some(t) => Some(t.deref()),
+            None => None,
+        }
+    }
+
+    /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
+    ///
+    /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
+    /// the inner type's [`Deref::Target`] type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut x: Option<String> = Some("hey".to_owned());
+    /// assert_eq!(x.as_deref_mut().map(|x| {
+    ///     x.make_ascii_uppercase();
+    ///     x
+    /// }), Some("HEY".to_owned().as_mut_str()));
+    /// ```
+    #[stable(feature = "option_deref", since = "1.40.0")]
+    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
+    where
+        T: ~const DerefMut,
+    {
+        match self.as_mut() {
+            Some(t) => Some(t.deref_mut()),
+            None => None,
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Iterator constructors
     /////////////////////////////////////////////////////////////////////////
@@ -1482,6 +1543,36 @@ impl<T> Option<T> {
         mem::replace(self, Some(value))
     }
 
+    /// Returns `true` if the option is a [`Some`] value containing the given value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_result_contains)]
+    ///
+    /// let x: Option<u32> = Some(2);
+    /// assert_eq!(x.contains(&2), true);
+    ///
+    /// let x: Option<u32> = Some(3);
+    /// assert_eq!(x.contains(&2), false);
+    ///
+    /// let x: Option<u32> = None;
+    /// assert_eq!(x.contains(&2), false);
+    /// ```
+    #[must_use]
+    #[inline]
+    #[unstable(feature = "option_result_contains", issue = "62358")]
+    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    pub const fn contains<U>(&self, x: &U) -> bool
+    where
+        U: ~const PartialEq<T>,
+    {
+        match self {
+            Some(y) => x.eq(y),
+            None => false,
+        }
+    }
+
     /// Zips `self` with another `Option`.
     ///
     /// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some((s, o))`.
@@ -1581,7 +1672,7 @@ impl<T, U> Option<(T, U)> {
     }
 }
 
-impl<T: Copy> Option<&T> {
+impl<T> Option<&T> {
     /// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
     /// option.
     ///
@@ -1597,7 +1688,10 @@ impl<T: Copy> Option<&T> {
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "copied", since = "1.35.0")]
     #[rustc_const_unstable(feature = "const_option", issue = "67441")]
-    pub const fn copied(self) -> Option<T> {
+    pub const fn copied(self) -> Option<T>
+    where
+        T: Copy,
+    {
         // FIXME: this implementation, which sidesteps using `Option::map` since it's not const
         // ready yet, should be reverted when possible to avoid code repetition
         match self {
@@ -1605,33 +1699,7 @@ impl<T: Copy> Option<&T> {
             None => None,
         }
     }
-}
-
-impl<T: Copy> Option<&mut T> {
-    /// Maps an `Option<&mut T>` to an `Option<T>` by copying the contents of the
-    /// option.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let mut x = 12;
-    /// let opt_x = Some(&mut x);
-    /// assert_eq!(opt_x, Some(&mut 12));
-    /// let copied = opt_x.copied();
-    /// assert_eq!(copied, Some(12));
-    /// ```
-    #[must_use = "`self` will be dropped if the result is not used"]
-    #[stable(feature = "copied", since = "1.35.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    pub const fn copied(self) -> Option<T> {
-        match self {
-            Some(&mut t) => Some(t),
-            None => None,
-        }
-    }
-}
 
-impl<T: Clone> Option<&T> {
     /// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the
     /// option.
     ///
@@ -1658,8 +1726,8 @@ impl<T: Clone> Option<&T> {
     }
 }
 
-impl<T: Clone> Option<&mut T> {
-    /// Maps an `Option<&mut T>` to an `Option<T>` by cloning the contents of the
+impl<T> Option<&mut T> {
+    /// Maps an `Option<&mut T>` to an `Option<T>` by copying the contents of the
     /// option.
     ///
     /// # Examples
@@ -1668,115 +1736,43 @@ impl<T: Clone> Option<&mut T> {
     /// let mut x = 12;
     /// let opt_x = Some(&mut x);
     /// assert_eq!(opt_x, Some(&mut 12));
-    /// let cloned = opt_x.cloned();
-    /// assert_eq!(cloned, Some(12));
+    /// let copied = opt_x.copied();
+    /// assert_eq!(copied, Some(12));
     /// ```
     #[must_use = "`self` will be dropped if the result is not used"]
-    #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
-    #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")]
-    pub const fn cloned(self) -> Option<T>
-    where
-        T: ~const Clone,
-    {
-        match self {
-            Some(t) => Some(t.clone()),
-            None => None,
-        }
-    }
-}
-
-impl<T: Default> Option<T> {
-    /// Returns the contained [`Some`] value or a default.
-    ///
-    /// Consumes the `self` argument then, if [`Some`], returns the contained
-    /// value, otherwise if [`None`], returns the [default value] for that
-    /// type.
-    ///
-    /// # Examples
-    ///
-    /// Converts a string to an integer, turning poorly-formed strings
-    /// into 0 (the default value for integers). [`parse`] converts
-    /// a string to any other type that implements [`FromStr`], returning
-    /// [`None`] on error.
-    ///
-    /// ```
-    /// let good_year_from_input = "1909";
-    /// let bad_year_from_input = "190blarg";
-    /// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
-    /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
-    ///
-    /// assert_eq!(1909, good_year);
-    /// assert_eq!(0, bad_year);
-    /// ```
-    ///
-    /// [default value]: Default::default
-    /// [`parse`]: str::parse
-    /// [`FromStr`]: crate::str::FromStr
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
+    #[stable(feature = "copied", since = "1.35.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    pub const fn unwrap_or_default(self) -> T
+    pub const fn copied(self) -> Option<T>
     where
-        T: ~const Default,
+        T: Copy,
     {
         match self {
-            Some(x) => x,
-            None => Default::default(),
-        }
-    }
-}
-
-impl<T: Deref> Option<T> {
-    /// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
-    ///
-    /// Leaves the original Option in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the contents via [`Deref`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let x: Option<String> = Some("hey".to_owned());
-    /// assert_eq!(x.as_deref(), Some("hey"));
-    ///
-    /// let x: Option<String> = None;
-    /// assert_eq!(x.as_deref(), None);
-    /// ```
-    #[stable(feature = "option_deref", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    pub const fn as_deref(&self) -> Option<&T::Target>
-    where
-        T: ~const Deref,
-    {
-        match self.as_ref() {
-            Some(t) => Some(t.deref()),
+            Some(&mut t) => Some(t),
             None => None,
         }
     }
-}
 
-impl<T: DerefMut> Option<T> {
-    /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
-    ///
-    /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
-    /// the inner type's [`Deref::Target`] type.
+    /// Maps an `Option<&mut T>` to an `Option<T>` by cloning the contents of the
+    /// option.
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut x: Option<String> = Some("hey".to_owned());
-    /// assert_eq!(x.as_deref_mut().map(|x| {
-    ///     x.make_ascii_uppercase();
-    ///     x
-    /// }), Some("HEY".to_owned().as_mut_str()));
+    /// let mut x = 12;
+    /// let opt_x = Some(&mut x);
+    /// assert_eq!(opt_x, Some(&mut 12));
+    /// let cloned = opt_x.cloned();
+    /// assert_eq!(cloned, Some(12));
     /// ```
-    #[stable(feature = "option_deref", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
+    #[must_use = "`self` will be dropped if the result is not used"]
+    #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
+    #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")]
+    pub const fn cloned(self) -> Option<T>
     where
-        T: ~const DerefMut,
+        T: ~const Clone,
     {
-        match self.as_mut() {
-            Some(t) => Some(t.deref_mut()),
+        match self {
+            Some(t) => Some(t.clone()),
             None => None,
         }
     }
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index 54f498d1dc1..0fb8846288b 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -69,23 +69,21 @@ pub use crate::{
 #[doc(no_inline)]
 pub use crate::concat_bytes;
 
+// Do not `doc(inline)` these `doc(hidden)` items.
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-#[allow(deprecated, deprecated_in_future)]
-#[doc(no_inline)]
-pub use crate::macros::builtin::{
-    bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
-};
+#[allow(deprecated)]
+pub use crate::macros::builtin::{RustcDecodable, RustcEncodable};
 
+// Do not `doc(no_inline)` so that they become doc items on their own
+// (no public module for them to be re-exported from).
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-#[doc(no_inline)]
-pub use crate::macros::builtin::derive;
+pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
 
 #[unstable(
     feature = "cfg_accessible",
     issue = "64797",
     reason = "`cfg_accessible` is not fully implemented"
 )]
-#[doc(no_inline)]
 pub use crate::macros::builtin::cfg_accessible;
 
 #[unstable(
@@ -93,5 +91,4 @@ pub use crate::macros::builtin::cfg_accessible;
     issue = "82679",
     reason = "`cfg_eval` is a recently implemented feature"
 )]
-#[doc(no_inline)]
 pub use crate::macros::builtin::cfg_eval;
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 3cde63493d3..504a01813ac 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -563,64 +563,6 @@ impl<T, E> Result<T, E> {
         !self.is_ok()
     }
 
-    /// Returns `true` if the result is an [`Ok`] value containing the given value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(option_result_contains)]
-    ///
-    /// let x: Result<u32, &str> = Ok(2);
-    /// assert_eq!(x.contains(&2), true);
-    ///
-    /// let x: Result<u32, &str> = Ok(3);
-    /// assert_eq!(x.contains(&2), false);
-    ///
-    /// let x: Result<u32, &str> = Err("Some error message");
-    /// assert_eq!(x.contains(&2), false);
-    /// ```
-    #[must_use]
-    #[inline]
-    #[unstable(feature = "option_result_contains", issue = "62358")]
-    pub fn contains<U>(&self, x: &U) -> bool
-    where
-        U: PartialEq<T>,
-    {
-        match self {
-            Ok(y) => x == y,
-            Err(_) => false,
-        }
-    }
-
-    /// Returns `true` if the result is an [`Err`] value containing the given value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_contains_err)]
-    ///
-    /// let x: Result<u32, &str> = Ok(2);
-    /// assert_eq!(x.contains_err(&"Some error message"), false);
-    ///
-    /// let x: Result<u32, &str> = Err("Some error message");
-    /// assert_eq!(x.contains_err(&"Some error message"), true);
-    ///
-    /// let x: Result<u32, &str> = Err("Some other error message");
-    /// assert_eq!(x.contains_err(&"Some error message"), false);
-    /// ```
-    #[must_use]
-    #[inline]
-    #[unstable(feature = "result_contains_err", issue = "62358")]
-    pub fn contains_err<F>(&self, f: &F) -> bool
-    where
-        F: PartialEq<E>,
-    {
-        match self {
-            Ok(_) => false,
-            Err(e) => f == e,
-        }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Adapter for each variant
     /////////////////////////////////////////////////////////////////////////
@@ -901,6 +843,56 @@ impl<T, E> Result<T, E> {
         self
     }
 
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`.
+    ///
+    /// Coerces the [`Ok`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref)
+    /// and returns the new [`Result`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x: Result<String, u32> = Ok("hello".to_string());
+    /// let y: Result<&str, &u32> = Ok("hello");
+    /// assert_eq!(x.as_deref(), y);
+    ///
+    /// let x: Result<String, u32> = Err(42);
+    /// let y: Result<&str, &u32> = Err(&42);
+    /// assert_eq!(x.as_deref(), y);
+    /// ```
+    #[stable(feature = "inner_deref", since = "1.47.0")]
+    pub fn as_deref(&self) -> Result<&T::Target, &E>
+    where
+        T: Deref,
+    {
+        self.as_ref().map(|t| t.deref())
+    }
+
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`.
+    ///
+    /// Coerces the [`Ok`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut)
+    /// and returns the new [`Result`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut s = "HELLO".to_string();
+    /// let mut x: Result<String, u32> = Ok("hello".to_string());
+    /// let y: Result<&mut str, &mut u32> = Ok(&mut s);
+    /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
+    ///
+    /// let mut i = 42;
+    /// let mut x: Result<String, u32> = Err(42);
+    /// let y: Result<&mut str, &mut u32> = Err(&mut i);
+    /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
+    /// ```
+    #[stable(feature = "inner_deref", since = "1.47.0")]
+    pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E>
+    where
+        T: DerefMut,
+    {
+        self.as_mut().map(|t| t.deref_mut())
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Iterator constructors
     /////////////////////////////////////////////////////////////////////////
@@ -951,6 +943,253 @@ impl<T, E> Result<T, E> {
         IterMut { inner: self.as_mut().ok() }
     }
 
+    /////////////////////////////////////////////////////////////////////////
+    // Extract a value
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Returns the contained [`Ok`] value, consuming the `self` value.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is an [`Err`], with a panic message including the
+    /// passed message, and the content of the [`Err`].
+    ///
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Err("emergency failure");
+    /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
+    /// ```
+    #[inline]
+    #[track_caller]
+    #[stable(feature = "result_expect", since = "1.4.0")]
+    pub fn expect(self, msg: &str) -> T
+    where
+        E: fmt::Debug,
+    {
+        match self {
+            Ok(t) => t,
+            Err(e) => unwrap_failed(msg, &e),
+        }
+    }
+
+    /// Returns the contained [`Ok`] value, consuming the `self` value.
+    ///
+    /// Because this function may panic, its use is generally discouraged.
+    /// Instead, prefer to use pattern matching and handle the [`Err`]
+    /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
+    /// [`unwrap_or_default`].
+    ///
+    /// [`unwrap_or`]: Result::unwrap_or
+    /// [`unwrap_or_else`]: Result::unwrap_or_else
+    /// [`unwrap_or_default`]: Result::unwrap_or_default
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is an [`Err`], with a panic message provided by the
+    /// [`Err`]'s value.
+    ///
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// let x: Result<u32, &str> = Ok(2);
+    /// assert_eq!(x.unwrap(), 2);
+    /// ```
+    ///
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Err("emergency failure");
+    /// x.unwrap(); // panics with `emergency failure`
+    /// ```
+    #[inline]
+    #[track_caller]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn unwrap(self) -> T
+    where
+        E: fmt::Debug,
+    {
+        match self {
+            Ok(t) => t,
+            Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e),
+        }
+    }
+
+    /// Returns the contained [`Ok`] value or a default
+    ///
+    /// Consumes the `self` argument then, if [`Ok`], returns the contained
+    /// value, otherwise if [`Err`], returns the default value for that
+    /// type.
+    ///
+    /// # Examples
+    ///
+    /// Converts a string to an integer, turning poorly-formed strings
+    /// into 0 (the default value for integers). [`parse`] converts
+    /// a string to any other type that implements [`FromStr`], returning an
+    /// [`Err`] on error.
+    ///
+    /// ```
+    /// let good_year_from_input = "1909";
+    /// let bad_year_from_input = "190blarg";
+    /// let good_year = good_year_from_input.parse().unwrap_or_default();
+    /// let bad_year = bad_year_from_input.parse().unwrap_or_default();
+    ///
+    /// assert_eq!(1909, good_year);
+    /// assert_eq!(0, bad_year);
+    /// ```
+    ///
+    /// [`parse`]: str::parse
+    /// [`FromStr`]: crate::str::FromStr
+    #[inline]
+    #[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
+    pub fn unwrap_or_default(self) -> T
+    where
+        T: Default,
+    {
+        match self {
+            Ok(x) => x,
+            Err(_) => Default::default(),
+        }
+    }
+
+    /// Returns the contained [`Err`] value, consuming the `self` value.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is an [`Ok`], with a panic message including the
+    /// passed message, and the content of the [`Ok`].
+    ///
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Ok(10);
+    /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10`
+    /// ```
+    #[inline]
+    #[track_caller]
+    #[stable(feature = "result_expect_err", since = "1.17.0")]
+    pub fn expect_err(self, msg: &str) -> E
+    where
+        T: fmt::Debug,
+    {
+        match self {
+            Ok(t) => unwrap_failed(msg, &t),
+            Err(e) => e,
+        }
+    }
+
+    /// Returns the contained [`Err`] value, consuming the `self` value.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the value is an [`Ok`], with a custom panic message provided
+    /// by the [`Ok`]'s value.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Ok(2);
+    /// x.unwrap_err(); // panics with `2`
+    /// ```
+    ///
+    /// ```
+    /// let x: Result<u32, &str> = Err("emergency failure");
+    /// assert_eq!(x.unwrap_err(), "emergency failure");
+    /// ```
+    #[inline]
+    #[track_caller]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn unwrap_err(self) -> E
+    where
+        T: fmt::Debug,
+    {
+        match self {
+            Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t),
+            Err(e) => e,
+        }
+    }
+
+    /// Returns the contained [`Ok`] value, but never panics.
+    ///
+    /// Unlike [`unwrap`], this method is known to never panic on the
+    /// result types it is implemented for. Therefore, it can be used
+    /// instead of `unwrap` as a maintainability safeguard that will fail
+    /// to compile if the error type of the `Result` is later changed
+    /// to an error that can actually occur.
+    ///
+    /// [`unwrap`]: Result::unwrap
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// # #![feature(never_type)]
+    /// # #![feature(unwrap_infallible)]
+    ///
+    /// fn only_good_news() -> Result<String, !> {
+    ///     Ok("this is fine".into())
+    /// }
+    ///
+    /// let s: String = only_good_news().into_ok();
+    /// println!("{}", s);
+    /// ```
+    #[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
+    #[inline]
+    pub fn into_ok(self) -> T
+    where
+        E: Into<!>,
+    {
+        match self {
+            Ok(x) => x,
+            Err(e) => e.into(),
+        }
+    }
+
+    /// Returns the contained [`Err`] value, but never panics.
+    ///
+    /// Unlike [`unwrap_err`], this method is known to never panic on the
+    /// result types it is implemented for. Therefore, it can be used
+    /// instead of `unwrap_err` as a maintainability safeguard that will fail
+    /// to compile if the ok type of the `Result` is later changed
+    /// to a type that can actually occur.
+    ///
+    /// [`unwrap_err`]: Result::unwrap_err
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// # #![feature(never_type)]
+    /// # #![feature(unwrap_infallible)]
+    ///
+    /// fn only_bad_news() -> Result<!, String> {
+    ///     Err("Oops, it failed".into())
+    /// }
+    ///
+    /// let error: String = only_bad_news().into_err();
+    /// println!("{}", error);
+    /// ```
+    #[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
+    #[inline]
+    pub fn into_err(self) -> E
+    where
+        T: Into<!>,
+    {
+        match self {
+            Ok(x) => x.into(),
+            Err(e) => e,
+        }
+    }
+
     ////////////////////////////////////////////////////////////////////////
     // Boolean operations on the values, eager and lazy
     /////////////////////////////////////////////////////////////////////////
@@ -1194,365 +1433,155 @@ impl<T, E> Result<T, E> {
             Err(e) => e,
         }
     }
-}
 
-impl<T: Copy, E> Result<&T, E> {
-    /// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
-    /// `Ok` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// let val = 12;
-    /// let x: Result<&i32, i32> = Ok(&val);
-    /// assert_eq!(x, Ok(&12));
-    /// let copied = x.copied();
-    /// assert_eq!(copied, Ok(12));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.map(|&t| t)
-    }
-}
-
-impl<T: Copy, E> Result<&mut T, E> {
-    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
-    /// `Ok` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// let mut val = 12;
-    /// let x: Result<&mut i32, i32> = Ok(&mut val);
-    /// assert_eq!(x, Ok(&mut 12));
-    /// let copied = x.copied();
-    /// assert_eq!(copied, Ok(12));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.map(|&mut t| t)
-    }
-}
-
-impl<T: Clone, E> Result<&T, E> {
-    /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
-    /// `Ok` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// let val = 12;
-    /// let x: Result<&i32, i32> = Ok(&val);
-    /// assert_eq!(x, Ok(&12));
-    /// let cloned = x.cloned();
-    /// assert_eq!(cloned, Ok(12));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.map(|t| t.clone())
-    }
-}
-
-impl<T: Clone, E> Result<&mut T, E> {
-    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
-    /// `Ok` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// let mut val = 12;
-    /// let x: Result<&mut i32, i32> = Ok(&mut val);
-    /// assert_eq!(x, Ok(&mut 12));
-    /// let cloned = x.cloned();
-    /// assert_eq!(cloned, Ok(12));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.map(|t| t.clone())
-    }
-}
+    /////////////////////////////////////////////////////////////////////////
+    // Misc or niche
+    /////////////////////////////////////////////////////////////////////////
 
-impl<T, E: fmt::Debug> Result<T, E> {
-    /// Returns the contained [`Ok`] value, consuming the `self` value.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the value is an [`Err`], with a panic message including the
-    /// passed message, and the content of the [`Err`].
-    ///
+    /// Returns `true` if the result is an [`Ok`] value containing the given value.
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
-    /// ```should_panic
-    /// let x: Result<u32, &str> = Err("emergency failure");
-    /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
     /// ```
-    #[inline]
-    #[track_caller]
-    #[stable(feature = "result_expect", since = "1.4.0")]
-    pub fn expect(self, msg: &str) -> T {
-        match self {
-            Ok(t) => t,
-            Err(e) => unwrap_failed(msg, &e),
-        }
-    }
-
-    /// Returns the contained [`Ok`] value, consuming the `self` value.
-    ///
-    /// Because this function may panic, its use is generally discouraged.
-    /// Instead, prefer to use pattern matching and handle the [`Err`]
-    /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or
-    /// [`unwrap_or_default`].
-    ///
-    /// [`unwrap_or`]: Result::unwrap_or
-    /// [`unwrap_or_else`]: Result::unwrap_or_else
-    /// [`unwrap_or_default`]: Result::unwrap_or_default
-    ///
-    /// # Panics
-    ///
-    /// Panics if the value is an [`Err`], with a panic message provided by the
-    /// [`Err`]'s value.
-    ///
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
+    /// #![feature(option_result_contains)]
     ///
-    /// ```
     /// let x: Result<u32, &str> = Ok(2);
-    /// assert_eq!(x.unwrap(), 2);
-    /// ```
-    ///
-    /// ```should_panic
-    /// let x: Result<u32, &str> = Err("emergency failure");
-    /// x.unwrap(); // panics with `emergency failure`
-    /// ```
-    #[inline]
-    #[track_caller]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap(self) -> T {
-        match self {
-            Ok(t) => t,
-            Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e),
-        }
-    }
-}
-
-impl<T: fmt::Debug, E> Result<T, E> {
-    /// Returns the contained [`Err`] value, consuming the `self` value.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the value is an [`Ok`], with a panic message including the
-    /// passed message, and the content of the [`Ok`].
-    ///
-    ///
-    /// # Examples
+    /// assert_eq!(x.contains(&2), true);
     ///
-    /// Basic usage:
+    /// let x: Result<u32, &str> = Ok(3);
+    /// assert_eq!(x.contains(&2), false);
     ///
-    /// ```should_panic
-    /// let x: Result<u32, &str> = Ok(10);
-    /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10`
+    /// let x: Result<u32, &str> = Err("Some error message");
+    /// assert_eq!(x.contains(&2), false);
     /// ```
+    #[must_use]
     #[inline]
-    #[track_caller]
-    #[stable(feature = "result_expect_err", since = "1.17.0")]
-    pub fn expect_err(self, msg: &str) -> E {
+    #[unstable(feature = "option_result_contains", issue = "62358")]
+    pub fn contains<U>(&self, x: &U) -> bool
+    where
+        U: PartialEq<T>,
+    {
         match self {
-            Ok(t) => unwrap_failed(msg, &t),
-            Err(e) => e,
+            Ok(y) => x == y,
+            Err(_) => false,
         }
     }
 
-    /// Returns the contained [`Err`] value, consuming the `self` value.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the value is an [`Ok`], with a custom panic message provided
-    /// by the [`Ok`]'s value.
+    /// Returns `true` if the result is an [`Err`] value containing the given value.
     ///
     /// # Examples
     ///
-    /// ```should_panic
-    /// let x: Result<u32, &str> = Ok(2);
-    /// x.unwrap_err(); // panics with `2`
     /// ```
+    /// #![feature(result_contains_err)]
     ///
-    /// ```
-    /// let x: Result<u32, &str> = Err("emergency failure");
-    /// assert_eq!(x.unwrap_err(), "emergency failure");
-    /// ```
-    #[inline]
-    #[track_caller]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_err(self) -> E {
-        match self {
-            Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t),
-            Err(e) => e,
-        }
-    }
-}
-
-impl<T: Default, E> Result<T, E> {
-    /// Returns the contained [`Ok`] value or a default
-    ///
-    /// Consumes the `self` argument then, if [`Ok`], returns the contained
-    /// value, otherwise if [`Err`], returns the default value for that
-    /// type.
-    ///
-    /// # Examples
-    ///
-    /// Converts a string to an integer, turning poorly-formed strings
-    /// into 0 (the default value for integers). [`parse`] converts
-    /// a string to any other type that implements [`FromStr`], returning an
-    /// [`Err`] on error.
+    /// let x: Result<u32, &str> = Ok(2);
+    /// assert_eq!(x.contains_err(&"Some error message"), false);
     ///
-    /// ```
-    /// let good_year_from_input = "1909";
-    /// let bad_year_from_input = "190blarg";
-    /// let good_year = good_year_from_input.parse().unwrap_or_default();
-    /// let bad_year = bad_year_from_input.parse().unwrap_or_default();
+    /// let x: Result<u32, &str> = Err("Some error message");
+    /// assert_eq!(x.contains_err(&"Some error message"), true);
     ///
-    /// assert_eq!(1909, good_year);
-    /// assert_eq!(0, bad_year);
+    /// let x: Result<u32, &str> = Err("Some other error message");
+    /// assert_eq!(x.contains_err(&"Some error message"), false);
     /// ```
-    ///
-    /// [`parse`]: str::parse
-    /// [`FromStr`]: crate::str::FromStr
+    #[must_use]
     #[inline]
-    #[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
-    pub fn unwrap_or_default(self) -> T {
+    #[unstable(feature = "result_contains_err", issue = "62358")]
+    pub fn contains_err<F>(&self, f: &F) -> bool
+    where
+        F: PartialEq<E>,
+    {
         match self {
-            Ok(x) => x,
-            Err(_) => Default::default(),
+            Ok(_) => false,
+            Err(e) => f == e,
         }
     }
 }
 
-#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
-impl<T, E: Into<!>> Result<T, E> {
-    /// Returns the contained [`Ok`] value, but never panics.
-    ///
-    /// Unlike [`unwrap`], this method is known to never panic on the
-    /// result types it is implemented for. Therefore, it can be used
-    /// instead of `unwrap` as a maintainability safeguard that will fail
-    /// to compile if the error type of the `Result` is later changed
-    /// to an error that can actually occur.
-    ///
-    /// [`unwrap`]: Result::unwrap
+impl<T, E> Result<&T, E> {
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```
-    /// # #![feature(never_type)]
-    /// # #![feature(unwrap_infallible)]
-    ///
-    /// fn only_good_news() -> Result<String, !> {
-    ///     Ok("this is fine".into())
-    /// }
-    ///
-    /// let s: String = only_good_news().into_ok();
-    /// println!("{}", s);
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x: Result<&i32, i32> = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
     /// ```
-    #[inline]
-    pub fn into_ok(self) -> T {
-        match self {
-            Ok(x) => x,
-            Err(e) => e.into(),
-        }
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E>
+    where
+        T: Copy,
+    {
+        self.map(|&t| t)
     }
-}
 
-#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
-impl<T: Into<!>, E> Result<T, E> {
-    /// Returns the contained [`Err`] value, but never panics.
-    ///
-    /// Unlike [`unwrap_err`], this method is known to never panic on the
-    /// result types it is implemented for. Therefore, it can be used
-    /// instead of `unwrap_err` as a maintainability safeguard that will fail
-    /// to compile if the ok type of the `Result` is later changed
-    /// to a type that can actually occur.
-    ///
-    /// [`unwrap_err`]: Result::unwrap_err
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
     ///
     /// # Examples
     ///
-    /// Basic usage:
-    ///
     /// ```
-    /// # #![feature(never_type)]
-    /// # #![feature(unwrap_infallible)]
-    ///
-    /// fn only_bad_news() -> Result<!, String> {
-    ///     Err("Oops, it failed".into())
-    /// }
-    ///
-    /// let error: String = only_bad_news().into_err();
-    /// println!("{}", error);
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x: Result<&i32, i32> = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
     /// ```
-    #[inline]
-    pub fn into_err(self) -> E {
-        match self {
-            Ok(x) => x.into(),
-            Err(e) => e,
-        }
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E>
+    where
+        T: Clone,
+    {
+        self.map(|t| t.clone())
     }
 }
 
-impl<T: Deref, E> Result<T, E> {
-    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`.
-    ///
-    /// Coerces the [`Ok`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref)
-    /// and returns the new [`Result`].
+impl<T, E> Result<&mut T, E> {
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
     ///
     /// # Examples
     ///
     /// ```
-    /// let x: Result<String, u32> = Ok("hello".to_string());
-    /// let y: Result<&str, &u32> = Ok("hello");
-    /// assert_eq!(x.as_deref(), y);
-    ///
-    /// let x: Result<String, u32> = Err(42);
-    /// let y: Result<&str, &u32> = Err(&42);
-    /// assert_eq!(x.as_deref(), y);
+    /// #![feature(result_copied)]
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
     /// ```
-    #[stable(feature = "inner_deref", since = "1.47.0")]
-    pub fn as_deref(&self) -> Result<&T::Target, &E> {
-        self.as_ref().map(|t| t.deref())
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E>
+    where
+        T: Copy,
+    {
+        self.map(|&mut t| t)
     }
-}
 
-impl<T: DerefMut, E> Result<T, E> {
-    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`.
-    ///
-    /// Coerces the [`Ok`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut)
-    /// and returns the new [`Result`].
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
     ///
     /// # Examples
     ///
     /// ```
-    /// let mut s = "HELLO".to_string();
-    /// let mut x: Result<String, u32> = Ok("hello".to_string());
-    /// let y: Result<&mut str, &mut u32> = Ok(&mut s);
-    /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
-    ///
-    /// let mut i = 42;
-    /// let mut x: Result<String, u32> = Err(42);
-    /// let y: Result<&mut str, &mut u32> = Err(&mut i);
-    /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
+    /// #![feature(result_cloned)]
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
     /// ```
-    #[stable(feature = "inner_deref", since = "1.47.0")]
-    pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> {
-        self.as_mut().map(|t| t.deref_mut())
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E>
+    where
+        T: Clone,
+    {
+        self.map(|t| t.clone())
     }
 }
 
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 743dd51333d..b52bcdfca9e 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -54,33 +54,30 @@ pub use core::prelude::v1::{
 #[doc(no_inline)]
 pub use core::prelude::v1::concat_bytes;
 
-// FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates
-// dead links which fail link checker testing.
+// Do not `doc(inline)` these `doc(hidden)` items.
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-#[allow(deprecated, deprecated_in_future)]
-#[doc(hidden)]
-pub use core::prelude::v1::{
-    bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
-};
+#[allow(deprecated)]
+pub use core::prelude::v1::{RustcDecodable, RustcEncodable};
 
+// Do not `doc(no_inline)` so that they become doc items on their own
+// (no public module for them to be re-exported from).
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
-#[doc(hidden)]
-pub use core::prelude::v1::derive;
+pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
 
+// Do not `doc(no_inline)` either.
 #[unstable(
     feature = "cfg_accessible",
     issue = "64797",
     reason = "`cfg_accessible` is not fully implemented"
 )]
-#[doc(hidden)]
 pub use core::prelude::v1::cfg_accessible;
 
+// Do not `doc(no_inline)` either.
 #[unstable(
     feature = "cfg_eval",
     issue = "82679",
     reason = "`cfg_eval` is a recently implemented feature"
 )]
-#[doc(hidden)]
 pub use core::prelude::v1::cfg_eval;
 
 // The file so far is equivalent to src/libcore/prelude/v1.rs,
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index 2cf678ef69b..2e54321e127 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -429,12 +429,13 @@ pub struct TryIter<'a, T: 'a> {
 }
 
 /// An owning iterator over messages on a [`Receiver`],
-/// created by **Receiver::into_iter**.
+/// created by [`into_iter`].
 ///
 /// This iterator will block whenever [`next`]
 /// is called, waiting for a new message, and [`None`] will be
 /// returned if the corresponding channel has hung up.
 ///
+/// [`into_iter`]: Receiver::into_iter
 /// [`next`]: Iterator::next
 ///
 /// # Examples
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index eb0925b3fda..684b8e3155e 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -15,7 +15,9 @@ use core::str::utf8_char_width;
 // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490.
 pub struct Stdin {
     surrogate: u16,
+    incomplete_utf8: IncompleteUtf8,
 }
+
 pub struct Stdout {
     incomplete_utf8: IncompleteUtf8,
 }
@@ -29,6 +31,25 @@ struct IncompleteUtf8 {
     len: u8,
 }
 
+impl IncompleteUtf8 {
+    // Implemented for use in Stdin::read.
+    fn read(&mut self, buf: &mut [u8]) -> usize {
+        // Write to buffer until the buffer is full or we run out of bytes.
+        let to_write = cmp::min(buf.len(), self.len as usize);
+        buf[..to_write].copy_from_slice(&self.bytes[..to_write]);
+
+        // Rotate the remaining bytes if not enough remaining space in buffer.
+        if usize::from(self.len) > buf.len() {
+            self.bytes.copy_within(to_write.., 0);
+            self.len -= to_write as u8;
+        } else {
+            self.len = 0;
+        }
+
+        to_write
+    }
+}
+
 // Apparently Windows doesn't handle large reads on stdin or writes to stdout/stderr well (see
 // #13304 for details).
 //
@@ -205,7 +226,7 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> {
 
 impl Stdin {
     pub const fn new() -> Stdin {
-        Stdin { surrogate: 0 }
+        Stdin { surrogate: 0, incomplete_utf8: IncompleteUtf8::new() }
     }
 }
 
@@ -221,24 +242,39 @@ impl io::Read for Stdin {
             }
         }
 
-        if buf.len() == 0 {
-            return Ok(0);
-        } else if buf.len() < 4 {
-            return Err(io::Error::new_const(
-                io::ErrorKind::InvalidInput,
-                &"Windows stdin in console mode does not support a buffer too small to \
-                 guarantee holding one arbitrary UTF-8 character (4 bytes)",
-            ));
+        // If there are bytes in the incomplete utf-8, start with those.
+        // (No-op if there is nothing in the buffer.)
+        let mut bytes_copied = self.incomplete_utf8.read(buf);
+
+        if bytes_copied == buf.len() {
+            return Ok(bytes_copied);
+        } else if buf.len() - bytes_copied < 4 {
+            // Not enough space to get a UTF-8 byte. We will use the incomplete UTF8.
+            let mut utf16_buf = [0u16; 1];
+            // Read one u16 character.
+            let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, 1, &mut self.surrogate)?;
+            // Read bytes, using the (now-empty) self.incomplete_utf8 as extra space.
+            let read_bytes = utf16_to_utf8(&utf16_buf[..read], &mut self.incomplete_utf8.bytes)?;
+
+            // Read in the bytes from incomplete_utf8 until the buffer is full.
+            self.incomplete_utf8.len = read_bytes as u8;
+            // No-op if no bytes.
+            bytes_copied += self.incomplete_utf8.read(&mut buf[bytes_copied..]);
+            Ok(bytes_copied)
+        } else {
+            let mut utf16_buf = [0u16; MAX_BUFFER_SIZE / 2];
+            // In the worst case, a UTF-8 string can take 3 bytes for every `u16` of a UTF-16. So
+            // we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets
+            // lost.
+            let amount = cmp::min(buf.len() / 3, utf16_buf.len());
+            let read =
+                read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
+
+            match utf16_to_utf8(&utf16_buf[..read], buf) {
+                Ok(value) => return Ok(bytes_copied + value),
+                Err(e) => return Err(e),
+            }
         }
-
-        let mut utf16_buf = [0u16; MAX_BUFFER_SIZE / 2];
-        // In the worst case, a UTF-8 string can take 3 bytes for every `u16` of a UTF-16. So
-        // we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets
-        // lost.
-        let amount = cmp::min(buf.len() / 3, utf16_buf.len());
-        let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
-
-        utf16_to_utf8(&utf16_buf[..read], buf)
     }
 }
 
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 2516f3452b1..608e587cf34 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -13,20 +13,12 @@
 // running tests while providing a base that other test frameworks may
 // build off of.
 
-// N.B., this is also specified in this crate's Cargo.toml, but librustc_ast contains logic specific to
-// this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
-// cargo) to detect this crate.
-
-#![crate_name = "test"]
 #![unstable(feature = "test", issue = "50297")]
 #![doc(test(attr(deny(warnings))))]
-#![feature(libc)]
-#![feature(rustc_private)]
 #![feature(nll)]
 #![feature(available_parallelism)]
 #![feature(bench_black_box)]
 #![feature(internal_output_capture)]
-#![feature(panic_unwind)]
 #![feature(staged_api)]
 #![feature(termination_trait_lib)]
 #![feature(test)]
@@ -444,8 +436,8 @@ pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAnd
         .into_iter()
         .map(|x| {
             let testfn = match x.testfn {
-                DynBenchFn(bench) => DynTestFn(Box::new(move || {
-                    bench::run_once(|b| __rust_begin_short_backtrace(|| bench.run(b)))
+                DynBenchFn(benchfn) => DynTestFn(Box::new(move || {
+                    bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
                 })),
                 StaticBenchFn(benchfn) => DynTestFn(Box::new(move || {
                     bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
@@ -544,11 +536,9 @@ pub fn run_test(
         TestRunOpts { strategy, nocapture: opts.nocapture, concurrency, time: opts.time_options };
 
     match testfn {
-        DynBenchFn(bencher) => {
+        DynBenchFn(benchfn) => {
             // Benchmarks aren't expected to panic, so we run them all in-process.
-            crate::bench::benchmark(id, desc, monitor_ch, opts.nocapture, |harness| {
-                bencher.run(harness)
-            });
+            crate::bench::benchmark(id, desc, monitor_ch, opts.nocapture, benchfn);
             None
         }
         StaticBenchFn(benchfn) => {
diff --git a/library/test/src/stats.rs b/library/test/src/stats.rs
index 45fae9c76b4..40b05704b40 100644
--- a/library/test/src/stats.rs
+++ b/library/test/src/stats.rs
@@ -1,5 +1,4 @@
 #![allow(missing_docs)]
-#![allow(deprecated)] // Float
 
 use std::mem;
 
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index 3512a57e8e4..37bb38fb0df 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -74,11 +74,6 @@ impl fmt::Display for TestName {
     }
 }
 
-/// Represents a benchmark function.
-pub trait TDynBenchFn: Send {
-    fn run(&self, harness: &mut Bencher);
-}
-
 // A function that runs a test. If the function returns successfully,
 // the test succeeds; if the function panics then the test fails. We
 // may need to come up with a more clever definition of test in order
@@ -87,7 +82,7 @@ pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut Bencher)),
     DynTestFn(Box<dyn FnOnce() + Send>),
-    DynBenchFn(Box<dyn TDynBenchFn + 'static>),
+    DynBenchFn(Box<dyn Fn(&mut Bencher) + Send>),
 }
 
 impl TestFn {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 5a33073e6b0..5235a6b8180 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -974,6 +974,7 @@ class RustBuild(object):
 
     def build_bootstrap(self):
         """Build bootstrap"""
+        print("Building rustbuild")
         build_dir = os.path.join(self.build_dir, "bootstrap")
         if self.clean and os.path.exists(build_dir):
             shutil.rmtree(build_dir)
@@ -1133,7 +1134,7 @@ class RustBuild(object):
             recorded_submodules[data[3]] = data[2]
         for module in filtered_submodules:
             self.update_submodule(module[0], module[1], recorded_submodules)
-        print("Submodules updated in %.2f seconds" % (time() - start_time))
+        print("  Submodules updated in %.2f seconds" % (time() - start_time))
 
     def set_dist_environment(self, url):
         """Set download URL for normal environment"""
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 917abde9de1..6ccf8b1d522 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -988,10 +988,20 @@ impl<'a> Builder<'a> {
             }
         };
 
-        if use_new_symbol_mangling {
-            rustflags.arg("-Zsymbol-mangling-version=v0");
+        // cfg(bootstrap) -- drop the compiler.stage == 0 branch.
+        if compiler.stage == 0 {
+            if use_new_symbol_mangling {
+                rustflags.arg("-Zsymbol-mangling-version=v0");
+            } else {
+                rustflags.arg("-Zsymbol-mangling-version=legacy");
+            }
         } else {
-            rustflags.arg("-Zsymbol-mangling-version=legacy");
+            if use_new_symbol_mangling {
+                rustflags.arg("-Csymbol-mangling-version=v0");
+            } else {
+                rustflags.arg("-Csymbol-mangling-version=legacy");
+                rustflags.arg("-Zunstable-options");
+            }
         }
 
         // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`,
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 2fddda74a28..9180c5f03af 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -401,26 +401,19 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
                     "\n
 Arguments:
     This subcommand accepts a number of paths to directories to the crates
-    and/or artifacts to compile. For example:
-
-        ./x.py build library/core
-        ./x.py build library/core library/proc_macro
-        ./x.py build library/std --stage 1
-
-    If no arguments are passed then the complete artifacts for that stage are
-    also compiled.
+    and/or artifacts to compile. For example, for a quick build of a usable
+    compiler:
 
-        ./x.py build
-        ./x.py build --stage 1
+        ./x.py build --stage 1 library/std
 
-    For a quick build of a usable compiler, you can pass:
+    This will build a compiler and standard library from the local source code.
+    Once this is done, build/$ARCH/stage1 contains a usable compiler.
 
-        ./x.py build --stage 1 library/test
+    If no arguments are passed then the default artifacts for that stage are
+    compiled. For example:
 
-    This will first build everything once (like `--stage 0` without further
-    arguments would), and then use the compiler built in stage 0 to build
-    library/test and its dependencies.
-    Once this is done, build/$ARCH/stage1 contains a usable compiler.",
+        ./x.py build --stage 0
+        ./x.py build ",
                 );
             }
             "check" | "c" => {
@@ -430,14 +423,9 @@ Arguments:
     This subcommand accepts a number of paths to directories to the crates
     and/or artifacts to compile. For example:
 
-        ./x.py check library/core
-        ./x.py check library/core library/proc_macro
+        ./x.py check library/std
 
-    If no arguments are passed then the complete artifacts are compiled: std, test, and rustc. Note
-    also that since we use `cargo check`, by default this will automatically enable incremental
-    compilation, so there's no need to pass it separately, though it won't hurt. We also completely
-    ignore the stage passed, as there's no way to compile in non-stage 0 without actually building
-    the compiler.",
+    If no arguments are passed then many artifacts are checked.",
                 );
             }
             "clippy" => {
diff --git a/src/doc/book b/src/doc/book
-Subproject 8a0bb3c96e71927b80fa2286d7a5a5f2547c6aa
+Subproject d3740fb7aad0ea4a80ae20f64dee3a8cfc0c5c3
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 06f9e61931bcf58b91dfe6c924057e42ce273ee
+Subproject f8ba2f12df60ee19b96de24ae5b73af3de8a446
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 9bf0028b557798ddd07a6f652e4d0c635d3d662
+Subproject 875464457c4104686faf667f47848aa7b0f0a74
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 959be5478b4..d80e79d164a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1350,17 +1350,23 @@ impl Clean<Type> for hir::Ty<'_> {
             }
             TyKind::Slice(ref ty) => Slice(box ty.clean(cx)),
             TyKind::Array(ref ty, ref length) => {
-                let def_id = cx.tcx.hir().local_def_id(length.hir_id);
-                // NOTE(min_const_generics): We can't use `const_eval_poly` for constants
-                // as we currently do not supply the parent generics to anonymous constants
-                // but do allow `ConstKind::Param`.
-                //
-                // `const_eval_poly` tries to to first substitute generic parameters which
-                // results in an ICE while manually constructing the constant and using `eval`
-                // does nothing for `ConstKind::Param`.
-                let ct = ty::Const::from_anon_const(cx.tcx, def_id);
-                let param_env = cx.tcx.param_env(def_id);
-                let length = print_const(cx, ct.eval(cx.tcx, param_env));
+                let length = match length {
+                    hir::ArrayLen::Infer(_, _) => "_".to_string(),
+                    hir::ArrayLen::Body(anon_const) => {
+                        let def_id = cx.tcx.hir().local_def_id(anon_const.hir_id);
+                        // NOTE(min_const_generics): We can't use `const_eval_poly` for constants
+                        // as we currently do not supply the parent generics to anonymous constants
+                        // but do allow `ConstKind::Param`.
+                        //
+                        // `const_eval_poly` tries to to first substitute generic parameters which
+                        // results in an ICE while manually constructing the constant and using `eval`
+                        // does nothing for `ConstKind::Param`.
+                        let ct = ty::Const::from_anon_const(cx.tcx, def_id);
+                        let param_env = cx.tcx.param_env(def_id);
+                        print_const(cx, ct.eval(cx.tcx, param_env))
+                    }
+                };
+
                 Array(box ty.clean(cx), length)
             }
             TyKind::Tup(tys) => Tuple(tys.iter().map(|x| x.clean(cx)).collect()),
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 2ee5de24687..f0f61bb94c8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -889,20 +889,25 @@ impl AttributesExt for [ast::Attribute] {
 }
 
 crate trait NestedAttributesExt {
-    /// Returns `true` if the attribute list contains a specific `Word`
-    fn has_word(self, word: Symbol) -> bool;
+    /// Returns `true` if the attribute list contains a specific `word`
+    fn has_word(self, word: Symbol) -> bool
+    where
+        Self: std::marker::Sized,
+    {
+        <Self as NestedAttributesExt>::get_word_attr(self, word).is_some()
+    }
+
+    /// Returns `Some(attr)` if the attribute list contains 'attr'
+    /// corresponding to a specific `word`
     fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem>;
 }
 
-impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
-    NestedAttributesExt for I
+impl<I> NestedAttributesExt for I
+where
+    I: IntoIterator<Item = ast::NestedMetaItem>,
 {
-    fn has_word(self, word: Symbol) -> bool {
-        self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
-    }
-
-    fn get_word_attr(mut self, word: Symbol) -> Option<ast::NestedMetaItem> {
-        self.find(|attr| attr.is_word() && attr.has_name(word))
+    fn get_word_attr(self, word: Symbol) -> Option<ast::NestedMetaItem> {
+        self.into_iter().find(|attr| attr.is_word() && attr.has_name(word))
     }
 }
 
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index e5c667a37c6..d82c65398b8 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -108,7 +108,7 @@ html {
 /* General structure and fonts */
 
 body {
-	font: 16px/1.4 "Source Serif 4", NanumBarunGothic, serif;
+	font: 1rem/1.4 "Source Serif 4", NanumBarunGothic, serif;
 	margin: 0;
 	position: relative;
 
@@ -118,13 +118,13 @@ body {
 }
 
 h1 {
-	font-size: 1.5em;
+	font-size: 1.5rem;
 }
 h2 {
-	font-size: 1.4em;
+	font-size: 1.4rem;
 }
 h3 {
-	font-size: 1.3em;
+	font-size: 1.3rem;
 }
 h1, h2, h3, h4, h5, h6 {
 	font-weight: 500;
@@ -160,10 +160,10 @@ h2,
 	border-bottom: 1px solid;
 }
 h3.code-header {
-	font-size: 1.1em;
+	font-size: 1.1rem;
 }
 h4.code-header {
-	font-size: 1em;
+	font-size: 1rem;
 }
 h3.code-header, h4.code-header {
 	font-weight: 600;
@@ -206,7 +206,7 @@ div.impl-items > div:not(.docblock):not(.item-info),
 }
 
 .content ul.crate a.crate {
-	font-size: 16px/1.6;
+	font-size: 1rem/1.6;
 }
 
 ol, ul {
@@ -317,7 +317,7 @@ li {
 
 nav.sub {
 	position: relative;
-	font-size: 16px;
+	font-size: 1rem;
 	text-transform: uppercase;
 }
 
@@ -423,7 +423,7 @@ nav.sub {
 
 .sidebar .location {
 	border: 1px solid;
-	font-size: 17px;
+	font-size: 1.0625rem;
 	margin: 30px 10px 20px 10px;
 	text-align: center;
 	word-wrap: break-word;
@@ -432,7 +432,7 @@ nav.sub {
 }
 
 .sidebar .version {
-	font-size: 15px;
+	font-size: 0.9375rem;
 	text-align: center;
 	border-bottom: 1px solid;
 	overflow-wrap: break-word;
@@ -470,7 +470,7 @@ nav.sub {
 	overflow: hidden;
 	line-height: 15px;
 	padding: 7px 5px;
-	font-size: 14px;
+	font-size: 0.875rem;
 	font-weight: 300;
 	transition: border 500ms ease-out;
 }
@@ -479,7 +479,7 @@ nav.sub {
 	border-top: 1px solid;
 	border-bottom: 1px solid;
 	text-align: center;
-	font-size: 17px;
+	font-size: 1.0625rem;
 	margin-bottom: 5px;
 	font-weight: inherit;
 	padding: 0;
@@ -579,18 +579,18 @@ nav.sub {
 	white-space: pre-wrap;
 }
 
-.top-doc .docblock h2 { font-size: 1.3em; }
-.top-doc .docblock h3 { font-size: 1.15em; }
+.top-doc .docblock h2 { font-size: 1.3rem; }
+.top-doc .docblock h3 { font-size: 1.15rem; }
 .top-doc .docblock h4,
 .top-doc .docblock h5 {
-	font-size: 1.1em;
+	font-size: 1.1rem;
 }
 .top-doc .docblock h6 {
-	font-size: 1em;
+	font-size: 1rem;
 }
 
-.docblock h5 { font-size: 1em; }
-.docblock h6 { font-size: 0.95em; }
+.docblock h5 { font-size: 1rem; }
+.docblock h6 { font-size: 0.95rem; }
 
 .docblock {
 	margin-left: 24px;
@@ -605,7 +605,7 @@ nav.sub {
 .content .out-of-band {
 	flex-grow: 0;
 	text-align: right;
-	font-size: 23px;
+	font-size: 1.4375rem;
 	margin: 0px;
 	padding: 0 0 0 12px;
 	font-weight: normal;
@@ -646,7 +646,7 @@ nav.sub {
 .content td { vertical-align: top; }
 .content td:first-child { padding-right: 20px; }
 .content td p:first-child { margin-top: 0; }
-.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
+.content td h1, .content td h2 { margin-left: 0; font-size: 1.1rem; }
 .content tr:first-child td { border-top: 0; }
 
 .docblock table {
@@ -687,7 +687,7 @@ nav.sub {
 .content .multi-column li { width: 100%; display: inline-block; }
 
 .content > .methods > .method {
-	font-size: 1em;
+	font-size: 1rem;
 	position: relative;
 }
 /* Shift "where ..." part of method or fn definition down a line */
@@ -695,7 +695,7 @@ nav.sub {
 .content .fn .where,
 .content .where.fmt-newline {
 	display: block;
-	font-size: 0.8em;
+	font-size: 0.8rem;
 }
 
 .content .methods > div:not(.notable-traits):not(.method) {
@@ -718,7 +718,7 @@ nav.sub {
 }
 
 .content .item-info code {
-	font-size: 90%;
+	font-size: 0.81rem;
 }
 
 .content .item-info {
@@ -732,7 +732,7 @@ nav.sub {
 
 .content .item-info::before {
 	content: '⬑';
-	font-size: 25px;
+	font-size: 1.5625rem;
 	position: absolute;
 	top: -6px;
 	left: -19px;
@@ -835,7 +835,7 @@ h2.small-section-header > .anchor {
 	position: absolute;
 	top: 0;
 	right: 0;
-	font-size: 17px;
+	font-size: 1.0625rem;
 	font-weight: normal;
 }
 
@@ -905,7 +905,7 @@ h2.small-section-header > .anchor {
 	border-radius: 1px;
 	margin-top: 5px;
 	padding: 10px 16px;
-	font-size: 17px;
+	font-size: 1.0625rem;
 	transition: border-color 300ms ease;
 	transition: border-radius 300ms ease-in-out;
 	transition: box-shadow 300ms ease-in-out;
@@ -1000,7 +1000,7 @@ body.blur > :not(#help) {
 #help span.top, #help span.bottom {
 	text-align: center;
 	display: block;
-	font-size: 18px;
+	font-size: 1.125rem;
 
 }
 #help span.top {
@@ -1030,7 +1030,7 @@ body.blur > :not(#help) {
 .stab {
 	padding: 3px;
 	margin-bottom: 5px;
-	font-size: 90%;
+	font-size: 0.9rem;
 	font-weight: normal;
 }
 .stab p {
@@ -1038,7 +1038,7 @@ body.blur > :not(#help) {
 }
 
 .stab .emoji {
-	font-size: 1.2em;
+	font-size: 1.2rem;
 }
 
 /* Black one-pixel outline around emoji shapes */
@@ -1054,7 +1054,7 @@ body.blur > :not(#help) {
 .import-item .stab {
 	border-radius: 3px;
 	display: inline-block;
-	font-size: 80%;
+	font-size: 0.8rem;
 	line-height: 1.2;
 	margin-bottom: 0;
 	margin-left: .3em;
@@ -1080,7 +1080,7 @@ body.blur > :not(#help) {
 
 .impl-items .srclink, .impl .srclink, .methods .srclink {
 	/* Override header settings otherwise it's too bold */
-	font-size: 17px;
+	font-size: 1.0625rem;
 	font-weight: normal;
 }
 
@@ -1089,7 +1089,7 @@ body.blur > :not(#help) {
 }
 
 .has-srclink {
-	font-size: 16px;
+	font-size: 1rem;
 	margin-bottom: 12px;
 	/* Push the src link out to the right edge consistently */
 	justify-content: space-between;
@@ -1120,7 +1120,7 @@ a.test-arrow {
 	position: absolute;
 	padding: 5px 10px 5px 10px;
 	border-radius: 5px;
-	font-size: 130%;
+	font-size: 1.3rem;
 	top: 5px;
 	right: 5px;
 	z-index: 1;
@@ -1155,19 +1155,19 @@ a.test-arrow:hover{
 
 .out-of-band > span.since {
 	position: initial;
-	font-size: 20px;
+	font-size: 1.25rem;
 	margin-right: 5px;
 }
 
 h3.variant {
 	font-weight: 600;
-	font-size: 1.1em;
+	font-size: 1.1rem;
 	margin-bottom: 10px;
 	border-bottom: none;
 }
 
 .sub-variant h4 {
-	font-size: 1em;
+	font-size: 1rem;
 	font-weight: 400;
 	border-bottom: none;
 	margin-top: 0;
@@ -1227,7 +1227,7 @@ h3.variant {
 	padding: 5px 3px 3px 3px;
 	border-radius: 6px;
 	margin-left: 5px;
-	font-size: 16px;
+	font-size: 1rem;
 }
 
 .tooltip.ignore::after {
@@ -1260,7 +1260,7 @@ h3.variant {
 
 .tooltip.compile_fail, .tooltip.should_panic, .tooltip.ignore {
 	font-weight: bold;
-	font-size: 20px;
+	font-size: 1.25rem;
 }
 
 .notable-traits-tooltip {
@@ -1279,7 +1279,7 @@ h3.variant {
 	border-radius: 6px;
 	margin-left: 5px;
 	z-index: 10;
-	font-size: 16px;
+	font-size: 1rem;
 	cursor: default;
 	position: absolute;
 	border: 1px solid;
@@ -1299,14 +1299,14 @@ h3.variant {
 .notable-traits .notable {
 	margin: 0;
 	margin-bottom: 13px;
-	font-size: 19px;
+	font-size: 1.1875rem;
 	font-weight: 600;
 }
 
 .notable-traits .docblock code.content{
 	margin: 0;
 	padding: 0;
-	font-size: 20px;
+	font-size: 1.25rem;
 }
 
 /* Example code has the "Run" button that needs to be positioned relative to the pre */
@@ -1344,7 +1344,7 @@ pre.rust {
 	float: left;
 	width: 33.3%;
 	text-align: center;
-	font-size: 18px;
+	font-size: 1.125rem;
 	cursor: pointer;
 	border: 0;
 	border-top: 2px solid;
@@ -1357,7 +1357,7 @@ pre.rust {
 
 #titles > button > div.count {
 	display: inline-block;
-	font-size: 16px;
+	font-size: 1rem;
 }
 
 .notable-traits {
@@ -1384,7 +1384,7 @@ pre.rust {
 	left: 0;
 	cursor: pointer;
 	font-weight: bold;
-	font-size: 1.2em;
+	font-size: 1.2rem;
 	border-bottom: 1px solid;
 	display: flex;
 	height: 40px;
@@ -1398,7 +1398,7 @@ pre.rust {
 	overflow: auto;
 }
 #source-sidebar > .title {
-	font-size: 1.5em;
+	font-size: 1.5rem;
 	text-align: center;
 	border-bottom: 1px solid;
 	margin-bottom: 6px;
@@ -1426,6 +1426,9 @@ pre.rust {
 
 #theme-picker, #settings-menu, #help-button, #copy-path {
 	padding: 4px;
+	/* Rare exception to specifying font sizes in rem. Since these are acting
+	   as icons, it's okay to specify their sizes in pixels. */
+	font-size: 16px;
 	width: 27px;
 	height: 29px;
 	border: 1px solid;
@@ -1437,7 +1440,9 @@ pre.rust {
 	right: 30px;
 	font-family: "Fira Sans", Arial, sans-serif;
 	text-align: center;
-	font-size: 17px;
+	/* Rare exception to specifying font sizes in rem. Since this is acting
+	   as an icon, it's okay to specify their sizes in pixels. */
+	font-size: 16px;
 	padding-top: 2px;
 }
 
@@ -1499,7 +1504,7 @@ kbd {
 	border: 0;
 	border-collapse: collapse;
 	border-spacing: 0;
-	font-size: 16px;
+	font-size: 1rem;
 }
 
 .table-display tr td:first-child {
@@ -1511,11 +1516,11 @@ kbd {
 }
 .table-display .out-of-band {
 	position: relative;
-	font-size: 19px;
+	font-size: 1.1875rem;
 	display: block;
 }
 #implementors-list > .impl-items .table-display .out-of-band {
-	font-size: 17px;
+	font-size: 1.0625rem;
 }
 
 .table-display td:hover .anchor {
@@ -1557,7 +1562,7 @@ div.name.expand + .children {
 div.name::before {
 	content: "\25B6";
 	padding-left: 4px;
-	font-size: 0.7em;
+	font-size: 0.7rem;
 	position: absolute;
 	left: -16px;
 	top: 4px;
@@ -1624,7 +1629,7 @@ details.rustdoc-toggle.top-doc > summary::before,
 details.rustdoc-toggle.non-exhaustive > summary,
 details.rustdoc-toggle.non-exhaustive > summary::before {
 	font-family: 'Fira Sans';
-	font-size: 16px;
+	font-size: 1rem;
 }
 
 details.non-exhaustive {
@@ -1768,7 +1773,7 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 		min-height: 39px;
 		background: inherit;
 		text-align: left;
-		font-size: 24px;
+		font-size: 1.5rem;
 	}
 
 	.sidebar .location:empty {
@@ -1909,7 +1914,7 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 	}
 
 	.show-it > .block.items > ul > li > a {
-		font-size: 21px;
+		font-size: 1.3125rem;
 	}
 
 	/* Because of ios, we need to actually have a full height sidebar title so the
diff --git a/src/test/incremental/change_private_fn/struct_point.rs b/src/test/incremental/change_private_fn/struct_point.rs
index 1791c089cfa..d57267adc6b 100644
--- a/src/test/incremental/change_private_fn/struct_point.rs
+++ b/src/test/incremental/change_private_fn/struct_point.rs
@@ -51,7 +51,11 @@ pub mod point {
 pub mod fn_calls_methods_in_same_impl {
     use point::Point;
 
-    #[rustc_clean(cfg="cfail2")]
+    // The cached result should actually be loaded from disk
+    // (not just marked green) - for example, `DeadVisitor`
+    // always runs during compilation as a "pass", and loads
+    // the typeck results for bodies.
+    #[rustc_clean(cfg="cfail2", loaded_from_disk="typeck")]
     pub fn check() {
         let x = Point { x: 2.0, y: 2.0 };
         x.distance_from_origin();
diff --git a/src/test/incremental/hash-module-order.rs b/src/test/incremental/hash-module-order.rs
new file mode 100644
index 00000000000..fe9af9eeb37
--- /dev/null
+++ b/src/test/incremental/hash-module-order.rs
@@ -0,0 +1,28 @@
+// revisions: rpass1 rpass2
+// compile-flags: -Z incremental-ignore-spans -Z query-dep-graph
+
+// Tests that module hashing depends on the order of the items
+// (since the order is exposed through `Mod.item_ids`).
+// Changing the order of items (while keeping `Span`s the same)
+// should still result in `hir_owner` being invalidated.
+// Note that it's possible to keep the spans unchanged using
+// a proc-macro (e.g. producing the module via `quote!`)
+// but we use `-Z incremental-ignore-spans` for simplicity
+
+#![feature(rustc_attrs)]
+
+#[cfg(rpass1)]
+#[rustc_clean(cfg="rpass1",except="hir_owner")]
+mod foo {
+    struct First;
+    struct Second;
+}
+
+#[cfg(rpass2)]
+#[rustc_clean(cfg="rpass2",except="hir_owner")]
+mod foo {
+    struct Second;
+    struct First;
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs b/src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs
new file mode 100644
index 00000000000..56b88a426a1
--- /dev/null
+++ b/src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs
@@ -0,0 +1,12 @@
+// To avoid having to `or` gate `_` as an expr.
+#![feature(generic_arg_infer)]
+
+fn foo() -> [u8; _] {
+    //~^ ERROR the const placeholder `_` is not allowed within types on item signatures for generics
+    // FIXME(generic_arg_infer): this error message should say in the return type or sth like that.
+    [0; 3]
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr b/src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr
new file mode 100644
index 00000000000..eaa12b4192d
--- /dev/null
+++ b/src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr
@@ -0,0 +1,9 @@
+error[E0121]: the const placeholder `_` is not allowed within types on item signatures for generics
+  --> $DIR/array-in-sig.rs:4:18
+   |
+LL | fn foo() -> [u8; _] {
+   |                  ^ not allowed in type signatures
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/const-generics/generic_arg_infer/array-repeat-expr.rs b/src/test/ui/const-generics/generic_arg_infer/array-repeat-expr.rs
new file mode 100644
index 00000000000..d3e53d7a892
--- /dev/null
+++ b/src/test/ui/const-generics/generic_arg_infer/array-repeat-expr.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+// To avoid having to `or` gate `_` as an expr.
+#![feature(generic_arg_infer)]
+
+fn foo() -> [u8; 3] {
+    let x: [u8; _] = [0; _];
+    x
+}
+
+fn main() {
+    assert_eq!([0; _], foo());
+}
diff --git a/src/test/ui/inference/infer-arg-test.rs b/src/test/ui/const-generics/generic_arg_infer/infer-arg-test.rs
index 1b67ccd6c43..29aa0f59d74 100644
--- a/src/test/ui/inference/infer-arg-test.rs
+++ b/src/test/ui/const-generics/generic_arg_infer/infer-arg-test.rs
@@ -18,7 +18,5 @@ fn main() {
   let a: All<_, _, _>;
   all_fn();
   let v: [u8; _];
-  //~^ ERROR in expressions
   let v: [u8; 10] = [0; _];
-  //~^ ERROR in expressions
 }
diff --git a/src/test/ui/inference/infer-arg-test.stderr b/src/test/ui/const-generics/generic_arg_infer/infer-arg-test.stderr
index 30e171eac21..e6d0c743d01 100644
--- a/src/test/ui/inference/infer-arg-test.stderr
+++ b/src/test/ui/const-generics/generic_arg_infer/infer-arg-test.stderr
@@ -10,18 +10,6 @@ error: expected identifier, found reserved identifier `_`
 LL | fn bad_infer_fn<_>() {}
    |                 ^ expected identifier, found reserved identifier
 
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/infer-arg-test.rs:20:15
-   |
-LL |   let v: [u8; _];
-   |               ^ `_` not allowed here
-
-error: in expressions, `_` can only be used on the left-hand side of an assignment
-  --> $DIR/infer-arg-test.rs:22:25
-   |
-LL |   let v: [u8; 10] = [0; _];
-   |                         ^ `_` not allowed here
-
 error[E0392]: parameter `_` is never used
   --> $DIR/infer-arg-test.rs:7:17
    |
@@ -31,6 +19,6 @@ LL | struct BadInfer<_>;
    = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `_` to be a const parameter, use `const _: usize` instead
 
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
index c17f02d58f3..49eede4794b 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.normal.stderr
@@ -1,5 +1,35 @@
+error[E0658]: using `_` for array lengths is unstable
+  --> $DIR/feature-gate-generic_arg_infer.rs:11:27
+   |
+LL |     let _x: [u8; 3] = [0; _];
+   |                           ^
+   |
+   = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/feature-gate-generic_arg_infer.rs:11:27
+   |
+LL |     let _x: [u8; 3] = [0; _];
+   |                           ^ `_` not allowed here
+
+error[E0658]: using `_` for array lengths is unstable
+  --> $DIR/feature-gate-generic_arg_infer.rs:14:18
+   |
+LL |     let _y: [u8; _] = [0; 3];
+   |                  ^
+   |
+   = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/feature-gate-generic_arg_infer.rs:14:18
+   |
+LL |     let _y: [u8; _] = [0; 3];
+   |                  ^ `_` not allowed here
+
 error[E0747]: type provided when a constant was expected
-  --> $DIR/feature-gate-generic_arg_infer.rs:11:20
+  --> $DIR/feature-gate-generic_arg_infer.rs:20:20
    |
 LL |     let _x = foo::<_>([1,2]);
    |                    ^
@@ -7,6 +37,7 @@ LL |     let _x = foo::<_>([1,2]);
    = help: const arguments cannot yet be inferred with `_`
    = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0747`.
+Some errors have detailed explanations: E0658, E0747.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs
index 4729773b12e..afd14b7843e 100644
--- a/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs
+++ b/src/test/ui/feature-gates/feature-gate-generic_arg_infer.rs
@@ -7,7 +7,17 @@ fn foo<const N: usize>(_: [u8; N]) -> [u8; N] {
   [0; N]
 }
 
+fn bar() {
+    let _x: [u8; 3] = [0; _];
+    //[normal]~^ ERROR: using `_` for array lengths is unstable
+    //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
+    let _y: [u8; _] = [0; 3];
+    //[normal]~^ ERROR: using `_` for array lengths is unstable
+    //[normal]~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
+}
+
 fn main() {
     let _x = foo::<_>([1,2]);
     //[normal]~^ ERROR: type provided when a constant was expected
+    let _y = bar();
 }
diff --git a/src/test/ui/inference/char-as-str-multi.rs b/src/test/ui/inference/char-as-str-multi.rs
new file mode 100644
index 00000000000..21bbc6f20b2
--- /dev/null
+++ b/src/test/ui/inference/char-as-str-multi.rs
@@ -0,0 +1,6 @@
+// When a MULTI-character string literal is used where a char should be,
+// DO NOT suggest changing to single quotes.
+
+fn main() {
+    let _: char = "foo"; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/char-as-str-multi.stderr b/src/test/ui/inference/char-as-str-multi.stderr
new file mode 100644
index 00000000000..c3ba17a5579
--- /dev/null
+++ b/src/test/ui/inference/char-as-str-multi.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/char-as-str-multi.rs:5:19
+   |
+LL |     let _: char = "foo";
+   |            ----   ^^^^^ expected `char`, found `&str`
+   |            |
+   |            expected due to this
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inference/char-as-str-single.fixed b/src/test/ui/inference/char-as-str-single.fixed
new file mode 100644
index 00000000000..e401492a830
--- /dev/null
+++ b/src/test/ui/inference/char-as-str-single.fixed
@@ -0,0 +1,11 @@
+// When a SINGLE-character string literal is used where a char should be,
+// suggest changing to single quotes.
+
+// Testing both single-byte and multi-byte characters, as we should handle both.
+
+// run-rustfix
+
+fn main() {
+    let _: char = 'a'; //~ ERROR mismatched types
+    let _: char = '人'; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/char-as-str-single.rs b/src/test/ui/inference/char-as-str-single.rs
new file mode 100644
index 00000000000..4f23cea5354
--- /dev/null
+++ b/src/test/ui/inference/char-as-str-single.rs
@@ -0,0 +1,11 @@
+// When a SINGLE-character string literal is used where a char should be,
+// suggest changing to single quotes.
+
+// Testing both single-byte and multi-byte characters, as we should handle both.
+
+// run-rustfix
+
+fn main() {
+    let _: char = "a"; //~ ERROR mismatched types
+    let _: char = "人"; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/char-as-str-single.stderr b/src/test/ui/inference/char-as-str-single.stderr
new file mode 100644
index 00000000000..29075c15414
--- /dev/null
+++ b/src/test/ui/inference/char-as-str-single.stderr
@@ -0,0 +1,29 @@
+error[E0308]: mismatched types
+  --> $DIR/char-as-str-single.rs:9:19
+   |
+LL |     let _: char = "a";
+   |            ----   ^^^ expected `char`, found `&str`
+   |            |
+   |            expected due to this
+   |
+help: if you meant to write a `char` literal, use single quotes
+   |
+LL |     let _: char = 'a';
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/char-as-str-single.rs:10:19
+   |
+LL |     let _: char = "人";
+   |            ----   ^^^^ expected `char`, found `&str`
+   |            |
+   |            expected due to this
+   |
+help: if you meant to write a `char` literal, use single quotes
+   |
+LL |     let _: char = '人';
+   |                   ~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inference/str-as-char.fixed b/src/test/ui/inference/str-as-char.fixed
new file mode 100644
index 00000000000..09f3dec5a17
--- /dev/null
+++ b/src/test/ui/inference/str-as-char.fixed
@@ -0,0 +1,8 @@
+// When a char literal is used where a str should be,
+// suggest changing to double quotes.
+
+// run-rustfix
+
+fn main() {
+    let _: &str = "a"; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/str-as-char.rs b/src/test/ui/inference/str-as-char.rs
new file mode 100644
index 00000000000..7092a612442
--- /dev/null
+++ b/src/test/ui/inference/str-as-char.rs
@@ -0,0 +1,8 @@
+// When a char literal is used where a str should be,
+// suggest changing to double quotes.
+
+// run-rustfix
+
+fn main() {
+    let _: &str = 'a'; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/str-as-char.stderr b/src/test/ui/inference/str-as-char.stderr
new file mode 100644
index 00000000000..ebbe7c80f77
--- /dev/null
+++ b/src/test/ui/inference/str-as-char.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/str-as-char.rs:7:19
+   |
+LL |     let _: &str = 'a';
+   |            ----   ^^^ expected `&str`, found `char`
+   |            |
+   |            expected due to this
+   |
+help: if you meant to write a `str` literal, use double quotes
+   |
+LL |     let _: &str = "a";
+   |                   ~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr
index d126e1bf0b5..e065e17c280 100644
--- a/src/test/ui/issues/issue-23589.stderr
+++ b/src/test/ui/issues/issue-23589.stderr
@@ -12,6 +12,11 @@ error[E0308]: mismatched types
    |
 LL |     let v: Vec(&str) = vec!['1', '2'];
    |                             ^^^ expected `&str`, found `char`
+   |
+help: if you meant to write a `str` literal, use double quotes
+   |
+LL |     let v: Vec(&str) = vec!["1", '2'];
+   |                             ~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
index e4e9705b07d..52ee1db5b15 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -5,7 +5,6 @@ LL |     let _result = &mut Some(42).as_deref_mut();
    |                                 ^^^^^^^^^^^^ method cannot be called on `Option<{integer}>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
-           `{integer}: DerefMut`
            `{integer}: Deref`
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
index 98a7091dd05..018557881ef 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -5,7 +5,6 @@ LL |     let _result = &mut Ok(42).as_deref_mut();
    |                               ^^^^^^^^^^^^ method cannot be called on `Result<{integer}, _>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
-           `{integer}: DerefMut`
            `{integer}: Deref`
 
 error: aborting due to previous error
diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
index 343a26c14a9..90983f35a5e 100644
--- a/src/test/ui/macros/stringify.rs
+++ b/src/test/ui/macros/stringify.rs
@@ -661,9 +661,9 @@ fn test_pat() {
     assert_eq!(stringify_pat!(ref mut _x @ _), "ref mut _x @ _");
 
     // PatKind::Struct
-    assert_eq!(stringify_pat!(Struct {}), "Struct {  }"); // FIXME
-    assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> {  }");
-    assert_eq!(stringify_pat!(Struct::<'static> {}), "Struct::<'static> {  }");
+    assert_eq!(stringify_pat!(Struct {}), "Struct {}");
+    assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> {}");
+    assert_eq!(stringify_pat!(Struct::<'static> {}), "Struct::<'static> {}");
     assert_eq!(stringify_pat!(Struct { x }), "Struct { x }");
     assert_eq!(stringify_pat!(Struct { x: _x }), "Struct { x: _x }");
     assert_eq!(stringify_pat!(Struct { .. }), "Struct { .. }");
@@ -672,7 +672,7 @@ fn test_pat() {
     #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
     assert_eq!(
         stringify_pat!(<Struct as Trait>::Type {}),
-        "<Struct as Trait>::Type {  }",
+        "<Struct as Trait>::Type {}",
     );
 
     // PatKind::TupleStruct
diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs
index f85c10d78c5..6303c6e6a5d 100644
--- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs
+++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs
@@ -3,5 +3,5 @@ struct Foo;
 fn main() {
     let a: Result<(), Foo> = Ok(());
     a.unwrap();
-    //~^ ERROR the method
+    //~^ ERROR `Foo` doesn't implement `Debug`
 }
diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
index 596b7bfe79c..dc73bcd6e4d 100644
--- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
+++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
@@ -1,19 +1,17 @@
-error[E0599]: the method `unwrap` exists for enum `Result<(), Foo>`, but its trait bounds were not satisfied
+error[E0277]: `Foo` doesn't implement `Debug`
   --> $DIR/method-help-unsatisfied-bound.rs:5:7
    |
-LL | struct Foo;
-   | ----------- doesn't satisfy `Foo: Debug`
-...
 LL |     a.unwrap();
-   |       ^^^^^^ method cannot be called on `Result<(), Foo>` due to unsatisfied trait bounds
+   |       ^^^^^^ `Foo` cannot be formatted using `{:?}`
    |
-   = note: the following trait bounds were not satisfied:
-           `Foo: Debug`
-help: consider annotating `Foo` with `#[derive(Debug)]`
-   |
-LL | #[derive(Debug)]
+   = help: the trait `Debug` is not implemented for `Foo`
+   = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
+note: required by a bound in `Result::<T, E>::unwrap`
+  --> $SRC_DIR/core/src/result.rs:LL:COL
    |
+LL |         E: fmt::Debug,
+   |            ^^^^^^^^^^ required by this bound in `Result::<T, E>::unwrap`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0599`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs
index fd01337296f..39ffe86dd49 100644
--- a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs
+++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs
@@ -1,3 +1,7 @@
+// This test has been spuriously failing a lot recently (#92000).
+// Ignore it until the underlying issue is fixed.
+// ignore-test
+
 // Regression test for #87481: short backtrace formatting cut off the entire stack trace.
 
 // Codegen-units is specified here so that we can replicate a typical rustc invocation which
diff --git a/src/test/ui/suggestions/while-let-typo.rs b/src/test/ui/suggestions/while-let-typo.rs
new file mode 100644
index 00000000000..dbbcdee3c19
--- /dev/null
+++ b/src/test/ui/suggestions/while-let-typo.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let foo = Some(0);
+    let bar = None;
+    while Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
+    while Some(foo) = bar {}
+    while 3 = foo {} //~ ERROR mismatched types
+    while Some(3) = foo {} //~ ERROR invalid left-hand side of assignment
+    while x = 5 {} //~ ERROR cannot find value `x` in this scope
+}
diff --git a/src/test/ui/suggestions/while-let-typo.stderr b/src/test/ui/suggestions/while-let-typo.stderr
new file mode 100644
index 00000000000..7cc2ed3149b
--- /dev/null
+++ b/src/test/ui/suggestions/while-let-typo.stderr
@@ -0,0 +1,45 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/while-let-typo.rs:4:16
+   |
+LL |     while Some(x) = foo {}
+   |                ^ not found in this scope
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     while let Some(x) = foo {}
+   |           +++
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/while-let-typo.rs:8:11
+   |
+LL |     while x = 5 {}
+   |           ^ not found in this scope
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     while let x = 5 {}
+   |           +++
+
+error[E0308]: mismatched types
+  --> $DIR/while-let-typo.rs:6:11
+   |
+LL |     while 3 = foo {}
+   |           ^^^^^^^ expected `bool`, found `()`
+
+error[E0070]: invalid left-hand side of assignment
+  --> $DIR/while-let-typo.rs:7:19
+   |
+LL |     while Some(3) = foo {}
+   |                -  ^
+   |                |
+   |                cannot assign to this expression
+   |
+help: you might have meant to use pattern destructuring
+   |
+LL |     while let Some(3) = foo {}
+   |           +++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0070, E0308, E0425.
+For more information about an error, try `rustc --explain E0070`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject fcef61230c3b6213b6b0d233a36ba4ebd1649ec
+Subproject 358e79fe56fe374649275ca7aebaafd57ade0e8
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index 47c0a84cd46..af36f726700 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -59,6 +59,7 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx
         if let ItemKind::Struct(data, _) = &item.kind;
         if let Some(last_field) = data.fields().last();
         if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind;
+        if let rustc_hir::ArrayLen::Body(length) = length;
 
         // Then check if that that array zero-sized
         let length_ldid = cx.tcx.hir().local_def_id(length.hir_id);
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index c1b811c2174..9b06ca4e824 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -6,7 +6,7 @@ use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_ast::LitIntType;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
-use rustc_hir::{ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
+use rustc_hir::{ArrayLen, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::{Ident, Symbol};
@@ -567,7 +567,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 bind!(self, value, length);
                 kind!("Repeat({value}, {length})");
                 self.expr(value);
-                self.body(field!(length.body));
+                match length.value {
+                    ArrayLen::Infer(..) => out!("if let ArrayLen::Infer(..) = length;"),
+                    ArrayLen::Body(anon_const) => {
+                        bind!(self, anon_const);
+                        out!("if let ArrayLen::Body({anon_const}) = {length};");
+                        self.body(field!(anon_const.body));
+                    }
+                }
             },
             ExprKind::Err => kind!("Err"),
             ExprKind::DropTemps(expr) => {
diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
index abf4826a069..c96766e5678 100644
--- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
@@ -334,12 +334,17 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
             println!("{}anon_const:", ind);
             print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1);
         },
-        hir::ExprKind::Repeat(val, ref anon_const) => {
+        hir::ExprKind::Repeat(val, length) => {
             println!("{}Repeat", ind);
             println!("{}value:", ind);
             print_expr(cx, val, indent + 1);
             println!("{}repeat count:", ind);
-            print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1);
+            match length {
+                hir::ArrayLen::Infer(_, _) => println!("{}repeat count: _", ind),
+                hir::ArrayLen::Body(anon_const) => {
+                    print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1)
+                }
+            }
         },
         hir::ExprKind::Err => {
             println!("{}Err", ind);
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index ad50759effa..ac2b1a0259e 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -8,7 +8,7 @@ use rustc_hir::HirIdMap;
 use rustc_hir::{
     BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
     InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
-    StmtKind, Ty, TyKind, TypeBinding,
+    StmtKind, Ty, TyKind, TypeBinding, ArrayLen
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::LateContext;
@@ -170,6 +170,14 @@ impl HirEqInterExpr<'_, '_, '_> {
         }
     }
 
+    pub fn eq_array_length(&mut self, left: ArrayLen, right: ArrayLen) -> bool {
+            match (left, right) {
+                (ArrayLen::Infer(..), ArrayLen::Infer(..)) => true,
+                (ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_body(l_ct.body, r_ct.body),
+                (_, _) => false,
+            }
+    }
+
     pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {
         let cx = self.inner.cx;
         let eval_const = |body| constant_context(cx, cx.tcx.typeck_body(body)).expr(&cx.tcx.hir().body(body).value);
@@ -194,8 +202,8 @@ impl HirEqInterExpr<'_, '_, '_> {
         }
 
         let is_eq = match (
-            &reduce_exprkind(self.inner.cx, &left.kind),
-            &reduce_exprkind(self.inner.cx, &right.kind),
+            reduce_exprkind(self.inner.cx, &left.kind),
+            reduce_exprkind(self.inner.cx, &right.kind),
         ) {
             (&ExprKind::AddrOf(lb, l_mut, le), &ExprKind::AddrOf(rb, r_mut, re)) => {
                 lb == rb && l_mut == r_mut && self.eq_expr(le, re)
@@ -232,7 +240,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             },
             (&ExprKind::Index(la, li), &ExprKind::Index(ra, ri)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
             (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
-                self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
+                self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
             },
             (&ExprKind::Let(l), &ExprKind::Let(r)) => {
                 self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
@@ -253,8 +261,8 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::MethodCall(l_path, _, l_args, _), &ExprKind::MethodCall(r_path, _, r_args, _)) => {
                 self.inner.allow_side_effects && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args)
             },
-            (&ExprKind::Repeat(le, ref ll_id), &ExprKind::Repeat(re, ref rl_id)) => {
-                self.eq_expr(le, re) && self.eq_body(ll_id.body, rl_id.body)
+            (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
+                self.eq_expr(le, re) && self.eq_array_length(ll, rl)
             },
             (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
             (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
@@ -391,8 +399,8 @@ impl HirEqInterExpr<'_, '_, '_> {
     fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
         match (&left.kind, &right.kind) {
             (&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
-            (&TyKind::Array(lt, ref ll_id), &TyKind::Array(rt, ref rl_id)) => {
-                self.eq_ty(lt, rt) && self.eq_body(ll_id.body, rl_id.body)
+            (&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => {
+                self.eq_ty(lt, rt) && self.eq_array_length(ll, rl)
             },
             (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => {
                 l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty)
@@ -714,9 +722,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             ExprKind::ConstBlock(ref l_id) => {
                 self.hash_body(l_id.body);
             },
-            ExprKind::Repeat(e, ref l_id) => {
+            ExprKind::Repeat(e, len) => {
                 self.hash_expr(e);
-                self.hash_body(l_id.body);
+                self.hash_array_length(len);
             },
             ExprKind::Ret(ref e) => {
                 if let Some(e) = *e {
@@ -906,9 +914,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             TyKind::Slice(ty) => {
                 self.hash_ty(ty);
             },
-            TyKind::Array(ty, anon_const) => {
+            &TyKind::Array(ty, len) => {
                 self.hash_ty(ty);
-                self.hash_body(anon_const.body);
+                self.hash_array_length(len);
             },
             TyKind::Ptr(ref mut_ty) => {
                 self.hash_ty(mut_ty.ty);
@@ -953,6 +961,13 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         }
     }
 
+    pub fn hash_array_length(&mut self, length: ArrayLen) {
+        match length {
+            ArrayLen::Infer(..) => {}
+            ArrayLen::Body(anon_const) => self.hash_body(anon_const.body),
+        }
+    }
+
     pub fn hash_body(&mut self, body_id: BodyId) {
         // swap out TypeckResults when hashing a body
         let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id));
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 54d470ca738..9179e67c4f4 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -79,7 +79,7 @@ use rustc_hir::{
     def, Arm, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl,
     ForeignItem, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local,
     MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem,
-    TraitItemKind, TraitRef, TyKind, UnOp,
+    TraitItemKind, TraitRef, TyKind, UnOp, ArrayLen
 };
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::exports::Export;
@@ -703,8 +703,9 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
             _ => false,
         },
         ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
-        ExprKind::Repeat(x, y) => if_chain! {
-            if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(y.body).value.kind;
+        ExprKind::Repeat(x, len) => if_chain! {
+            if let ArrayLen::Body(len) = len;
+            if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind;
             if let LitKind::Int(v, _) = const_lit.node;
             if v <= 32 && is_default_equivalent(cx, x);
             then {
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 1a4da1627b7..836558b07cb 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -193,7 +193,6 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv
             }
         },
         Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
-        Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() {
diff --git a/src/tools/clippy/tests/ui/author/repeat.stdout b/src/tools/clippy/tests/ui/author/repeat.stdout
index f16350e4b5e..471bbce4f41 100644
--- a/src/tools/clippy/tests/ui/author/repeat.stdout
+++ b/src/tools/clippy/tests/ui/author/repeat.stdout
@@ -2,7 +2,8 @@ if_chain! {
     if let ExprKind::Repeat(value, length) = expr.kind;
     if let ExprKind::Lit(ref lit) = value.kind;
     if let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node;
-    let expr1 = &cx.tcx.hir().body(length.body).value;
+    if let ArrayLen::Body(anon_const) = length;
+    let expr1 = &cx.tcx.hir().body(anon_const.body).value;
     if let ExprKind::Lit(ref lit1) = expr1.kind;
     if let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node;
     then {