diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index cb7b7c0eb6116..a1cbcde1f4291 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -10,82 +10,90 @@ use rustc_span::symbol::Ident;
 use rustc_span::{source_map::Spanned, Span};
 
 impl<'a, 'hir> LoweringContext<'a, 'hir> {
-    crate fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
+    crate fn lower_pat(&mut self, mut pattern: &Pat) -> &'hir hir::Pat<'hir> {
         ensure_sufficient_stack(|| {
-            let node = match p.kind {
-                PatKind::Wild => hir::PatKind::Wild,
-                PatKind::Ident(ref binding_mode, ident, ref sub) => {
-                    let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
-                    let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
-                    node
-                }
-                PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
-                PatKind::TupleStruct(ref path, ref pats) => {
-                    let qpath = self.lower_qpath(
-                        p.id,
-                        &None,
-                        path,
-                        ParamMode::Optional,
-                        ImplTraitContext::disallowed(),
-                    );
-                    let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
-                    hir::PatKind::TupleStruct(qpath, pats, ddpos)
-                }
-                PatKind::Or(ref pats) => hir::PatKind::Or(
-                    self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
-                ),
-                PatKind::Path(ref qself, ref path) => {
-                    let qpath = self.lower_qpath(
-                        p.id,
-                        qself,
-                        path,
-                        ParamMode::Optional,
-                        ImplTraitContext::disallowed(),
-                    );
-                    hir::PatKind::Path(qpath)
-                }
-                PatKind::Struct(ref path, ref fields, etc) => {
-                    let qpath = self.lower_qpath(
-                        p.id,
-                        &None,
-                        path,
-                        ParamMode::Optional,
-                        ImplTraitContext::disallowed(),
-                    );
+            // loop here to avoid recursion
+            let node = loop {
+                match pattern.kind {
+                    PatKind::Wild => break hir::PatKind::Wild,
+                    PatKind::Ident(ref binding_mode, ident, ref sub) => {
+                        let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
+                        break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
+                    }
+                    PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
+                    PatKind::TupleStruct(ref path, ref pats) => {
+                        let qpath = self.lower_qpath(
+                            pattern.id,
+                            &None,
+                            path,
+                            ParamMode::Optional,
+                            ImplTraitContext::disallowed(),
+                        );
+                        let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
+                        break hir::PatKind::TupleStruct(qpath, pats, ddpos);
+                    }
+                    PatKind::Or(ref pats) => {
+                        break hir::PatKind::Or(
+                            self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
+                        );
+                    }
+                    PatKind::Path(ref qself, ref path) => {
+                        let qpath = self.lower_qpath(
+                            pattern.id,
+                            qself,
+                            path,
+                            ParamMode::Optional,
+                            ImplTraitContext::disallowed(),
+                        );
+                        break hir::PatKind::Path(qpath);
+                    }
+                    PatKind::Struct(ref path, ref fields, etc) => {
+                        let qpath = self.lower_qpath(
+                            pattern.id,
+                            &None,
+                            path,
+                            ParamMode::Optional,
+                            ImplTraitContext::disallowed(),
+                        );
 
-                    let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
-                        hir_id: self.next_id(),
-                        ident: f.ident,
-                        pat: self.lower_pat(&f.pat),
-                        is_shorthand: f.is_shorthand,
-                        span: f.span,
-                    }));
-                    hir::PatKind::Struct(qpath, fs, etc)
-                }
-                PatKind::Tuple(ref pats) => {
-                    let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
-                    hir::PatKind::Tuple(pats, ddpos)
-                }
-                PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
-                PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl),
-                PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
-                    hir::PatKind::Range(
-                        e1.as_deref().map(|e| self.lower_expr(e)),
-                        e2.as_deref().map(|e| self.lower_expr(e)),
-                        self.lower_range_end(end, e2.is_some()),
-                    )
-                }
-                PatKind::Slice(ref pats) => self.lower_pat_slice(pats),
-                PatKind::Rest => {
-                    // If we reach here the `..` pattern is not semantically allowed.
-                    self.ban_illegal_rest_pat(p.span)
+                        let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
+                            hir_id: self.next_id(),
+                            ident: f.ident,
+                            pat: self.lower_pat(&f.pat),
+                            is_shorthand: f.is_shorthand,
+                            span: f.span,
+                        }));
+                        break hir::PatKind::Struct(qpath, fs, etc);
+                    }
+                    PatKind::Tuple(ref pats) => {
+                        let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
+                        break hir::PatKind::Tuple(pats, ddpos);
+                    }
+                    PatKind::Box(ref inner) => {
+                        break hir::PatKind::Box(self.lower_pat(inner));
+                    }
+                    PatKind::Ref(ref inner, mutbl) => {
+                        break hir::PatKind::Ref(self.lower_pat(inner), mutbl);
+                    }
+                    PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
+                        break hir::PatKind::Range(
+                            e1.as_deref().map(|e| self.lower_expr(e)),
+                            e2.as_deref().map(|e| self.lower_expr(e)),
+                            self.lower_range_end(end, e2.is_some()),
+                        );
+                    }
+                    PatKind::Slice(ref pats) => break self.lower_pat_slice(pats),
+                    PatKind::Rest => {
+                        // If we reach here the `..` pattern is not semantically allowed.
+                        break self.ban_illegal_rest_pat(pattern.span);
+                    }
+                    // return inner to be processed in next loop
+                    PatKind::Paren(ref inner) => pattern = inner,
+                    PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
                 }
-                // FIXME: consider not using recursion to lower this.
-                PatKind::Paren(ref inner) => return self.lower_pat(inner),
-                PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", p.span),
             };
 
-            self.pat_with_node_id_of(p, node)
+            self.pat_with_node_id_of(pattern, node)
         })
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 092d1cea29515..ea1a7cfa5d3b5 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -936,8 +936,8 @@ unsafe fn embed_bitcode(
         llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
     } else {
         let asm = "
-            .section .llvmbc,\"a\"
-            .section .llvmcmd,\"a\"
+            .section .llvmbc,\"e\"
+            .section .llvmcmd,\"e\"
         ";
         llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
     }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 150cedde7e833..56ff580b43b59 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -324,8 +324,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     }
 
     #[inline]
-    pub fn coverage_context(&'a self) -> &'a coverageinfo::CrateCoverageContext<'tcx> {
-        self.coverage_cx.as_ref().unwrap()
+    pub fn coverage_context(&'a self) -> Option<&'a coverageinfo::CrateCoverageContext<'tcx>> {
+        self.coverage_cx.as_ref()
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 0098555a3736b..c1163a871cf1f 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -26,7 +26,10 @@ use tracing::debug;
 /// undocumented details in Clang's implementation (that may or may not be important) were also
 /// replicated for Rust's Coverage Map.
 pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
-    let function_coverage_map = cx.coverage_context().take_function_coverage_map();
+    let function_coverage_map = match cx.coverage_context() {
+        Some(ctx) => ctx.take_function_coverage_map(),
+        None => return,
+    };
     if function_coverage_map.is_empty() {
         // This module has no functions with coverage instrumentation
         return;
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 2bd37bf9c4f9c..7fdbe1a55128a 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -64,17 +64,22 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         function_source_hash: u64,
         id: CounterValueReference,
         region: CodeRegion,
-    ) {
-        debug!(
-            "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={:?}, \
-             at {:?}",
-            instance, function_source_hash, id, region,
-        );
-        let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
-        coverage_regions
-            .entry(instance)
-            .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_counter(function_source_hash, id, region);
+    ) -> bool {
+        if let Some(coverage_context) = self.coverage_context() {
+            debug!(
+                "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={:?}, \
+                at {:?}",
+                instance, function_source_hash, id, region,
+            );
+            let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut();
+            coverage_regions
+                .entry(instance)
+                .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
+                .add_counter(function_source_hash, id, region);
+            true
+        } else {
+            false
+        }
     }
 
     fn add_counter_expression_region(
@@ -85,29 +90,39 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         op: Op,
         rhs: ExpressionOperandId,
         region: CodeRegion,
-    ) {
-        debug!(
-            "adding counter expression to coverage_regions: instance={:?}, id={:?}, {:?} {:?} {:?}, \
-             at {:?}",
-            instance, id, lhs, op, rhs, region,
-        );
-        let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
-        coverage_regions
-            .entry(instance)
-            .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_counter_expression(id, lhs, op, rhs, region);
+    ) -> bool {
+        if let Some(coverage_context) = self.coverage_context() {
+            debug!(
+                "adding counter expression to coverage_regions: instance={:?}, id={:?}, {:?} {:?} {:?}, \
+                at {:?}",
+                instance, id, lhs, op, rhs, region,
+            );
+            let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut();
+            coverage_regions
+                .entry(instance)
+                .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
+                .add_counter_expression(id, lhs, op, rhs, region);
+            true
+        } else {
+            false
+        }
     }
 
-    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) {
-        debug!(
-            "adding unreachable code to coverage_regions: instance={:?}, at {:?}",
-            instance, region,
-        );
-        let mut coverage_regions = self.coverage_context().function_coverage_map.borrow_mut();
-        coverage_regions
-            .entry(instance)
-            .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
-            .add_unreachable_region(region);
+    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool {
+        if let Some(coverage_context) = self.coverage_context() {
+            debug!(
+                "adding unreachable code to coverage_regions: instance={:?}, at {:?}",
+                instance, region,
+            );
+            let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut();
+            coverage_regions
+                .entry(instance)
+                .or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
+                .add_unreachable_region(region);
+            true
+        } else {
+            false
+        }
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
index a2ad27b925c34..4811adea9ec06 100644
--- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
@@ -10,19 +10,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let Coverage { kind, code_region } = coverage;
         match kind {
             CoverageKind::Counter { function_source_hash, id } => {
-                bx.add_counter_region(self.instance, function_source_hash, id, code_region);
+                if bx.add_counter_region(self.instance, function_source_hash, id, code_region) {
+                    let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id());
 
-                let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id());
-
-                let fn_name = bx.create_pgo_func_name_var(self.instance);
-                let hash = bx.const_u64(function_source_hash);
-                let num_counters = bx.const_u32(coverageinfo.num_counters);
-                let id = bx.const_u32(u32::from(id));
-                debug!(
-                    "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
-                    fn_name, hash, num_counters, id,
-                );
-                bx.instrprof_increment(fn_name, hash, num_counters, id);
+                    let fn_name = bx.create_pgo_func_name_var(self.instance);
+                    let hash = bx.const_u64(function_source_hash);
+                    let num_counters = bx.const_u32(coverageinfo.num_counters);
+                    let id = bx.const_u32(u32::from(id));
+                    debug!(
+                        "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
+                        fn_name, hash, num_counters, id,
+                    );
+                    bx.instrprof_increment(fn_name, hash, num_counters, id);
+                }
             }
             CoverageKind::Expression { id, lhs, op, rhs } => {
                 bx.add_counter_expression_region(self.instance, id, lhs, op, rhs, code_region);
diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
index b74e4e459016f..3b1654f3ad4fc 100644
--- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
@@ -9,14 +9,18 @@ pub trait CoverageInfoMethods: BackendTypes {
 pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
     fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value;
 
+    /// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage`
+    /// is not enabled (a coverage map is not being generated).
     fn add_counter_region(
         &mut self,
         instance: Instance<'tcx>,
         function_source_hash: u64,
         id: CounterValueReference,
         region: CodeRegion,
-    );
+    ) -> bool;
 
+    /// Returns true if the expression was added to the coverage map; false if
+    /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated).
     fn add_counter_expression_region(
         &mut self,
         instance: Instance<'tcx>,
@@ -25,7 +29,9 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
         op: Op,
         rhs: ExpressionOperandId,
         region: CodeRegion,
-    );
+    ) -> bool;
 
-    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion);
+    /// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage`
+    /// is not enabled (a coverage map is not being generated).
+    fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool;
 }
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 4d884dde39387..16e9aafb25a54 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -175,19 +175,15 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
 impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
     type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
 
-    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
-        let (val, span) = match (value1.val, value2.val) {
+    fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
+        Ok(match (value1.val, value2.val) {
             (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
                 bug!("equating two const variables, both of which have known values")
             }
 
             // If one side is known, prefer that one.
-            (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
-                (value1.val, value1.origin.span)
-            }
-            (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
-                (value2.val, value2.origin.span)
-            }
+            (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => value1,
+            (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => value2,
 
             // If both sides are *unknown*, it hardly matters, does it?
             (
@@ -200,16 +196,11 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
                 // universe is the minimum of the two universes, because that is
                 // the one which contains the fewest names in scope.
                 let universe = cmp::min(universe1, universe2);
-                (ConstVariableValue::Unknown { universe }, value1.origin.span)
+                ConstVarValue {
+                    val: ConstVariableValue::Unknown { universe },
+                    origin: value1.origin,
+                }
             }
-        };
-
-        Ok(ConstVarValue {
-            origin: ConstVariableOrigin {
-                kind: ConstVariableOriginKind::ConstInference,
-                span: span,
-            },
-            val,
         })
     }
 }
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 5524d91a6d533..0e5e22dcaae9f 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -30,8 +30,6 @@
 //!
 //! These methods return true to indicate that the visitor has found what it is
 //! looking for, and does not need to visit anything else.
-
-use crate::ty::structural_impls::PredicateVisitor;
 use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -211,6 +209,10 @@ pub trait TypeVisitor<'tcx>: Sized {
     fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
         c.super_visit_with(self)
     }
+
+    fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> bool {
+        p.super_visit_with(self)
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -868,9 +870,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
             _ => ct.super_visit_with(self),
         }
     }
-}
 
-impl<'tcx> PredicateVisitor<'tcx> for HasEscapingVarsVisitor {
     fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
         predicate.inner.outer_exclusive_binder > self.outer_index
     }
@@ -903,9 +903,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
         debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
         flags.intersects(self.flags)
     }
-}
 
-impl<'tcx> PredicateVisitor<'tcx> for HasTypeFlagsVisitor {
     fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
         debug!(
             "HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
@@ -914,6 +912,7 @@ impl<'tcx> PredicateVisitor<'tcx> for HasTypeFlagsVisitor {
         predicate.inner.flags.intersects(self.flags)
     }
 }
+
 /// Collects all the late-bound regions at the innermost binding level
 /// into a hash set.
 struct LateBoundRegionsCollector {
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index d9ec6bb20fda8..53521d0e9f332 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -1040,16 +1040,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
     }
 }
 
-pub(super) trait PredicateVisitor<'tcx>: TypeVisitor<'tcx> {
-    fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool;
-}
-
-impl<T: TypeVisitor<'tcx>> PredicateVisitor<'tcx> for T {
-    default fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
-        predicate.super_visit_with(self)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))
diff --git a/compiler/rustc_mir/src/transform/simplify_branches.rs b/compiler/rustc_mir/src/transform/simplify_branches.rs
index 5f63c03993d3a..a9a45e61a38cb 100644
--- a/compiler/rustc_mir/src/transform/simplify_branches.rs
+++ b/compiler/rustc_mir/src/transform/simplify_branches.rs
@@ -49,9 +49,10 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches {
                 }
                 TerminatorKind::Assert {
                     target, cond: Operand::Constant(ref c), expected, ..
-                } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => {
-                    TerminatorKind::Goto { target }
-                }
+                } => match c.literal.try_eval_bool(tcx, param_env) {
+                    Some(v) if v == expected => TerminatorKind::Goto { target },
+                    _ => continue,
+                },
                 TerminatorKind::FalseEdge { real_target, .. } => {
                     TerminatorKind::Goto { target: real_target }
                 }
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index e34277d5af04c..1b17c2c278f9a 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -34,6 +34,7 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
 pub fn opts(arch: Arch) -> TargetOptions {
     TargetOptions {
         cpu: target_cpu(arch),
+        dynamic_linking: false,
         executables: true,
         link_env_remove: link_env_remove(arch),
         has_elf_tls: false,
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b69e19072af44..c039be8f67cda 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -118,6 +118,7 @@
 #![feature(raw_ref_op)]
 #![feature(rustc_attrs)]
 #![feature(receiver_trait)]
+#![feature(renamed_spin_loop)]
 #![feature(min_specialization)]
 #![feature(slice_ptr_get)]
 #![feature(slice_ptr_len)]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 3a83aa7cbe5bd..cd18535b0697d 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -10,6 +10,7 @@ use core::cmp::Ordering;
 use core::convert::{From, TryFrom};
 use core::fmt;
 use core::hash::{Hash, Hasher};
+use core::hint;
 use core::intrinsics::abort;
 use core::iter;
 use core::marker::{PhantomData, Unpin, Unsize};
@@ -764,6 +765,7 @@ impl<T: ?Sized> Arc<T> {
         loop {
             // check if the weak counter is currently "locked"; if so, spin.
             if cur == usize::MAX {
+                hint::spin_loop();
                 cur = this.inner().weak.load(Relaxed);
                 continue;
             }
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index ed8ee2d8823c0..834dd4656ff76 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -529,6 +529,13 @@ mod slice_index {
             message: "out of bounds";
         }
 
+        in mod rangeinclusive_len {
+            data: "abcdef";
+            good: data[0..=5] == "abcdef";
+            bad: data[0..=6];
+            message: "out of bounds";
+        }
+
         in mod range_len_len {
             data: "abcdef";
             good: data[6..6] == "";
@@ -544,6 +551,28 @@ mod slice_index {
         }
     }
 
+    panic_cases! {
+        in mod rangeinclusive_exhausted {
+            data: "abcdef";
+
+            good: data[0..=5] == "abcdef";
+            good: data[{
+                let mut iter = 0..=5;
+                iter.by_ref().count(); // exhaust it
+                iter
+            }] == "";
+
+            // 0..=6 is out of bounds before exhaustion, so it
+            // stands to reason that it still would be after.
+            bad: data[{
+                let mut iter = 0..=6;
+                iter.by_ref().count(); // exhaust it
+                iter
+            }];
+            message: "out of bounds";
+        }
+    }
+
     panic_cases! {
         in mod range_neg_width {
             data: "abcdef";
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index 4423cfc27dd17..1d67e65e51f5f 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -446,6 +446,20 @@ impl<Idx> RangeInclusive<Idx> {
     }
 }
 
+impl RangeInclusive<usize> {
+    /// Converts to an exclusive `Range` for `SliceIndex` implementations.
+    /// The caller is responsible for dealing with `end == usize::MAX`.
+    #[inline]
+    pub(crate) fn into_slice_range(self) -> Range<usize> {
+        // If we're not exhausted, we want to simply slice `start..end + 1`.
+        // If we are exhausted, then slicing with `end + 1..end + 1` gives us an
+        // empty range that is still subject to bounds-checks for that endpoint.
+        let exclusive_end = self.end + 1;
+        let start = if self.exhausted { exclusive_end } else { self.start };
+        start..exclusive_end
+    }
+}
+
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -479,6 +493,16 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// assert!(!(0.0..=f32::NAN).contains(&0.0));
     /// assert!(!(f32::NAN..=1.0).contains(&1.0));
     /// ```
+    ///
+    /// This method always returns `false` after iteration has finished:
+    ///
+    /// ```
+    /// let mut r = 3..=5;
+    /// assert!(r.contains(&3) && r.contains(&5));
+    /// for _ in r.by_ref() {}
+    /// // Precise field values are unspecified here
+    /// assert!(!r.contains(&3) && !r.contains(&5));
+    /// ```
     #[stable(feature = "range_contains", since = "1.35.0")]
     pub fn contains<U>(&self, item: &U) -> bool
     where
@@ -881,7 +905,13 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
         Included(&self.start)
     }
     fn end_bound(&self) -> Bound<&T> {
-        Included(&self.end)
+        if self.exhausted {
+            // When the iterator is exhausted, we usually have start == end,
+            // but we want the range to appear empty, containing nothing.
+            Excluded(&self.end)
+        } else {
+            Included(&self.end)
+        }
     }
 }
 
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 825144e5a6fbe..3daf26208b937 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -562,6 +562,36 @@ impl<T> Option<T> {
         }
     }
 
+    /// Inserts `value` into the option then returns a mutable reference to it.
+    ///
+    /// If the option already contains a value, the old value is dropped.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(option_insert)]
+    ///
+    /// let mut opt = None;
+    /// let val = opt.insert(1);
+    /// assert_eq!(*val, 1);
+    /// assert_eq!(opt.unwrap(), 1);
+    /// let val = opt.insert(2);
+    /// assert_eq!(*val, 2);
+    /// *val = 3;
+    /// assert_eq!(opt.unwrap(), 3);
+    /// ```
+    #[inline]
+    #[unstable(feature = "option_insert", reason = "newly added", issue = "78271")]
+    pub fn insert(&mut self, value: T) -> &mut T {
+        *self = Some(value);
+
+        match self {
+            Some(v) => v,
+            // SAFETY: the code above just filled the option
+            None => unsafe { hint::unreachable_unchecked() },
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Iterator constructors
     /////////////////////////////////////////////////////////////////////////
@@ -792,7 +822,7 @@ impl<T> Option<T> {
     // Entry-like operations to insert if None and return a reference
     /////////////////////////////////////////////////////////////////////////
 
-    /// Inserts `v` into the option if it is [`None`], then
+    /// Inserts `value` into the option if it is [`None`], then
     /// returns a mutable reference to the contained value.
     ///
     /// # Examples
@@ -811,12 +841,12 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
-    pub fn get_or_insert(&mut self, v: T) -> &mut T {
-        self.get_or_insert_with(|| v)
+    pub fn get_or_insert(&mut self, value: T) -> &mut T {
+        self.get_or_insert_with(|| value)
     }
 
-    /// Inserts a value computed from `f` into the option if it is [`None`], then
-    /// returns a mutable reference to the contained value.
+    /// Inserts a value computed from `f` into the option if it is [`None`],
+    /// then returns a mutable reference to the contained value.
     ///
     /// # Examples
     ///
@@ -839,8 +869,8 @@ impl<T> Option<T> {
             *self = Some(f());
         }
 
-        match *self {
-            Some(ref mut v) => v,
+        match self {
+            Some(v) => v,
             // SAFETY: a `None` variant for `self` would have been replaced by a `Some`
             // variant in the code above.
             None => unsafe { hint::unreachable_unchecked() },
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index f1f21c1d24b0b..660c8a2da5da0 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -376,28 +376,24 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
+        if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        if *self.end() == usize::MAX {
-            None
-        } else {
-            (*self.start()..self.end() + 1).get_mut(slice)
-        }
+        if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
-        unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
+        unsafe { self.into_slice_range().get_unchecked(slice) }
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
         // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
-        unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
+        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
     }
 
     #[inline]
@@ -405,7 +401,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
         if *self.end() == usize::MAX {
             slice_end_index_overflow_fail();
         }
-        (*self.start()..self.end() + 1).index(slice)
+        self.into_slice_range().index(slice)
     }
 
     #[inline]
@@ -413,7 +409,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
         if *self.end() == usize::MAX {
             slice_end_index_overflow_fail();
         }
-        (*self.start()..self.end() + 1).index_mut(slice)
+        self.into_slice_range().index_mut(slice)
     }
 }
 
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index af1ce007e8b7c..9cfb5a8998773 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -398,39 +398,35 @@ unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
-        if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
+        if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
     }
     #[inline]
     fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
-        if *self.end() == usize::MAX {
-            None
-        } else {
-            (*self.start()..self.end() + 1).get_mut(slice)
-        }
+        if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
     }
     #[inline]
     unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
         // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
-        unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
+        unsafe { self.into_slice_range().get_unchecked(slice) }
     }
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
         // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
-        unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
+        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
     }
     #[inline]
     fn index(self, slice: &str) -> &Self::Output {
         if *self.end() == usize::MAX {
             str_index_overflow_fail();
         }
-        (*self.start()..self.end() + 1).index(slice)
+        self.into_slice_range().index(slice)
     }
     #[inline]
     fn index_mut(self, slice: &mut str) -> &mut Self::Output {
         if *self.end() == usize::MAX {
             str_index_overflow_fail();
         }
-        (*self.start()..self.end() + 1).index_mut(slice)
+        self.into_slice_range().index_mut(slice)
     }
 }
 
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index ac5c9353ccb46..9ccc5a08dcbea 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -1341,6 +1341,14 @@ mod slice_index {
             message: "out of range";
         }
 
+        in mod rangeinclusive_len {
+            data: [0, 1, 2, 3, 4, 5];
+
+            good: data[0..=5] == [0, 1, 2, 3, 4, 5];
+            bad: data[0..=6];
+            message: "out of range";
+        }
+
         in mod range_len_len {
             data: [0, 1, 2, 3, 4, 5];
 
@@ -1358,6 +1366,28 @@ mod slice_index {
         }
     }
 
+    panic_cases! {
+        in mod rangeinclusive_exhausted {
+            data: [0, 1, 2, 3, 4, 5];
+
+            good: data[0..=5] == [0, 1, 2, 3, 4, 5];
+            good: data[{
+                let mut iter = 0..=5;
+                iter.by_ref().count(); // exhaust it
+                iter
+            }] == [];
+
+            // 0..=6 is out of range before exhaustion, so it
+            // stands to reason that it still would be after.
+            bad: data[{
+                let mut iter = 0..=6;
+                iter.by_ref().count(); // exhaust it
+                iter
+            }];
+            message: "out of range";
+        }
+    }
+
     panic_cases! {
         in mod range_neg_width {
             data: [0, 1, 2, 3, 4, 5];
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index a4bbb18da5983..9b704ee9ecab2 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -346,7 +346,7 @@ mod else_keyword {}
 /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data
 /// is added as the type describes, for example `Option::Some(123)`. The same follows with
 /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff:
-/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be
+/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to [`!`] in that they cannot be
 /// instantiated at all, and are used mainly to mess with the type system in interesting ways.
 ///
 /// For more information, take a look at the [Rust Book] or the [Reference]
@@ -354,6 +354,7 @@ mod else_keyword {}
 /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type
 /// [Rust Book]: ../book/ch06-01-defining-an-enum.html
 /// [Reference]: ../reference/items/enumerations.html
+/// [`!`]: primitive.never.html
 mod enum_keyword {}
 
 #[doc(keyword = "extern")]
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 22cfd0c56431d..3834e50e3fa11 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -232,7 +232,13 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
         match subcommand.as_str() {
             "test" | "t" => {
                 opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
-                opts.optmulti("", "test-args", "extra arguments", "ARGS");
+                opts.optmulti(
+                    "",
+                    "test-args",
+                    "extra arguments to be passed for the test tool being used \
+                        (e.g. libtest, compiletest or rustdoc)",
+                    "ARGS",
+                );
                 opts.optmulti(
                     "",
                     "rustc-args",
diff --git a/src/doc/unstable-book/src/language-features/inline-const.md b/src/doc/unstable-book/src/language-features/inline-const.md
new file mode 100644
index 0000000000000..00e1c79ca3ff3
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/inline-const.md
@@ -0,0 +1,45 @@
+# `inline_const`
+
+The tracking issue for this feature is: [#76001]
+
+------
+
+This feature allows you to use inline constant expressions. For example, you can
+turn this code:
+
+```rust
+# fn add_one(x: i32) -> i32 { x + 1 }
+const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
+
+fn main() {
+    let x = add_one(MY_COMPUTATION);
+}
+```
+
+into this code:
+
+```rust
+#![feature(inline_const)]
+
+# fn add_one(x: i32) -> i32 { x + 1 }
+fn main() {
+    let x = add_one(const { 1 + 2 * 3 / 4 });
+}
+```
+
+You can also use inline constant expressions in patterns:
+
+```rust
+#![feature(inline_const)]
+
+const fn one() -> i32 { 1 }
+
+let some_int = 3;
+match some_int {
+    const { 1 + 2 } => println!("Matched 1 + 2"),
+    const { one() } => println!("Matched const fn returning 1"),
+    _ => println!("Didn't match anything :("),
+}
+```
+
+[#76001]: https://github.com/rust-lang/rust/issues/76001
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index a027d6845ea21..ef734f260afd5 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -94,6 +94,12 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
     var fullNewTheme = newTheme + resourcesSuffix + ".css";
     var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
 
+    // If this new value comes from a system setting or from the previously
+    // saved theme, no need to save it.
+    if (saveTheme === true) {
+        updateLocalStorage("rustdoc-theme", newTheme);
+    }
+
     if (styleElem.href === newHref) {
         return;
     }
@@ -112,11 +118,6 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
     });
     if (found === true) {
         styleElem.href = newHref;
-        // If this new value comes from a system setting or from the previously
-        // saved theme, no need to save it.
-        if (saveTheme === true) {
-            updateLocalStorage("rustdoc-theme", newTheme);
-        }
     }
 }
 
diff --git a/src/test/ui/const-generics/infer/issue-77092.stderr b/src/test/ui/const-generics/infer/issue-77092.stderr
index e84ff8baeea53..63facbf3b8c0f 100644
--- a/src/test/ui/const-generics/infer/issue-77092.stderr
+++ b/src/test/ui/const-generics/infer/issue-77092.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-77092.rs:13:26
    |
 LL |         println!("{:?}", take_array_from_mut(&mut arr, i));
-   |                          ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}`
+   |                          ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/issue-77475.rs b/src/test/ui/macros/issue-77475.rs
new file mode 100644
index 0000000000000..7b32a33ea4f17
--- /dev/null
+++ b/src/test/ui/macros/issue-77475.rs
@@ -0,0 +1,10 @@
+// check-pass
+// Regression test of #77475, this used to be ICE.
+
+#![feature(decl_macro)]
+
+use crate as _;
+
+pub macro ice(){}
+
+fn main() {}