about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock11
-rw-r--r--Cargo.toml2
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs8
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs13
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs15
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs13
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml1
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs21
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs4
-rw-r--r--compiler/rustc_data_structures/src/fingerprint.rs5
-rw-r--r--compiler/rustc_data_structures/src/svh.rs10
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs23
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs2
-rw-r--r--compiler/rustc_infer/src/infer/at.rs3
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs32
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs75
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs7
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs30
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs4
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs3
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs17
-rw-r--r--compiler/rustc_middle/src/ty/util.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs1
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs21
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs5
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/ident.rs72
-rw-r--r--compiler/rustc_resolve/src/late.rs162
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs4
-rw-r--r--compiler/rustc_serialize/src/opaque.rs153
-rw-r--r--compiler/rustc_serialize/src/serialize.rs8
-rw-r--r--compiler/rustc_span/src/lib.rs5
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/string.rs9
-rw-r--r--library/core/src/array/ascii.rs34
-rw-r--r--library/core/src/array/mod.rs1
-rw-r--r--library/core/src/ascii.rs4
-rw-r--r--library/core/src/ascii/ascii_char.rs565
-rw-r--r--library/core/src/char/methods.rs19
-rw-r--r--library/core/src/num/mod.rs11
-rw-r--r--library/core/src/num/nonzero.rs26
-rw-r--r--library/core/src/slice/ascii.rs30
-rw-r--r--library/core/src/str/mod.rs11
-rw-r--r--library/std/src/ascii.rs3
-rw-r--r--library/std/src/sys/common/thread_local/mod.rs5
-rw-r--r--library/std/src/sys/common/thread_local/os_local.rs2
-rw-r--r--library/std/src/thread/mod.rs32
-rw-r--r--library/sysroot/Cargo.toml27
-rw-r--r--library/sysroot/src/lib.rs1
-rw-r--r--library/test/Cargo.toml20
-rw-r--r--library/test/src/formatters/junit.rs40
-rw-r--r--src/bootstrap/check.rs2
-rw-r--r--src/bootstrap/clean.rs2
-rw-r--r--src/bootstrap/compile.rs4
-rw-r--r--src/bootstrap/dist.rs3
-rw-r--r--src/bootstrap/doc.rs2
-rw-r--r--src/bootstrap/test.rs2
-rw-r--r--tests/codegen/ascii-char.rs37
-rw-r--r--tests/incremental/change_crate_dep_kind.rs1
-rw-r--r--tests/incremental/issue-80691-bad-eval-cache.rs1
-rw-r--r--tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff46
-rw-r--r--tests/mir-opt/const_prop/address_of_pair.rs17
-rw-r--r--tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff3
-rw-r--r--tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff3
-rw-r--r--tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff25
-rw-r--r--tests/mir-opt/dead-store-elimination/place_mention.rs9
-rw-r--r--tests/run-make/c-unwind-abi-catch-lib-panic/Makefile1
-rw-r--r--tests/run-make/c-unwind-abi-catch-panic/Makefile1
-rw-r--r--tests/run-make/const_fn_mir/Makefile1
-rw-r--r--tests/run-make/debug-assertions/Makefile1
-rw-r--r--tests/run-make/foreign-double-unwind/Makefile1
-rw-r--r--tests/run-make/foreign-exceptions/Makefile1
-rw-r--r--tests/run-make/foreign-rust-exceptions/Makefile1
-rw-r--r--tests/run-make/libtest-json/Makefile1
-rw-r--r--tests/run-make/libtest-junit/Makefile19
-rw-r--r--tests/run-make/libtest-junit/f.rs23
-rw-r--r--tests/run-make/libtest-junit/output-default.xml1
-rw-r--r--tests/run-make/libtest-junit/output-stdout-success.xml1
-rwxr-xr-xtests/run-make/libtest-junit/validate_junit.py12
-rw-r--r--tests/run-make/static-unwinding/Makefile1
-rw-r--r--tests/run-make/test-benches/Makefile1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs24
-rw-r--r--tests/ui/const-generics/sneaky-array-repeat-expr.rs2
-rw-r--r--tests/ui/const-generics/sneaky-array-repeat-expr.stderr20
-rw-r--r--tests/ui/consts/const-block-const-bound.rs6
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr18
-rw-r--r--tests/ui/consts/issue-50439.rs4
-rw-r--r--tests/ui/consts/issue-50439.stderr10
-rw-r--r--tests/ui/dropck/negative.rs7
-rw-r--r--tests/ui/dropck/negative.stderr8
-rw-r--r--tests/ui/dropck/reservation.rs10
-rw-r--r--tests/ui/dropck/reservation.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs4
-rw-r--r--tests/ui/impl-trait/in-trait/foreign-dyn-error.rs8
-rw-r--r--tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr15
-rw-r--r--tests/ui/impl-trait/in-trait/foreign.rs9
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.rs10
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.stderr14
-rw-r--r--tests/ui/panics/default-backtrace-ice.rs14
-rw-r--r--tests/ui/panics/default-backtrace-ice.stderr5
-rw-r--r--tests/ui/self/elision/nested-item.rs13
-rw-r--r--tests/ui/self/elision/nested-item.stderr38
-rw-r--r--tests/ui/self/self-ctor-inner-const.rs17
-rw-r--r--tests/ui/self/self-ctor-inner-const.stderr33
-rw-r--r--tests/ui/test-attrs/test-type.rs1
-rw-r--r--tests/ui/typeck/repeat-expr-checks-wf.rs10
-rw-r--r--tests/ui/typeck/repeat-expr-checks-wf.stderr12
116 files changed, 1640 insertions, 546 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6519ffa7169..e69b36cb983 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3165,6 +3165,7 @@ dependencies = [
  "rustc_expand",
  "rustc_feature",
  "rustc_fluent_macro",
+ "rustc_index",
  "rustc_lexer",
  "rustc_lint_defs",
  "rustc_macros",
@@ -4739,6 +4740,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "sysroot"
+version = "0.0.0"
+dependencies = [
+ "proc_macro",
+ "std",
+ "test",
+]
+
+[[package]]
 name = "tar"
 version = "0.4.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4822,7 +4832,6 @@ dependencies = [
  "getopts",
  "panic_abort",
  "panic_unwind",
- "proc_macro",
  "std",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index a497d7321e0..7aaa34a68e6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,7 @@
 members = [
   "compiler/rustc",
   "library/std",
-  "library/test",
+  "library/sysroot",
   "src/rustdoc-json-types",
   "src/tools/build_helper",
   "src/tools/cargotest",
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index 6259722b694..74e6ce37e97 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -54,7 +54,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
 
         // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
         // contain dangling references.
-        PlaceContext::NonUse(NonUseContext::PlaceMention) |
+        PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
         PlaceContext::NonUse(NonUseContext::AscribeUserTy) |
 
         PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index c4c54620e04..315303b25fe 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -498,11 +498,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
         let next_region = self.infcx.next_region_var(origin);
         let vid = next_region.as_var();
 
-        if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
             let ctxt = get_ctxt_fn();
             let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(vid, ctxt);
+            assert_eq!(var_to_origin.insert(vid, ctxt), None);
         }
 
         next_region
@@ -520,11 +520,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
         let next_region = self.infcx.next_nll_region_var(origin);
         let vid = next_region.as_var();
 
-        if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
             let ctxt = get_ctxt_fn();
             let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(vid, ctxt);
+            assert_eq!(var_to_origin.insert(vid, ctxt), None);
         }
 
         next_region
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 65573c71f14..8fbe814c856 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -76,7 +76,7 @@ pub struct RegionInferenceContext<'tcx> {
     /// Reverse of the SCC constraint graph --  i.e., an edge `A -> B` exists if
     /// `B: A`. This is used to compute the universal regions that are required
     /// to outlive a given SCC. Computed lazily.
-    rev_scc_graph: Option<Rc<ReverseSccGraph>>,
+    rev_scc_graph: Option<ReverseSccGraph>,
 
     /// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
     member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
@@ -813,9 +813,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // free region that must outlive the member region `R0` (`UB:
         // R0`). Therefore, we need only keep an option `O` if `UB: O`
         // for all UB.
-        let rev_scc_graph = self.reverse_scc_graph();
+        self.compute_reverse_scc_graph();
         let universal_region_relations = &self.universal_region_relations;
-        for ub in rev_scc_graph.upper_bounds(scc) {
+        for ub in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
             debug!(?ub);
             choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r));
         }
diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
index 23a59c12865..fe56bd54a3f 100644
--- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
@@ -8,7 +8,6 @@ use rustc_data_structures::graph::vec_graph::VecGraph;
 use rustc_data_structures::graph::WithSuccessors;
 use rustc_middle::ty::RegionVid;
 use std::ops::Range;
-use std::rc::Rc;
 
 pub(crate) struct ReverseSccGraph {
     graph: VecGraph<ConstraintSccIndex>,
@@ -40,10 +39,10 @@ impl ReverseSccGraph {
 }
 
 impl RegionInferenceContext<'_> {
-    /// Compute and return the reverse SCC-based constraint graph (lazily).
-    pub(super) fn reverse_scc_graph(&mut self) -> Rc<ReverseSccGraph> {
-        if let Some(g) = &self.rev_scc_graph {
-            return g.clone();
+    /// Compute the reverse SCC-based constraint graph (lazily).
+    pub(super) fn compute_reverse_scc_graph(&mut self) {
+        if self.rev_scc_graph.is_some() {
+            return;
         }
 
         let graph = self.constraint_sccs.reverse();
@@ -63,8 +62,6 @@ impl RegionInferenceContext<'_> {
             start += group_size;
         }
 
-        let rev_graph = Rc::new(ReverseSccGraph { graph, scc_regions, universal_regions });
-        self.rev_scc_graph = Some(rev_graph.clone());
-        rev_graph
+        self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions });
     }
 }
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 22de7549e94..4389d2b60bc 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -109,6 +109,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
+    fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, location: Location) {
+        let old_ct = *ct;
+        *ct = self.renumber_regions(old_ct, || RegionCtxt::Location(location));
+
+        debug!(?ct);
+    }
+
+    #[instrument(skip(self), level = "debug")]
     fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) {
         let literal = constant.literal;
         constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(location));
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 601589480d1..dcabeb792be 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -772,12 +772,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
         match context {
             PlaceContext::MutatingUse(_) => ty::Invariant,
-            PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => {
-                ty::Invariant
-            }
+            PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
             PlaceContext::NonMutatingUse(
-                Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf
-                | Projection,
+                Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow
+                | AddressOf | Projection,
             ) => ty::Covariant,
             PlaceContext::NonUse(AscribeUserTy) => ty::Covariant,
         }
@@ -1803,6 +1801,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Rvalue::Repeat(operand, len) => {
                 self.check_operand(operand, location);
 
+                let array_ty = rvalue.ty(body.local_decls(), tcx);
+                self.prove_predicate(
+                    ty::PredicateKind::WellFormed(array_ty.into()),
+                    Locations::Single(location),
+                    ConstraintCategory::Boring,
+                );
+
                 // If the length cannot be evaluated we must assume that the length can be larger
                 // than 1.
                 // If the length is larger than 1, the repeat expression will need to copy the
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 7e6d17ec343..7158c62b548 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -131,9 +131,13 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
         };
 
-        if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(reg.as_var(), RegionCtxt::Placeholder(reg_info));
+            let new = RegionCtxt::Placeholder(reg_info);
+            let prev = var_to_origin.insert(reg.as_var(), new);
+            if let Some(prev) = prev {
+                assert_eq!(new, prev);
+            }
         }
 
         reg
@@ -146,9 +150,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             universe,
         );
 
-        if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
+        if cfg!(debug_assertions) {
             let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
-            var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None));
+            let prev = var_to_origin.insert(reg.as_var(), RegionCtxt::Existential(None));
+            assert_eq!(prev, None);
         }
 
         reg
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index 5f6441660e3..44012e802aa 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -14,6 +14,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_expand = { path = "../rustc_expand" }
 rustc_feature = { path = "../rustc_feature" }
+rustc_index = { path = "../rustc_index" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index ac817d9a152..bb059a120df 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -2,9 +2,10 @@ use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter};
 use rustc_ast::tokenstream::TokenStream;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::PResult;
 use rustc_expand::base::{self, *};
+use rustc_index::bit_set::GrowableBitSet;
 use rustc_parse::parser::Parser;
 use rustc_parse_format as parse;
 use rustc_session::lint;
@@ -20,8 +21,8 @@ use crate::errors;
 pub struct AsmArgs {
     pub templates: Vec<P<ast::Expr>>,
     pub operands: Vec<(ast::InlineAsmOperand, Span)>,
-    named_args: FxHashMap<Symbol, usize>,
-    reg_args: FxHashSet<usize>,
+    named_args: FxIndexMap<Symbol, usize>,
+    reg_args: GrowableBitSet<usize>,
     pub clobber_abis: Vec<(Symbol, Span)>,
     options: ast::InlineAsmOptions,
     pub options_spans: Vec<Span>,
@@ -56,8 +57,8 @@ pub fn parse_asm_args<'a>(
     let mut args = AsmArgs {
         templates: vec![first_template],
         operands: vec![],
-        named_args: FxHashMap::default(),
-        reg_args: FxHashSet::default(),
+        named_args: Default::default(),
+        reg_args: Default::default(),
         clobber_abis: Vec::new(),
         options: ast::InlineAsmOptions::empty(),
         options_spans: vec![],
@@ -213,7 +214,7 @@ pub fn parse_asm_args<'a>(
         } else {
             if !args.named_args.is_empty() || !args.reg_args.is_empty() {
                 let named = args.named_args.values().map(|p| args.operands[*p].1).collect();
-                let explicit = args.reg_args.iter().map(|p| args.operands[*p].1).collect();
+                let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect();
 
                 diag.emit_err(errors::AsmPositionalAfter { span, named, explicit });
             }
@@ -446,8 +447,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
     // Register operands are implicitly used since they are not allowed to be
     // referenced in the template string.
     let mut used = vec![false; args.operands.len()];
-    for pos in &args.reg_args {
-        used[*pos] = true;
+    for pos in args.reg_args.iter() {
+        used[pos] = true;
     }
     let named_pos: FxHashMap<usize, Symbol> =
         args.named_args.iter().map(|(&sym, &idx)| (idx, sym)).collect();
@@ -581,7 +582,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                         parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
                             if idx >= args.operands.len()
                                 || named_pos.contains_key(&idx)
-                                || args.reg_args.contains(&idx)
+                                || args.reg_args.contains(idx)
                             {
                                 let msg = format!("invalid reference to argument at index {}", idx);
                                 let mut err = ecx.struct_span_err(span, &msg);
@@ -608,7 +609,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                                         args.operands[idx].1,
                                         "named arguments cannot be referenced by position",
                                     );
-                                } else if args.reg_args.contains(&idx) {
+                                } else if args.reg_args.contains(idx) {
                                     err.span_label(
                                         args.operands[idx].1,
                                         "explicit register argument",
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 8f86ef44aa3..c7da61d72b3 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -1,7 +1,6 @@
 //! This crate contains implementations of built-in macros and other code generating facilities
 //! injecting code into the crate before it is lowered to HIR.
 
-#![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(array_windows)]
 #![feature(box_patterns)]
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 0334c7ff132..569599faa36 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -203,7 +203,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
                 self.assign(local, DefLocation::Body(location));
             }
 
-            PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
+            PlaceContext::NonUse(_)
+            | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention)
+            | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
 
             PlaceContext::NonMutatingUse(
                 NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs
index 6fa76981408..9995c08345c 100644
--- a/compiler/rustc_data_structures/src/fingerprint.rs
+++ b/compiler/rustc_data_structures/src/fingerprint.rs
@@ -64,6 +64,11 @@ impl Fingerprint {
         )
     }
 
+    #[inline]
+    pub(crate) fn as_u128(self) -> u128 {
+        u128::from(self.1) << 64 | u128::from(self.0)
+    }
+
     // Combines two hashes in an order independent way. Make sure this is what
     // you want.
     #[inline]
diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs
index a3d2724fcdb..71679086f16 100644
--- a/compiler/rustc_data_structures/src/svh.rs
+++ b/compiler/rustc_data_structures/src/svh.rs
@@ -23,18 +23,18 @@ impl Svh {
         Svh { hash }
     }
 
-    pub fn as_u64(&self) -> u64 {
-        self.hash.to_smaller_hash().as_u64()
+    pub fn as_u128(self) -> u128 {
+        self.hash.as_u128()
     }
 
-    pub fn to_string(&self) -> String {
-        format!("{:016x}", self.hash.to_smaller_hash())
+    pub fn to_hex(self) -> String {
+        format!("{:032x}", self.hash.as_u128())
     }
 }
 
 impl fmt::Display for Svh {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.pad(&self.to_string())
+        f.pad(&self.to_hex())
     }
 }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 283e68a68b5..1c222fb4a89 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -88,6 +88,7 @@ use rustc_span::Span;
 use std::borrow::Cow;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::fmt::Display;
+use std::rc::Rc;
 
 /// A unit within a matcher that a `MatcherPos` can refer to. Similar to (and derived from)
 /// `mbe::TokenTree`, but designed specifically for fast and easy traversal during matching.
@@ -257,10 +258,10 @@ struct MatcherPos {
     /// against the relevant metavar by the black box parser. An element will be a `MatchedSeq` if
     /// the corresponding metavar decl is within a sequence.
     ///
-    /// It is critical to performance that this is an `Lrc`, because it gets cloned frequently when
+    /// It is critical to performance that this is an `Rc`, because it gets cloned frequently when
     /// processing sequences. Mostly for sequence-ending possibilities that must be tried but end
     /// up failing.
-    matches: Lrc<Vec<NamedMatch>>,
+    matches: Rc<Vec<NamedMatch>>,
 }
 
 // This type is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -272,7 +273,7 @@ impl MatcherPos {
     /// and both are hot enough to be always worth inlining.
     #[inline(always)]
     fn push_match(&mut self, metavar_idx: usize, seq_depth: usize, m: NamedMatch) {
-        let matches = Lrc::make_mut(&mut self.matches);
+        let matches = Rc::make_mut(&mut self.matches);
         match seq_depth {
             0 => {
                 // We are not within a sequence. Just append `m`.
@@ -427,7 +428,7 @@ pub struct TtParser {
 
     /// Pre-allocate an empty match array, so it can be cloned cheaply for macros with many rules
     /// that have no metavars.
-    empty_matches: Lrc<Vec<NamedMatch>>,
+    empty_matches: Rc<Vec<NamedMatch>>,
 }
 
 impl TtParser {
@@ -437,7 +438,7 @@ impl TtParser {
             cur_mps: vec![],
             next_mps: vec![],
             bb_mps: vec![],
-            empty_matches: Lrc::new(vec![]),
+            empty_matches: Rc::new(vec![]),
         }
     }
 
@@ -507,7 +508,7 @@ impl TtParser {
                         // Try zero matches of this sequence, by skipping over it.
                         self.cur_mps.push(MatcherPos {
                             idx: idx_first_after,
-                            matches: Lrc::clone(&mp.matches),
+                            matches: Rc::clone(&mp.matches),
                         });
                     }
 
@@ -521,7 +522,7 @@ impl TtParser {
                     // processed next time around the loop.
                     let ending_mp = MatcherPos {
                         idx: mp.idx + 1, // +1 skips the Kleene op
-                        matches: Lrc::clone(&mp.matches),
+                        matches: Rc::clone(&mp.matches),
                     };
                     self.cur_mps.push(ending_mp);
 
@@ -537,7 +538,7 @@ impl TtParser {
                     // will fail quietly when it is processed next time around the loop.
                     let ending_mp = MatcherPos {
                         idx: mp.idx + 2, // +2 skips the separator and the Kleene op
-                        matches: Lrc::clone(&mp.matches),
+                        matches: Rc::clone(&mp.matches),
                     };
                     self.cur_mps.push(ending_mp);
 
@@ -587,9 +588,9 @@ impl TtParser {
         if *token == token::Eof {
             Some(match eof_mps {
                 EofMatcherPositions::One(mut eof_mp) => {
-                    // Need to take ownership of the matches from within the `Lrc`.
-                    Lrc::make_mut(&mut eof_mp.matches);
-                    let matches = Lrc::try_unwrap(eof_mp.matches).unwrap().into_iter();
+                    // Need to take ownership of the matches from within the `Rc`.
+                    Rc::make_mut(&mut eof_mp.matches);
+                    let matches = Rc::try_unwrap(eof_mp.matches).unwrap().into_iter();
                     self.nameize(matcher, matches)
                 }
                 EofMatcherPositions::Multiple => {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index e4f225bdad7..eaa75bde6c6 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -280,3 +280,7 @@ hir_analysis_const_specialize = cannot specialize on const impl with non-const i
 hir_analysis_static_specialize = cannot specialize on `'static` lifetime
 
 hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization
+
+hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
+
+hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 64dff8e68b8..bae80807f71 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -1,7 +1,6 @@
 // FIXME(@lcnr): Move this module out of `rustc_hir_analysis`.
 //
 // We don't do any drop checking during hir typeck.
-use crate::hir::def_id::{DefId, LocalDefId};
 use rustc_errors::{struct_span_err, ErrorGuaranteed};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
@@ -9,6 +8,9 @@ use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::util::IgnoreRegions;
 use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
 
+use crate::errors;
+use crate::hir::def_id::{DefId, LocalDefId};
+
 /// This function confirms that the `Drop` implementation identified by
 /// `drop_impl_did` is not any more specialized than the type it is
 /// attached to (Issue #8142).
@@ -27,6 +29,19 @@ use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
 ///
 pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> {
+    match tcx.impl_polarity(drop_impl_did) {
+        ty::ImplPolarity::Positive => {}
+        ty::ImplPolarity::Negative => {
+            return Err(tcx.sess.emit_err(errors::DropImplPolarity::Negative {
+                span: tcx.def_span(drop_impl_did),
+            }));
+        }
+        ty::ImplPolarity::Reservation => {
+            return Err(tcx.sess.emit_err(errors::DropImplPolarity::Reservation {
+                span: tcx.def_span(drop_impl_did),
+            }));
+        }
+    }
     let dtor_self_type = tcx.type_of(drop_impl_did).subst_identity();
     let dtor_predicates = tcx.predicates_of(drop_impl_did);
     match dtor_self_type.kind() {
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 25ad1bed763..c0ee777722e 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -823,3 +823,17 @@ pub(crate) struct MissingTildeConst {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+pub(crate) enum DropImplPolarity {
+    #[diag(hir_analysis_drop_impl_negative)]
+    Negative {
+        #[primary_span]
+        span: Span,
+    },
+    #[diag(hir_analysis_drop_impl_reservation)]
+    Reservation {
+        #[primary_span]
+        span: Span,
+    },
+}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 047d8a82bfc..bba049c3819 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1426,6 +1426,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.check_repeat_element_needs_copy_bound(element, count, element_ty);
 
+        self.register_wf_obligation(
+            tcx.mk_array_with_const_len(t, count).into(),
+            expr.span,
+            traits::WellFormed(None),
+        );
+
         tcx.mk_array_with_const_len(t, count)
     }
 
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index ec6d61f9e5f..e3c688b3e98 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -346,7 +346,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
     let mut new_sub_dir_name = String::from(&old_sub_dir_name[..=dash_indices[2]]);
 
     // Append the svh
-    base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name);
+    base_n::push_str(svh.as_u128(), INT_ENCODE_BASE, &mut new_sub_dir_name);
 
     // Create the full path
     let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name);
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index d240d8e491f..0c8854e962a 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -30,8 +30,6 @@ use super::*;
 use rustc_middle::ty::relate::{Relate, TypeRelation};
 use rustc_middle::ty::{Const, ImplSubject};
 
-use std::cell::Cell;
-
 /// Whether we should define opaque types or just treat them opaquely.
 ///
 /// Currently only used to prevent predicate matching from matching anything
@@ -84,7 +82,6 @@ impl<'tcx> InferCtxt<'tcx> {
             in_snapshot: self.in_snapshot.clone(),
             universe: self.universe.clone(),
             intercrate: self.intercrate,
-            inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index d798202a644..427d05c8b4d 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -561,8 +561,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     where
         V: TypeFoldable<TyCtxt<'tcx>>,
     {
-        let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();
-
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::HAS_INFER |
             TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1cfdb791cd6..a89b9931599 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -39,7 +39,6 @@ use rustc_span::Span;
 
 use std::cell::{Cell, RefCell};
 use std::fmt;
-use std::ops::Drop;
 
 use self::combine::CombineFields;
 use self::error_reporting::TypeErrCtxt;
@@ -342,11 +341,6 @@ pub struct InferCtxt<'tcx> {
     /// there is no type that the user could *actually name* that
     /// would satisfy it. This avoids crippling inference, basically.
     pub intercrate: bool,
-
-    /// Flag that is set when we enter canonicalization. Used for debugging to ensure
-    /// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin`
-    /// inside non-canonicalization contexts.
-    inside_canonicalization_ctxt: Cell<bool>,
 }
 
 /// See the `error_reporting` module for more details.
@@ -638,7 +632,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             skip_leak_check: Cell::new(false),
             universe: Cell::new(ty::UniverseIndex::ROOT),
             intercrate,
-            inside_canonicalization_ctxt: Cell::new(false),
         }
     }
 }
@@ -1636,31 +1629,6 @@ impl<'tcx> InferCtxt<'tcx> {
             }
         }
     }
-
-    pub fn inside_canonicalization_ctxt(&self) -> bool {
-        self.inside_canonicalization_ctxt.get()
-    }
-
-    pub fn set_canonicalization_ctxt(&self) -> CanonicalizationCtxtGuard<'_, 'tcx> {
-        let prev_ctxt = self.inside_canonicalization_ctxt();
-        self.inside_canonicalization_ctxt.set(true);
-        CanonicalizationCtxtGuard { prev_ctxt, infcx: self }
-    }
-
-    fn set_canonicalization_ctxt_to(&self, ctxt: bool) {
-        self.inside_canonicalization_ctxt.set(ctxt);
-    }
-}
-
-pub struct CanonicalizationCtxtGuard<'cx, 'tcx> {
-    prev_ctxt: bool,
-    infcx: &'cx InferCtxt<'tcx>,
-}
-
-impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> {
-    fn drop(&mut self) {
-        self.infcx.set_canonicalization_ctxt_to(self.prev_ctxt)
-    }
 }
 
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 9f7b26b87f4..88a0a81e276 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -30,11 +30,10 @@ use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
 use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
-use std::ops::ControlFlow;
 
 use super::combine::ObligationEmittingRelation;
 
@@ -115,11 +114,6 @@ pub trait TypeRelatingDelegate<'tcx> {
     fn forbid_inference_vars() -> bool;
 }
 
-#[derive(Clone, Debug, Default)]
-struct BoundRegionScope<'tcx> {
-    map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
-}
-
 #[derive(Copy, Clone)]
 struct UniversallyQuantified(bool);
 
@@ -230,10 +224,13 @@ where
     ) -> RelateResult<'tcx, T> {
         let universe = self.infcx.probe_ty_var(for_vid).unwrap_err();
 
+        if value.has_escaping_bound_vars() {
+            bug!("trying to instantiate {for_vid:?} with escaping bound vars: {value:?}");
+        }
+
         let mut generalizer = TypeGeneralizer {
             infcx: self.infcx,
             delegate: &mut self.delegate,
-            first_free_index: ty::INNERMOST,
             ambient_variance: self.ambient_variance,
             for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid),
             universe,
@@ -488,13 +485,7 @@ where
         }
 
         if a == b {
-            // Subtle: if a or b has a bound variable that we are lazily
-            // substituting, then even if a == b, it could be that the values we
-            // will substitute for those bound variables are *not* the same, and
-            // hence returning `Ok(a)` is incorrect.
-            if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
-                return Ok(a);
-            }
+            return Ok(a);
         }
 
         match (a.kind(), b.kind()) {
@@ -726,47 +717,6 @@ where
     }
 }
 
-/// When we encounter a binder like `for<..> fn(..)`, we actually have
-/// to walk the `fn` value to find all the values bound by the `for`
-/// (these are not explicitly present in the ty representation right
-/// now). This visitor handles that: it descends the type, tracking
-/// binder depth, and finds late-bound regions targeting the
-/// `for<..`>. For each of those, it creates an entry in
-/// `bound_region_scope`.
-struct ScopeInstantiator<'me, 'tcx> {
-    next_region: &'me mut dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
-    // The debruijn index of the scope we are instantiating.
-    target_index: ty::DebruijnIndex,
-    bound_region_scope: &'me mut BoundRegionScope<'tcx>,
-}
-
-impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> ControlFlow<Self::BreakTy> {
-        self.target_index.shift_in(1);
-        t.super_visit_with(self);
-        self.target_index.shift_out(1);
-
-        ControlFlow::Continue(())
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
-        let ScopeInstantiator { bound_region_scope, next_region, .. } = self;
-
-        match *r {
-            ty::ReLateBound(debruijn, br) if debruijn == self.target_index => {
-                bound_region_scope.map.entry(br).or_insert_with(|| next_region(br));
-            }
-
-            _ => {}
-        }
-
-        ControlFlow::Continue(())
-    }
-}
-
 /// The "type generalizer" is used when handling inference variables.
 ///
 /// The basic strategy for handling a constraint like `?A <: B` is to
@@ -780,11 +730,6 @@ impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> {
 /// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
 /// establishes `'0: 'x` as a constraint.
 ///
-/// As a side-effect of this generalization procedure, we also replace
-/// all the bound regions that we have traversed with concrete values,
-/// so that the resulting generalized type is independent from the
-/// scopes.
-///
 /// [blog post]: https://is.gd/0hKvIr
 struct TypeGeneralizer<'me, 'tcx, D>
 where
@@ -798,8 +743,6 @@ where
     /// some other type. What will be the variance at this point?
     ambient_variance: ty::Variance,
 
-    first_free_index: ty::DebruijnIndex,
-
     /// The vid of the type variable that is in the process of being
     /// instantiated. If we find this within the value we are folding,
     /// that means we would have created a cyclic value.
@@ -939,7 +882,7 @@ where
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("TypeGeneralizer::regions(a={:?})", a);
 
-        if let ty::ReLateBound(debruijn, _) = *a && debruijn < self.first_free_index {
+        if let ty::ReLateBound(..) = *a {
             return Ok(a);
         }
 
@@ -958,7 +901,6 @@ where
         // FIXME(#54105) -- if the ambient variance is bivariant,
         // though, we may however need to check well-formedness or
         // risk a problem like #41677 again.
-
         let replacement_region_vid = self.delegate.generalize_existential(self.universe);
 
         Ok(replacement_region_vid)
@@ -1002,10 +944,7 @@ where
         T: Relate<'tcx>,
     {
         debug!("TypeGeneralizer::binders(a={:?})", a);
-
-        self.first_free_index.shift_in(1);
         let result = self.relate(a.skip_binder(), a.skip_binder())?;
-        self.first_free_index.shift_out(1);
         Ok(a.rebind(result))
     }
 }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 3253d0a9057..82c66b9dfb9 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -108,11 +108,7 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
         emit_i64(i64);
         emit_i32(i32);
         emit_i16(i16);
-        emit_i8(i8);
 
-        emit_bool(bool);
-        emit_char(char);
-        emit_str(&str);
         emit_raw_bytes(&[u8]);
     }
 }
@@ -837,11 +833,12 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::AnonConst
         | DefKind::InlineConst
         | DefKind::OpaqueTy
+        | DefKind::ImplTraitPlaceholder
         | DefKind::Field
         | DefKind::Impl { .. }
         | DefKind::Closure
         | DefKind::Generator => true,
-        DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false,
+        DefKind::ForeignMod | DefKind::GlobalAsm => false,
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 0a9fcd898b9..6718605ed0b 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -192,6 +192,14 @@ macro_rules! make_mir_visitor {
                 self.super_constant(constant, location);
             }
 
+            fn visit_ty_const(
+                &mut self,
+                ct: $( & $mutability)? ty::Const<'tcx>,
+                location: Location,
+            ) {
+                self.super_ty_const(ct, location);
+            }
+
             fn visit_span(
                 &mut self,
                 span: $(& $mutability)? Span,
@@ -410,7 +418,7 @@ macro_rules! make_mir_visitor {
                     StatementKind::PlaceMention(place) => {
                         self.visit_place(
                             place,
-                            PlaceContext::NonUse(NonUseContext::PlaceMention),
+                            PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention),
                             location
                         );
                     }
@@ -625,8 +633,9 @@ macro_rules! make_mir_visitor {
                         self.visit_operand(operand, location);
                     }
 
-                    Rvalue::Repeat(value, _) => {
+                    Rvalue::Repeat(value, ct) => {
                         self.visit_operand(value, location);
+                        self.visit_ty_const($(&$mutability)? *ct, location);
                     }
 
                     Rvalue::ThreadLocalRef(_) => {}
@@ -878,12 +887,20 @@ macro_rules! make_mir_visitor {
                 self.visit_span($(& $mutability)? *span);
                 drop(user_ty); // no visit method for this
                 match literal {
-                    ConstantKind::Ty(_) => {}
+                    ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
                     ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
                     ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
                 }
             }
 
+            fn super_ty_const(
+                &mut self,
+                _ct: $(& $mutability)? ty::Const<'tcx>,
+                _location: Location,
+            ) {
+
+            }
+
             fn super_span(&mut self, _span: $(& $mutability)? Span) {
             }
 
@@ -1251,6 +1268,11 @@ pub enum NonMutatingUseContext {
     UniqueBorrow,
     /// AddressOf for *const pointer.
     AddressOf,
+    /// PlaceMention statement.
+    ///
+    /// This statement is executed as a check that the `Place` is live without reading from it,
+    /// so it must be considered as a non-mutating use.
+    PlaceMention,
     /// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
     /// For example, the projection `x.y` is not marked as a mutation in these cases:
     /// ```ignore (illustrative)
@@ -1301,8 +1323,6 @@ pub enum NonUseContext {
     AscribeUserTy,
     /// The data of a user variable, for debug info.
     VarDebugInfo,
-    /// PlaceMention statement.
-    PlaceMention,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index e56faff5ed4..220118ae5cc 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -1026,11 +1026,7 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
         emit_i64(i64);
         emit_i32(i32);
         emit_i16(i16);
-        emit_i8(i8);
 
-        emit_bool(bool);
-        emit_char(char);
-        emit_str(&str);
         emit_raw_bytes(&[u8]);
     }
 }
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 029cf793ad8..bfb740ab356 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -63,7 +63,8 @@ impl<'tcx> TyCtxt<'tcx> {
                         Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e),
                         Ok(Some(bac)) => {
                             let substs = self.tcx.erase_regions(uv.substs);
-                            bac.subst(self.tcx, substs)
+                            let bac = bac.subst(self.tcx, substs);
+                            return bac.fold_with(self);
                         }
                         Ok(None) => c,
                     },
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 7536903ef96..7fc75674da5 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -506,23 +506,18 @@ macro_rules! implement_ty_decoder {
 
             impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
                 $crate::__impl_decoder_methods! {
+                    read_usize -> usize;
                     read_u128 -> u128;
                     read_u64 -> u64;
                     read_u32 -> u32;
                     read_u16 -> u16;
                     read_u8 -> u8;
-                    read_usize -> usize;
 
+                    read_isize -> isize;
                     read_i128 -> i128;
                     read_i64 -> i64;
                     read_i32 -> i32;
                     read_i16 -> i16;
-                    read_i8 -> i8;
-                    read_isize -> isize;
-
-                    read_bool -> bool;
-                    read_char -> char;
-                    read_str -> &str;
                 }
 
                 #[inline]
@@ -531,13 +526,13 @@ macro_rules! implement_ty_decoder {
                 }
 
                 #[inline]
-                fn position(&self) -> usize {
-                    self.opaque.position()
+                fn peek_byte(&self) -> u8 {
+                    self.opaque.peek_byte()
                 }
 
                 #[inline]
-                fn peek_byte(&self) -> u8 {
-                    self.opaque.peek_byte()
+                fn position(&self) -> usize {
+                    self.opaque.position()
                 }
             }
         }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index c77985c6bd6..e5b2d342452 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -360,16 +360,16 @@ impl<'tcx> TyCtxt<'tcx> {
         let ty = self.type_of(adt_did).subst_identity();
         let mut dtor_candidate = None;
         self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
-            let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
-                self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function");
-                return;
-            };
-
             if validate(self, impl_did).is_err() {
                 // Already `ErrorGuaranteed`, no need to delay a span bug here.
                 return;
             }
 
+            let Some(item_id) = self.associated_item_def_ids(impl_did).first() else {
+                self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function");
+                return;
+            };
+
             if let Some((old_item_id, _)) = dtor_candidate {
                 self.sess
                     .struct_span_err(self.def_span(item_id), "multiple drop impls found")
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index bc67aa476f1..aeca0073304 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -197,6 +197,7 @@ impl DefUse {
                 | NonMutatingUseContext::Copy
                 | NonMutatingUseContext::Inspect
                 | NonMutatingUseContext::Move
+                | NonMutatingUseContext::PlaceMention
                 | NonMutatingUseContext::ShallowBorrow
                 | NonMutatingUseContext::SharedBorrow
                 | NonMutatingUseContext::UniqueBorrow,
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index deec66bbaf3..7f995c69a48 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -714,13 +714,22 @@ impl CanConstProp {
     }
 }
 
-impl Visitor<'_> for CanConstProp {
+impl<'tcx> Visitor<'tcx> for CanConstProp {
+    fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) {
+        use rustc_middle::mir::visit::PlaceContext::*;
+
+        // Dereferencing just read the addess of `place.local`.
+        if place.projection.first() == Some(&PlaceElem::Deref) {
+            context = NonMutatingUse(NonMutatingUseContext::Copy);
+        }
+
+        self.visit_local(place.local, context, loc);
+        self.visit_projection(place.as_ref(), context, loc);
+    }
+
     fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
         use rustc_middle::mir::visit::PlaceContext::*;
         match context {
-            // Projections are fine, because `&mut foo.x` will be caught by
-            // `MutatingUseContext::Borrow` elsewhere.
-            MutatingUse(MutatingUseContext::Projection)
             // These are just stores, where the storing is not propagatable, but there may be later
             // mutations of the same local via `Store`
             | MutatingUse(MutatingUseContext::Call)
@@ -751,7 +760,7 @@ impl Visitor<'_> for CanConstProp {
             NonMutatingUse(NonMutatingUseContext::Copy)
             | NonMutatingUse(NonMutatingUseContext::Move)
             | NonMutatingUse(NonMutatingUseContext::Inspect)
-            | NonMutatingUse(NonMutatingUseContext::Projection)
+            | NonMutatingUse(NonMutatingUseContext::PlaceMention)
             | NonUse(_) => {}
 
             // These could be propagated with a smarter analysis or just some careful thinking about
@@ -770,6 +779,8 @@ impl Visitor<'_> for CanConstProp {
                 trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
                 self.can_const_prop[local] = ConstPropMode::NoPropagation;
             }
+            MutatingUse(MutatingUseContext::Projection)
+            | NonMutatingUse(NonMutatingUseContext::Projection) => bug!("visit_place should not pass {context:?} for {local:?}"),
         }
     }
 }
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 9dd39a5c9fe..72371b9950b 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -2,6 +2,7 @@
 
 use hir::CRATE_HIR_ID;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
 use rustc_expand::base::resolve_path;
 use rustc_hir as hir;
 use rustc_hir::HirId;
@@ -9,8 +10,6 @@ use rustc_middle::ty::TyCtxt;
 use rustc_middle::{query::LocalCrate, ty::query::Providers};
 use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType};
 
-use std::sync::Arc;
-
 use crate::errors::DebugVisualizerUnreadable;
 
 fn check_for_debugger_visualizer(
@@ -52,7 +51,7 @@ fn check_for_debugger_visualizer(
             match std::fs::read(&file) {
                 Ok(contents) => {
                     debugger_visualizers
-                        .insert(DebuggerVisualizerFile::new(Arc::from(contents), visualizer_type));
+                        .insert(DebuggerVisualizerFile::new(Lrc::from(contents), visualizer_type));
                 }
                 Err(error) => {
                     tcx.sess.emit_err(DebugVisualizerUnreadable {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index fd263bab78f..fae7d549592 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -550,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                 let sm = self.tcx.sess.source_map();
                 let def_id = match outer_res {
-                    Res::SelfTyParam { .. } => {
+                    Res::SelfTyParam { .. } | Res::SelfCtor(_) => {
                         err.span_label(span, "can't use `Self` here");
                         return err;
                     }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 530c188fe18..2db1d83d4fd 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -24,7 +24,6 @@ use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding,
 
 use Determinacy::*;
 use Namespace::*;
-use RibKind::*;
 
 type Visibility = ty::Visibility<LocalDefId>;
 
@@ -324,8 +323,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
 
             module = match ribs[i].kind {
-                ModuleRibKind(module) => module,
-                MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
+                RibKind::Module(module) => module,
+                RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
                     // If an invocation of this macro created `ident`, give up on `ident`
                     // and switch to `ident`'s source from the macro definition.
                     ident.span.remove_mark();
@@ -1084,7 +1083,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let ribs = &all_ribs[rib_index + 1..];
 
         // An invalid forward use of a generic parameter from a previous default.
-        if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind {
+        if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
             if let Some(span) = finalize {
                 let res_error = if rib_ident.name == kw::SelfUpper {
                     ResolutionError::SelfInGenericParamDefault
@@ -1104,14 +1103,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                 for rib in ribs {
                     match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | ForwardGenericParamBanRibKind => {
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                         }
-                        ItemRibKind(_) | AssocItemRibKind => {
+                        RibKind::Item(_) | RibKind::AssocItem => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
@@ -1123,7 +1122,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
                             }
                         }
-                        ConstantItemRibKind(_, item) => {
+                        RibKind::ConstantItem(_, item) => {
                             // Still doesn't deal with upvars
                             if let Some(span) = finalize {
                                 let (span, resolution_error) =
@@ -1152,13 +1151,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             }
                             return Res::Err;
                         }
-                        ConstParamTyRibKind => {
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
                             }
                             return Res::Err;
                         }
-                        InlineAsmSymRibKind => {
+                        RibKind::InlineAsmSym => {
                             if let Some(span) = finalize {
                                 self.report_error(span, InvalidAsmSym);
                             }
@@ -1171,21 +1170,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     return Res::Err;
                 }
             }
-            Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
+            Res::Def(DefKind::TyParam, _)
+            | Res::SelfTyParam { .. }
+            | Res::SelfTyAlias { .. }
+            | Res::SelfCtor(_) => {
                 for rib in ribs {
                     let has_generic_params: HasGenericParams = match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | InlineAsmSymRibKind
-                        | AssocItemRibKind
-                        | ForwardGenericParamBanRibKind => {
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::InlineAsmSym
+                        | RibKind::AssocItem
+                        | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                             continue;
                         }
 
-                        ConstantItemRibKind(trivial, _) => {
+                        RibKind::ConstantItem(trivial, _) => {
                             let features = self.tcx.sess.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
                             if !(trivial == ConstantHasGenerics::Yes
@@ -1226,8 +1228,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
 
                         // This was an attempt to use a type parameter outside its scope.
-                        ItemRibKind(has_generic_params) => has_generic_params,
-                        ConstParamTyRibKind => {
+                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
@@ -1253,15 +1255,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             Res::Def(DefKind::ConstParam, _) => {
                 for rib in ribs {
                     let has_generic_params = match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | InlineAsmSymRibKind
-                        | AssocItemRibKind
-                        | ForwardGenericParamBanRibKind => continue,
-
-                        ConstantItemRibKind(trivial, _) => {
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::InlineAsmSym
+                        | RibKind::AssocItem
+                        | RibKind::ForwardGenericParamBan => continue,
+
+                        RibKind::ConstantItem(trivial, _) => {
                             let features = self.tcx.sess.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
                             if !(trivial == ConstantHasGenerics::Yes
@@ -1284,8 +1286,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             continue;
                         }
 
-                        ItemRibKind(has_generic_params) => has_generic_params,
-                        ConstParamTyRibKind => {
+                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 11d2b975fec..6f5d54bcf87 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -6,8 +6,6 @@
 //! If you wonder why there's no `early.rs`, that's because it's split into three files -
 //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
 
-use RibKind::*;
-
 use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
 use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
@@ -133,28 +131,28 @@ enum RecordPartialRes {
 #[derive(Copy, Clone, Debug)]
 pub(crate) enum RibKind<'a> {
     /// No restriction needs to be applied.
-    NormalRibKind,
+    Normal,
 
     /// We passed through an impl or trait and are now in one of its
     /// methods or associated types. Allow references to ty params that impl or trait
     /// binds. Disallow any other upvars (including other ty params that are
     /// upvars).
-    AssocItemRibKind,
+    AssocItem,
 
     /// We passed through a closure. Disallow labels.
-    ClosureOrAsyncRibKind,
+    ClosureOrAsync,
 
     /// We passed through an item scope. Disallow upvars.
-    ItemRibKind(HasGenericParams),
+    Item(HasGenericParams),
 
     /// We're in a constant item. Can't refer to dynamic stuff.
     ///
     /// The item may reference generic parameters in trivial constant expressions.
     /// All other constants aren't allowed to use generic params at all.
-    ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
+    ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
 
     /// We passed through a module.
-    ModuleRibKind(Module<'a>),
+    Module(Module<'a>),
 
     /// We passed through a `macro_rules!` statement
     MacroDefinition(DefId),
@@ -162,15 +160,15 @@ pub(crate) enum RibKind<'a> {
     /// All bindings in this rib are generic parameters that can't be used
     /// from the default of a generic parameter because they're not declared
     /// before said generic parameter. Also see the `visit_generics` override.
-    ForwardGenericParamBanRibKind,
+    ForwardGenericParamBan,
 
     /// We are inside of the type of a const parameter. Can't refer to any
     /// parameters.
-    ConstParamTyRibKind,
+    ConstParamTy,
 
     /// We are inside a `sym` inline assembly operand. Can only refer to
     /// globals.
-    InlineAsmSymRibKind,
+    InlineAsmSym,
 }
 
 impl RibKind<'_> {
@@ -178,30 +176,30 @@ impl RibKind<'_> {
     /// variables.
     pub(crate) fn contains_params(&self) -> bool {
         match self {
-            NormalRibKind
-            | ClosureOrAsyncRibKind
-            | ConstantItemRibKind(..)
-            | ModuleRibKind(_)
-            | MacroDefinition(_)
-            | ConstParamTyRibKind
-            | InlineAsmSymRibKind => false,
-            AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
+            RibKind::Normal
+            | RibKind::ClosureOrAsync
+            | RibKind::ConstantItem(..)
+            | RibKind::Module(_)
+            | RibKind::MacroDefinition(_)
+            | RibKind::ConstParamTy
+            | RibKind::InlineAsmSym => false,
+            RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
         }
     }
 
     /// This rib forbids referring to labels defined in upwards ribs.
     fn is_label_barrier(self) -> bool {
         match self {
-            NormalRibKind | MacroDefinition(..) => false,
-
-            AssocItemRibKind
-            | ClosureOrAsyncRibKind
-            | ItemRibKind(..)
-            | ConstantItemRibKind(..)
-            | ModuleRibKind(..)
-            | ForwardGenericParamBanRibKind
-            | ConstParamTyRibKind
-            | InlineAsmSymRibKind => true,
+            RibKind::Normal | RibKind::MacroDefinition(..) => false,
+
+            RibKind::AssocItem
+            | RibKind::ClosureOrAsync
+            | RibKind::Item(..)
+            | RibKind::ConstantItem(..)
+            | RibKind::Module(..)
+            | RibKind::ForwardGenericParamBan
+            | RibKind::ConstParamTy
+            | RibKind::InlineAsmSym => true,
         }
     }
 }
@@ -702,7 +700,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                     let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());
                     self.with_generic_param_rib(
                         &[],
-                        NormalRibKind,
+                        RibKind::Normal,
                         LifetimeRibKind::Generics {
                             binder: ty.id,
                             kind: LifetimeBinderKind::PolyTrait,
@@ -740,7 +738,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                 let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
                 self.with_generic_param_rib(
                     &bare_fn.generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: ty.id,
                         kind: LifetimeBinderKind::BareFnType,
@@ -780,7 +778,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
         let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
         self.with_generic_param_rib(
             &tref.bound_generic_params,
-            NormalRibKind,
+            RibKind::Normal,
             LifetimeRibKind::Generics {
                 binder: tref.trait_ref.ref_id,
                 kind: LifetimeBinderKind::PolyTrait,
@@ -804,7 +802,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
             ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Item,
@@ -816,7 +814,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
             ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Function,
@@ -870,9 +868,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
         debug!("(resolving function) entering function");
 
         // Create a value rib for the function.
-        self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::ClosureOrAsync, |this| {
             // Create a label rib for the function.
-            this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+            this.with_label_rib(RibKind::ClosureOrAsync, |this| {
                 match fn_kind {
                     FnKind::Fn(_, _, sig, _, generics, body) => {
                         this.visit_generics(generics);
@@ -1129,7 +1127,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                 let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
                 this.with_generic_param_rib(
                     &bound_generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: bounded_ty.id,
                         kind: LifetimeBinderKind::WhereBound,
@@ -1175,9 +1173,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
 
     fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
         // This is similar to the code for AnonConst.
-        self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
-            this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
-                this.with_label_rib(InlineAsmSymRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {
+            this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {
+                this.with_label_rib(RibKind::InlineAsmSym, |this| {
                     this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
                     visit::walk_inline_asm_sym(this, sym);
                 });
@@ -1202,7 +1200,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // although it may be useful to track other components as well for diagnostics.
         let graph_root = resolver.graph_root;
         let parent_scope = ParentScope::module(graph_root, resolver);
-        let start_rib_kind = ModuleRibKind(graph_root);
+        let start_rib_kind = RibKind::Module(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
@@ -1306,8 +1304,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
             // Move down in the graph.
             let orig_module = replace(&mut self.parent_scope.module, module);
-            self.with_rib(ValueNS, ModuleRibKind(module), |this| {
-                this.with_rib(TypeNS, ModuleRibKind(module), |this| {
+            self.with_rib(ValueNS, RibKind::Module(module), |this| {
+                this.with_rib(TypeNS, RibKind::Module(module), |this| {
                     let ret = f(this);
                     this.parent_scope.module = orig_module;
                     ret
@@ -1324,8 +1322,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // provide previous type parameters as they're built. We
         // put all the parameters on the ban list and then remove
         // them one by one as they are processed and become available.
-        let mut forward_ty_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
-        let mut forward_const_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
+        let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
+        let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
         for param in params.iter() {
             match param.kind {
                 GenericParamKind::Type { .. } => {
@@ -1386,8 +1384,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         // Const parameters can't have param bounds.
                         assert!(param.bounds.is_empty());
 
-                        this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
-                        this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
+                        this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
+                        this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
                         this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
                             this.visit_ty(ty)
                         });
@@ -2072,6 +2070,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 }
                 visit::walk_ty(self, ty)
             }
+
+            // A type may have an expression as a const generic argument.
+            // We do not want to recurse into those.
+            fn visit_expr(&mut self, _: &'a Expr) {}
         }
 
         let impl_self = self
@@ -2109,7 +2111,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         for i in (0..self.label_ribs.len()).rev() {
             let rib = &self.label_ribs[i];
 
-            if let MacroDefinition(def) = rib.kind {
+            if let RibKind::MacroDefinition(def) = rib.kind {
                 // If an invocation of this macro created `ident`, give up on `ident`
                 // and switch to `ident`'s source from the macro definition.
                 if def == self.r.macro_def(label.span.ctxt()) {
@@ -2157,7 +2159,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(
                 &generics.params,
-                ItemRibKind(HasGenericParams::Yes(generics.span)),
+                RibKind::Item(HasGenericParams::Yes(generics.span)),
                 LifetimeRibKind::Generics {
                     binder: item.id,
                     kind: LifetimeBinderKind::Item,
@@ -2238,7 +2240,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2251,7 +2253,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Function,
@@ -2290,7 +2292,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2311,7 +2313,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2414,11 +2416,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         let mut seen_lifetimes = FxHashSet::default();
 
         // We also can't shadow bindings from the parent item
-        if let AssocItemRibKind = kind {
+        if let RibKind::AssocItem = kind {
             let mut add_bindings_for_ns = |ns| {
                 let parent_rib = self.ribs[ns]
                     .iter()
-                    .rfind(|r| matches!(r.kind, ItemRibKind(_)))
+                    .rfind(|r| matches!(r.kind, RibKind::Item(_)))
                     .expect("associated item outside of an item");
                 seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
             };
@@ -2507,8 +2509,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             };
 
             let res = match kind {
-                ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()),
-                NormalRibKind => {
+                RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()),
+                RibKind::Normal => {
                     if self.r.tcx.sess.features_untracked().non_lifetime_binders {
                         Res::Def(def_kind, def_id.to_def_id())
                     } else {
@@ -2554,7 +2556,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     }
 
     fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
-        let kind = ItemRibKind(HasGenericParams::No);
+        let kind = RibKind::Item(HasGenericParams::No);
         self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
     }
 
@@ -2574,15 +2576,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         item: Option<(Ident, ConstantItemKind)>,
         f: impl FnOnce(&mut Self),
     ) {
-        self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| {
+        self.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
             this.with_rib(
                 TypeNS,
-                ConstantItemRibKind(
+                RibKind::ConstantItem(
                     may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
                     item,
                 ),
                 |this| {
-                    this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f);
+                    this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
                 },
             )
         });
@@ -2614,7 +2616,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             |this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| {
                 this.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind },
                     |this| visit::walk_assoc_item(this, item, AssocCtxt::Trait),
                 );
@@ -2695,7 +2697,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     }
 
     fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
-        let mut self_type_rib = Rib::new(NormalRibKind);
+        let mut self_type_rib = Rib::new(RibKind::Normal);
 
         // Plain insert (no renaming, since types are not currently hygienic)
         self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
@@ -2721,7 +2723,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // If applicable, create a rib for the type parameters.
         self.with_generic_param_rib(
             &generics.params,
-            ItemRibKind(HasGenericParams::Yes(generics.span)),
+            RibKind::Item(HasGenericParams::Yes(generics.span)),
             LifetimeRibKind::Generics {
                 span: generics.span,
                 binder: item_id,
@@ -2835,7 +2837,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         span: generics.span,
@@ -2863,7 +2865,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         span: generics.span,
@@ -3135,7 +3137,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     }
 
     fn resolve_arm(&mut self, arm: &'ast Arm) {
-        self.with_rib(ValueNS, NormalRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::Normal, |this| {
             this.resolve_pattern_top(&arm.pat, PatternSource::Match);
             walk_list!(this, visit_expr, &arm.guard);
             this.visit_expr(&arm.body);
@@ -3857,7 +3859,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 diagnostics::signal_label_shadowing(self.r.tcx.sess, orig_span, label.ident)
             }
 
-            self.with_label_rib(NormalRibKind, |this| {
+            self.with_label_rib(RibKind::Normal, |this| {
                 let ident = label.ident.normalize_to_macro_rules();
                 this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
                 f(this);
@@ -3880,11 +3882,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         let mut num_macro_definition_ribs = 0;
         if let Some(anonymous_module) = anonymous_module {
             debug!("(resolving block) found anonymous module, moving down");
-            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
-            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
+            self.ribs[ValueNS].push(Rib::new(RibKind::Module(anonymous_module)));
+            self.ribs[TypeNS].push(Rib::new(RibKind::Module(anonymous_module)));
             self.parent_scope.module = anonymous_module;
         } else {
-            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
+            self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
         }
 
         let prev = self.diagnostic_metadata.current_block_could_be_bare_struct_literal.take();
@@ -3901,8 +3903,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 && let ItemKind::MacroDef(..) = item.kind {
                 num_macro_definition_ribs += 1;
                 let res = self.r.local_def_id(item.id).to_def_id();
-                self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
-                self.label_ribs.push(Rib::new(MacroDefinition(res)));
+                self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res)));
+                self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res)));
             }
 
             self.visit_stmt(stmt);
@@ -3989,7 +3991,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             ExprKind::If(ref cond, ref then, ref opt_else) => {
-                self.with_rib(ValueNS, NormalRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
                     let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                     this.visit_expr(cond);
                     this.diagnostic_metadata.in_if_condition = old;
@@ -4006,7 +4008,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             ExprKind::While(ref cond, ref block, label) => {
                 self.with_resolved_label(label, expr.id, |this| {
-                    this.with_rib(ValueNS, NormalRibKind, |this| {
+                    this.with_rib(ValueNS, RibKind::Normal, |this| {
                         let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                         this.visit_expr(cond);
                         this.diagnostic_metadata.in_if_condition = old;
@@ -4017,7 +4019,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
                 self.visit_expr(iter_expr);
-                self.with_rib(ValueNS, NormalRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
                     this.resolve_pattern_top(pat, PatternSource::For);
                     this.resolve_labeled_block(label, expr.id, block);
                 });
@@ -4073,8 +4075,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 ref body,
                 ..
             }) => {
-                self.with_rib(ValueNS, NormalRibKind, |this| {
-                    this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
+                    this.with_label_rib(RibKind::ClosureOrAsync, |this| {
                         // Resolve arguments:
                         this.resolve_params(&fn_decl.inputs);
                         // No need to resolve return type --
@@ -4098,7 +4100,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }) => {
                 self.with_generic_param_rib(
                     &generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: expr.id,
                         kind: LifetimeBinderKind::Closure,
@@ -4109,7 +4111,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
             ExprKind::Closure(..) => visit::walk_expr(self, expr),
             ExprKind::Async(..) => {
-                self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr));
+                self.with_label_rib(RibKind::ClosureOrAsync, |this| visit::walk_expr(this, expr));
             }
             ExprKind::Repeat(ref elem, ref ct) => {
                 self.visit_expr(elem);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e215b6b7090..42d498c7ee0 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -605,7 +605,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
 
         // Try to find in last block rib
-        if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
+        if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind {
             for (ident, &res) in &rib.bindings {
                 if let Res::Local(_) = res && path.len() == 1 &&
                     ident.span.eq_ctxt(path[0].ident.span) &&
@@ -1690,7 +1690,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 }
 
                 // Items in scope
-                if let RibKind::ModuleRibKind(module) = rib.kind {
+                if let RibKind::Module(module) = rib.kind {
                     // Items from this module
                     self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
 
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index a2ec318df6d..6b559cb5b2f 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -265,52 +265,41 @@ impl Drop for FileEncoder {
     }
 }
 
-macro_rules! file_encoder_write_leb128 {
-    ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{
-        const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>();
+macro_rules! write_leb128 {
+    ($this_fn:ident, $int_ty:ty, $write_leb_fn:ident) => {
+        #[inline]
+        fn $this_fn(&mut self, v: $int_ty) {
+            const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>();
 
-        // We ensure this during `FileEncoder` construction.
-        debug_assert!($enc.capacity() >= MAX_ENCODED_LEN);
+            // We ensure this during `FileEncoder` construction.
+            debug_assert!(self.capacity() >= MAX_ENCODED_LEN);
 
-        let mut buffered = $enc.buffered;
+            let mut buffered = self.buffered;
 
-        // This can't overflow. See assertion in `FileEncoder::with_capacity`.
-        if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > $enc.capacity()) {
-            $enc.flush();
-            buffered = 0;
-        }
+            // This can't overflow. See assertion in `FileEncoder::with_capacity`.
+            if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > self.capacity()) {
+                self.flush();
+                buffered = 0;
+            }
 
-        // SAFETY: The above check and flush ensures that there is enough
-        // room to write the encoded value to the buffer.
-        let buf = unsafe {
-            &mut *($enc.buf.as_mut_ptr().add(buffered) as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN])
-        };
+            // SAFETY: The above check and flush ensures that there is enough
+            // room to write the encoded value to the buffer.
+            let buf = unsafe {
+                &mut *(self.buf.as_mut_ptr().add(buffered)
+                    as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN])
+            };
 
-        let encoded = leb128::$fun(buf, $value);
-        $enc.buffered = buffered + encoded.len();
-    }};
+            let encoded = leb128::$write_leb_fn(buf, v);
+            self.buffered = buffered + encoded.len();
+        }
+    };
 }
 
 impl Encoder for FileEncoder {
-    #[inline]
-    fn emit_usize(&mut self, v: usize) {
-        file_encoder_write_leb128!(self, v, usize, write_usize_leb128)
-    }
-
-    #[inline]
-    fn emit_u128(&mut self, v: u128) {
-        file_encoder_write_leb128!(self, v, u128, write_u128_leb128)
-    }
-
-    #[inline]
-    fn emit_u64(&mut self, v: u64) {
-        file_encoder_write_leb128!(self, v, u64, write_u64_leb128)
-    }
-
-    #[inline]
-    fn emit_u32(&mut self, v: u32) {
-        file_encoder_write_leb128!(self, v, u32, write_u32_leb128)
-    }
+    write_leb128!(emit_usize, usize, write_usize_leb128);
+    write_leb128!(emit_u128, u128, write_u128_leb128);
+    write_leb128!(emit_u64, u64, write_u64_leb128);
+    write_leb128!(emit_u32, u32, write_u32_leb128);
 
     #[inline]
     fn emit_u16(&mut self, v: u16) {
@@ -322,25 +311,10 @@ impl Encoder for FileEncoder {
         self.write_one(v);
     }
 
-    #[inline]
-    fn emit_isize(&mut self, v: isize) {
-        file_encoder_write_leb128!(self, v, isize, write_isize_leb128)
-    }
-
-    #[inline]
-    fn emit_i128(&mut self, v: i128) {
-        file_encoder_write_leb128!(self, v, i128, write_i128_leb128)
-    }
-
-    #[inline]
-    fn emit_i64(&mut self, v: i64) {
-        file_encoder_write_leb128!(self, v, i64, write_i64_leb128)
-    }
-
-    #[inline]
-    fn emit_i32(&mut self, v: i32) {
-        file_encoder_write_leb128!(self, v, i32, write_i32_leb128)
-    }
+    write_leb128!(emit_isize, isize, write_isize_leb128);
+    write_leb128!(emit_i128, i128, write_i128_leb128);
+    write_leb128!(emit_i64, i64, write_i64_leb128);
+    write_leb128!(emit_i32, i32, write_i32_leb128);
 
     #[inline]
     fn emit_i16(&mut self, v: i16) {
@@ -437,30 +411,19 @@ impl<'a> MemDecoder<'a> {
 }
 
 macro_rules! read_leb128 {
-    ($dec:expr, $fun:ident) => {{ leb128::$fun($dec) }};
+    ($this_fn:ident, $int_ty:ty, $read_leb_fn:ident) => {
+        #[inline]
+        fn $this_fn(&mut self) -> $int_ty {
+            leb128::$read_leb_fn(self)
+        }
+    };
 }
 
 impl<'a> Decoder for MemDecoder<'a> {
-    #[inline]
-    fn position(&self) -> usize {
-        // SAFETY: This type guarantees start <= current
-        unsafe { self.current.sub_ptr(self.start) }
-    }
-
-    #[inline]
-    fn read_u128(&mut self) -> u128 {
-        read_leb128!(self, read_u128_leb128)
-    }
-
-    #[inline]
-    fn read_u64(&mut self) -> u64 {
-        read_leb128!(self, read_u64_leb128)
-    }
-
-    #[inline]
-    fn read_u32(&mut self) -> u32 {
-        read_leb128!(self, read_u32_leb128)
-    }
+    read_leb128!(read_usize, usize, read_usize_leb128);
+    read_leb128!(read_u128, u128, read_u128_leb128);
+    read_leb128!(read_u64, u64, read_u64_leb128);
+    read_leb128!(read_u32, u32, read_u32_leb128);
 
     #[inline]
     fn read_u16(&mut self) -> u16 {
@@ -480,25 +443,10 @@ impl<'a> Decoder for MemDecoder<'a> {
         }
     }
 
-    #[inline]
-    fn read_usize(&mut self) -> usize {
-        read_leb128!(self, read_usize_leb128)
-    }
-
-    #[inline]
-    fn read_i128(&mut self) -> i128 {
-        read_leb128!(self, read_i128_leb128)
-    }
-
-    #[inline]
-    fn read_i64(&mut self) -> i64 {
-        read_leb128!(self, read_i64_leb128)
-    }
-
-    #[inline]
-    fn read_i32(&mut self) -> i32 {
-        read_leb128!(self, read_i32_leb128)
-    }
+    read_leb128!(read_isize, isize, read_isize_leb128);
+    read_leb128!(read_i128, i128, read_i128_leb128);
+    read_leb128!(read_i64, i64, read_i64_leb128);
+    read_leb128!(read_i32, i32, read_i32_leb128);
 
     #[inline]
     fn read_i16(&mut self) -> i16 {
@@ -506,11 +454,6 @@ impl<'a> Decoder for MemDecoder<'a> {
     }
 
     #[inline]
-    fn read_isize(&mut self) -> isize {
-        read_leb128!(self, read_isize_leb128)
-    }
-
-    #[inline]
     fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] {
         if bytes > self.remaining() {
             Self::decoder_exhausted();
@@ -532,6 +475,12 @@ impl<'a> Decoder for MemDecoder<'a> {
         // Since we just checked current == end, the current pointer must be inbounds.
         unsafe { *self.current }
     }
+
+    #[inline]
+    fn position(&self) -> usize {
+        // SAFETY: This type guarantees start <= current
+        unsafe { self.current.sub_ptr(self.start) }
+    }
 }
 
 // Specializations for contiguous byte sequences follow. The default implementations for slices
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index e1bc598736f..06166cabc18 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -1,9 +1,5 @@
 //! Support code for encoding and decoding types.
 
-/*
-Core encoding and decoding interfaces.
-*/
-
 use std::alloc::Allocator;
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
@@ -35,13 +31,13 @@ const STR_SENTINEL: u8 = 0xC1;
 /// really makes sense to store floating-point values at all.
 /// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.)
 pub trait Encoder {
-    // Primitive types:
     fn emit_usize(&mut self, v: usize);
     fn emit_u128(&mut self, v: u128);
     fn emit_u64(&mut self, v: u64);
     fn emit_u32(&mut self, v: u32);
     fn emit_u16(&mut self, v: u16);
     fn emit_u8(&mut self, v: u8);
+
     fn emit_isize(&mut self, v: isize);
     fn emit_i128(&mut self, v: i128);
     fn emit_i64(&mut self, v: i64);
@@ -93,13 +89,13 @@ pub trait Encoder {
 /// really makes sense to store floating-point values at all.
 /// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.)
 pub trait Decoder {
-    // Primitive types:
     fn read_usize(&mut self) -> usize;
     fn read_u128(&mut self) -> u128;
     fn read_u64(&mut self) -> u64;
     fn read_u32(&mut self) -> u32;
     fn read_u16(&mut self) -> u16;
     fn read_u8(&mut self) -> u8;
+
     fn read_isize(&mut self) -> isize;
     fn read_i128(&mut self) -> i128;
     fn read_i64(&mut self) -> i64;
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 8a900ca427e..341cc61fd1c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -69,7 +69,6 @@ use std::hash::Hash;
 use std::ops::{Add, Range, Sub};
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
-use std::sync::Arc;
 
 use md5::Digest;
 use md5::Md5;
@@ -1269,13 +1268,13 @@ pub enum DebuggerVisualizerType {
 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)]
 pub struct DebuggerVisualizerFile {
     /// The complete debugger visualizer source.
-    pub src: Arc<[u8]>,
+    pub src: Lrc<[u8]>,
     /// Indicates which visualizer type this targets.
     pub visualizer_type: DebuggerVisualizerType,
 }
 
 impl DebuggerVisualizerFile {
-    pub fn new(src: Arc<[u8]>, visualizer_type: DebuggerVisualizerType) -> Self {
+    pub fn new(src: Lrc<[u8]>, visualizer_type: DebuggerVisualizerType) -> Self {
         DebuggerVisualizerFile { src, visualizer_type }
     }
 }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index a002421aeef..18f25aec5fe 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -101,6 +101,7 @@
 #![feature(array_into_iter_constructors)]
 #![feature(array_methods)]
 #![feature(array_windows)]
+#![feature(ascii_char)]
 #![feature(assert_matches)]
 #![feature(async_iterator)]
 #![feature(coerce_unsized)]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index cf16a3424a0..b9ef76c109a 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2527,6 +2527,15 @@ impl<T: fmt::Display + ?Sized> ToString for T {
 }
 
 #[cfg(not(no_global_oom_handling))]
+#[unstable(feature = "ascii_char", issue = "110998")]
+impl ToString for core::ascii::Char {
+    #[inline]
+    fn to_string(&self) -> String {
+        self.as_str().to_owned()
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "char_to_string_specialization", since = "1.46.0")]
 impl ToString for char {
     #[inline]
diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs
new file mode 100644
index 00000000000..6750d7c0711
--- /dev/null
+++ b/library/core/src/array/ascii.rs
@@ -0,0 +1,34 @@
+use crate::ascii;
+
+#[cfg(not(test))]
+impl<const N: usize> [u8; N] {
+    /// Converts this array of bytes into a array of ASCII characters,
+    /// or returns `None` if any of the characters is non-ASCII.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[must_use]
+    #[inline]
+    pub fn as_ascii(&self) -> Option<&[ascii::Char; N]> {
+        if self.is_ascii() {
+            // SAFETY: Just checked that it's ASCII
+            Some(unsafe { self.as_ascii_unchecked() })
+        } else {
+            None
+        }
+    }
+
+    /// Converts this array of bytes into a array of ASCII characters,
+    /// without checking whether they're valid.
+    ///
+    /// # Safety
+    ///
+    /// Every byte in the array must be in `0..=127`, or else this is UB.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[must_use]
+    #[inline]
+    pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char; N] {
+        let byte_ptr: *const [u8; N] = self;
+        let ascii_ptr = byte_ptr as *const [ascii::Char; N];
+        // SAFETY: The caller promised all the bytes are ASCII
+        unsafe { &*ascii_ptr }
+    }
+}
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 940558974e6..bdb4c975909 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -17,6 +17,7 @@ use crate::ops::{
 };
 use crate::slice::{Iter, IterMut};
 
+mod ascii;
 mod drain;
 mod equality;
 mod iter;
diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs
index 065f1b3e70e..7fd14a7e1ea 100644
--- a/library/core/src/ascii.rs
+++ b/library/core/src/ascii.rs
@@ -14,6 +14,10 @@ use crate::fmt;
 use crate::iter::FusedIterator;
 use crate::num::NonZeroUsize;
 
+mod ascii_char;
+#[unstable(feature = "ascii_char", issue = "110998")]
+pub use ascii_char::AsciiChar as Char;
+
 /// An iterator over the escaped version of a byte.
 ///
 /// This `struct` is created by the [`escape_default`] function. See its
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
new file mode 100644
index 00000000000..f093a0990d1
--- /dev/null
+++ b/library/core/src/ascii/ascii_char.rs
@@ -0,0 +1,565 @@
+//! This uses the name `AsciiChar`, even though it's not exposed that way right now,
+//! because it avoids a whole bunch of "are you sure you didn't mean `char`?"
+//! suggestions from rustc if you get anything slightly wrong in here, and overall
+//! helps with clarity as we're also referring to `char` intentionally in here.
+
+use crate::fmt;
+use crate::mem::transmute;
+
+/// One of the 128 Unicode characters from U+0000 through U+007F,
+/// often known as the [ASCII] subset.
+///
+/// Officially, this is the first [block] in Unicode, _Basic Latin_.
+/// For details, see the [*C0 Controls and Basic Latin*][chart] code chart.
+///
+/// This block was based on older 7-bit character code standards such as
+/// ANSI X3.4-1977, ISO 646-1973, and [NIST FIPS 1-2].
+///
+/// # When to use this
+///
+/// The main advantage of this subset is that it's always valid UTF-8.  As such,
+/// the `&[ascii::Char]` -> `&str` conversion function (as well as other related
+/// ones) are O(1): *no* runtime checks are needed.
+///
+/// If you're consuming strings, you should usually handle Unicode and thus
+/// accept `str`s, not limit yourself to `ascii::Char`s.
+///
+/// However, certain formats are intentionally designed to produce ASCII-only
+/// output in order to be 8-bit-clean.  In those cases, it can be simpler and
+/// faster to generate `ascii::Char`s instead of dealing with the variable width
+/// properties of general UTF-8 encoded strings, while still allowing the result
+/// to be used freely with other Rust things that deal in general `str`s.
+///
+/// For example, a UUID library might offer a way to produce the string
+/// representation of a UUID as an `[ascii::Char; 36]` to avoid memory
+/// allocation yet still allow it to be used as UTF-8 via `as_str` without
+/// paying for validation (or needing `unsafe` code) the way it would if it
+/// were provided as a `[u8; 36]`.
+///
+/// # Layout
+///
+/// This type is guaranteed to have a size and alignment of 1 byte.
+///
+/// # Names
+///
+/// The variants on this type are [Unicode names][NamesList] of the characters
+/// in upper camel case, with a few tweaks:
+/// - For `<control>` characters, the primary alias name is used.
+/// - `LATIN` is dropped, as this block has no non-latin letters.
+/// - `LETTER` is dropped, as `CAPITAL`/`SMALL` suffices in this block.
+/// - `DIGIT`s use a single digit rather than writing out `ZERO`, `ONE`, etc.
+///
+/// [ASCII]: https://www.unicode.org/glossary/index.html#ASCII
+/// [block]: https://www.unicode.org/glossary/index.html#block
+/// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf
+/// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf
+/// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[unstable(feature = "ascii_char", issue = "110998")]
+#[repr(u8)]
+pub enum AsciiChar {
+    /// U+0000
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Null = 0,
+    /// U+0001
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    StartOfHeading = 1,
+    /// U+0002
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    StartOfText = 2,
+    /// U+0003
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    EndOfText = 3,
+    /// U+0004
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    EndOfTransmission = 4,
+    /// U+0005
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Enquiry = 5,
+    /// U+0006
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Acknowledge = 6,
+    /// U+0007
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Bell = 7,
+    /// U+0008
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Backspace = 8,
+    /// U+0009
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CharacterTabulation = 9,
+    /// U+000A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LineFeed = 10,
+    /// U+000B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LineTabulation = 11,
+    /// U+000C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    FormFeed = 12,
+    /// U+000D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CarriageReturn = 13,
+    /// U+000E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    ShiftOut = 14,
+    /// U+000F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    ShiftIn = 15,
+    /// U+0010
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DataLinkEscape = 16,
+    /// U+0011
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DeviceControlOne = 17,
+    /// U+0012
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DeviceControlTwo = 18,
+    /// U+0013
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DeviceControlThree = 19,
+    /// U+0014
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DeviceControlFour = 20,
+    /// U+0015
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    NegativeAcknowledge = 21,
+    /// U+0016
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SynchronousIdle = 22,
+    /// U+0017
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    EndOfTransmissionBlock = 23,
+    /// U+0018
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Cancel = 24,
+    /// U+0019
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    EndOfMedium = 25,
+    /// U+001A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Substitute = 26,
+    /// U+001B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Escape = 27,
+    /// U+001C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    InformationSeparatorFour = 28,
+    /// U+001D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    InformationSeparatorThree = 29,
+    /// U+001E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    InformationSeparatorTwo = 30,
+    /// U+001F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    InformationSeparatorOne = 31,
+    /// U+0020
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Space = 32,
+    /// U+0021
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    ExclamationMark = 33,
+    /// U+0022
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    QuotationMark = 34,
+    /// U+0023
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    NumberSign = 35,
+    /// U+0024
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    DollarSign = 36,
+    /// U+0025
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    PercentSign = 37,
+    /// U+0026
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Ampersand = 38,
+    /// U+0027
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Apostrophe = 39,
+    /// U+0028
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LeftParenthesis = 40,
+    /// U+0029
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    RightParenthesis = 41,
+    /// U+002A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Asterisk = 42,
+    /// U+002B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    PlusSign = 43,
+    /// U+002C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Comma = 44,
+    /// U+002D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    HyphenMinus = 45,
+    /// U+002E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    FullStop = 46,
+    /// U+002F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Solidus = 47,
+    /// U+0030
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit0 = 48,
+    /// U+0031
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit1 = 49,
+    /// U+0032
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit2 = 50,
+    /// U+0033
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit3 = 51,
+    /// U+0034
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit4 = 52,
+    /// U+0035
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit5 = 53,
+    /// U+0036
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit6 = 54,
+    /// U+0037
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit7 = 55,
+    /// U+0038
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit8 = 56,
+    /// U+0039
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Digit9 = 57,
+    /// U+003A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Colon = 58,
+    /// U+003B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Semicolon = 59,
+    /// U+003C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LessThanSign = 60,
+    /// U+003D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    EqualsSign = 61,
+    /// U+003E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    GreaterThanSign = 62,
+    /// U+003F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    QuestionMark = 63,
+    /// U+0040
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CommercialAt = 64,
+    /// U+0041
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalA = 65,
+    /// U+0042
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalB = 66,
+    /// U+0043
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalC = 67,
+    /// U+0044
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalD = 68,
+    /// U+0045
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalE = 69,
+    /// U+0046
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalF = 70,
+    /// U+0047
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalG = 71,
+    /// U+0048
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalH = 72,
+    /// U+0049
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalI = 73,
+    /// U+004A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalJ = 74,
+    /// U+004B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalK = 75,
+    /// U+004C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalL = 76,
+    /// U+004D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalM = 77,
+    /// U+004E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalN = 78,
+    /// U+004F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalO = 79,
+    /// U+0050
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalP = 80,
+    /// U+0051
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalQ = 81,
+    /// U+0052
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalR = 82,
+    /// U+0053
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalS = 83,
+    /// U+0054
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalT = 84,
+    /// U+0055
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalU = 85,
+    /// U+0056
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalV = 86,
+    /// U+0057
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalW = 87,
+    /// U+0058
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalX = 88,
+    /// U+0059
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalY = 89,
+    /// U+005A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CapitalZ = 90,
+    /// U+005B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LeftSquareBracket = 91,
+    /// U+005C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    ReverseSolidus = 92,
+    /// U+005D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    RightSquareBracket = 93,
+    /// U+005E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    CircumflexAccent = 94,
+    /// U+005F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LowLine = 95,
+    /// U+0060
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    GraveAccent = 96,
+    /// U+0061
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallA = 97,
+    /// U+0062
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallB = 98,
+    /// U+0063
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallC = 99,
+    /// U+0064
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallD = 100,
+    /// U+0065
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallE = 101,
+    /// U+0066
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallF = 102,
+    /// U+0067
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallG = 103,
+    /// U+0068
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallH = 104,
+    /// U+0069
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallI = 105,
+    /// U+006A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallJ = 106,
+    /// U+006B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallK = 107,
+    /// U+006C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallL = 108,
+    /// U+006D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallM = 109,
+    /// U+006E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallN = 110,
+    /// U+006F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallO = 111,
+    /// U+0070
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallP = 112,
+    /// U+0071
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallQ = 113,
+    /// U+0072
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallR = 114,
+    /// U+0073
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallS = 115,
+    /// U+0074
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallT = 116,
+    /// U+0075
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallU = 117,
+    /// U+0076
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallV = 118,
+    /// U+0077
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallW = 119,
+    /// U+0078
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallX = 120,
+    /// U+0079
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallY = 121,
+    /// U+007A
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    SmallZ = 122,
+    /// U+007B
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    LeftCurlyBracket = 123,
+    /// U+007C
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    VerticalLine = 124,
+    /// U+007D
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    RightCurlyBracket = 125,
+    /// U+007E
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Tilde = 126,
+    /// U+007F
+    #[unstable(feature = "ascii_char_variants", issue = "110998")]
+    Delete = 127,
+}
+
+impl AsciiChar {
+    /// Creates an ascii character from the byte `b`,
+    /// or returns `None` if it's too large.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn from_u8(b: u8) -> Option<Self> {
+        if b <= 127 {
+            // SAFETY: Just checked that `b` is in-range
+            Some(unsafe { Self::from_u8_unchecked(b) })
+        } else {
+            None
+        }
+    }
+
+    /// Creates an ASCII character from the byte `b`,
+    /// without checking whether it's valid.
+    ///
+    /// # Safety
+    ///
+    /// `b` must be in `0..=127`, or else this is UB.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const unsafe fn from_u8_unchecked(b: u8) -> Self {
+        // SAFETY: Our safety precondition is that `b` is in-range.
+        unsafe { transmute(b) }
+    }
+
+    /// When passed the *number* `0`, `1`, …, `9`, returns the *character*
+    /// `'0'`, `'1'`, …, `'9'` respectively.
+    ///
+    /// If `d >= 10`, returns `None`.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn digit(d: u8) -> Option<Self> {
+        if d < 10 {
+            // SAFETY: Just checked it's in-range.
+            Some(unsafe { Self::digit_unchecked(d) })
+        } else {
+            None
+        }
+    }
+
+    /// When passed the *number* `0`, `1`, …, `9`, returns the *character*
+    /// `'0'`, `'1'`, …, `'9'` respectively, without checking that it's in-range.
+    ///
+    /// # Safety
+    ///
+    /// This is immediate UB if called with `d > 64`.
+    ///
+    /// If `d >= 10` and `d <= 64`, this is allowed to return any value or panic.
+    /// Notably, it should not be expected to return hex digits, or any other
+    /// reasonable extension of the decimal digits.
+    ///
+    /// (This lose safety condition is intended to simplify soundness proofs
+    /// when writing code using this method, since the implementation doesn't
+    /// need something really specific, not to make those other arguments do
+    /// something useful. It might be tightened before stabilization.)
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const unsafe fn digit_unchecked(d: u8) -> Self {
+        debug_assert!(d < 10);
+
+        // SAFETY: `'0'` through `'9'` are U+00030 through U+0039,
+        // so because `d` must be 64 or less the addition can return at most
+        // 112 (0x70), which doesn't overflow and is within the ASCII range.
+        unsafe {
+            let byte = b'0'.unchecked_add(d);
+            Self::from_u8_unchecked(byte)
+        }
+    }
+
+    /// Gets this ASCII character as a byte.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_u8(self) -> u8 {
+        self as u8
+    }
+
+    /// Gets this ASCII character as a `char` Unicode Scalar Value.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_char(self) -> char {
+        self as u8 as char
+    }
+
+    /// Views this ASCII character as a one-code-unit UTF-8 `str`.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_str(&self) -> &str {
+        crate::slice::from_ref(self).as_str()
+    }
+}
+
+impl [AsciiChar] {
+    /// Views this slice of ASCII characters as a UTF-8 `str`.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_str(&self) -> &str {
+        let ascii_ptr: *const Self = self;
+        let str_ptr = ascii_ptr as *const str;
+        // SAFETY: Each ASCII codepoint in UTF-8 is encoded as one single-byte
+        // code unit having the same value as the ASCII byte.
+        unsafe { &*str_ptr }
+    }
+
+    /// Views this slice of ASCII characters as a slice of `u8` bytes.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_bytes(&self) -> &[u8] {
+        self.as_str().as_bytes()
+    }
+}
+
+#[unstable(feature = "ascii_char", issue = "110998")]
+impl fmt::Display for AsciiChar {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        <str as fmt::Display>::fmt(self.as_str(), f)
+    }
+}
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 2408f178075..1dfa9c34db1 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1,5 +1,6 @@
 //! impl char {}
 
+use crate::ascii;
 use crate::slice;
 use crate::str::from_utf8_unchecked_mut;
 use crate::unicode::printable::is_printable;
@@ -1101,6 +1102,24 @@ impl char {
         *self as u32 <= 0x7F
     }
 
+    /// Returns `Some` if the value is within the ASCII range,
+    /// or `None` if it's not.
+    ///
+    /// This is preferred to [`Self::is_ascii`] when you're passing the value
+    /// along to something else that can take [`ascii::Char`] rather than
+    /// needing to check again for itself whether the value is in ASCII.
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_ascii(&self) -> Option<ascii::Char> {
+        if self.is_ascii() {
+            // SAFETY: Just checked that this is ASCII.
+            Some(unsafe { ascii::Char::from_u8_unchecked(*self as u8) })
+        } else {
+            None
+        }
+    }
+
     /// Makes a copy of the value in its ASCII upper case equivalent.
     ///
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index fdd7be625ed..08444421dca 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -472,7 +472,16 @@ impl u8 {
     #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")]
     #[inline]
     pub const fn is_ascii(&self) -> bool {
-        *self & 128 == 0
+        *self <= 127
+    }
+
+    /// If the value of this byte is within the ASCII range, returns it as an
+    /// [ASCII character](ascii::Char).  Otherwise, returns `None`.
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn as_ascii(&self) -> Option<ascii::Char> {
+        ascii::Char::from_u8(*self)
     }
 
     /// Makes a copy of the value in its ASCII upper case equivalent.
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index b80bfe1c92d..74a325b89d4 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -713,6 +713,32 @@ macro_rules! nonzero_signed_operations {
                     unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
                 }
 
+                /// Returns `true` if `self` is positive and `false` if the
+                /// number is negative.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_negation_ops)]
+                ///
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+                ///
+                /// assert!(pos_five.is_positive());
+                /// assert!(!neg_five.is_positive());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[must_use]
+                #[inline]
+                #[unstable(feature = "nonzero_negation_ops", issue = "102443")]
+                pub const fn is_positive(self) -> bool {
+                    self.get().is_positive()
+                }
+
                 /// Returns `true` if `self` is negative and `false` if the
                 /// number is positive.
                 ///
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 5e5399acc1b..7bae6692ad4 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -16,6 +16,36 @@ impl [u8] {
         is_ascii(self)
     }
 
+    /// If this slice [`is_ascii`](Self::is_ascii), returns it as a slice of
+    /// [ASCII characters](`ascii::Char`), otherwise returns `None`.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[must_use]
+    #[inline]
+    pub fn as_ascii(&self) -> Option<&[ascii::Char]> {
+        if self.is_ascii() {
+            // SAFETY: Just checked that it's ASCII
+            Some(unsafe { self.as_ascii_unchecked() })
+        } else {
+            None
+        }
+    }
+
+    /// Converts this slice of bytes into a slice of ASCII characters,
+    /// without checking whether they're valid.
+    ///
+    /// # Safety
+    ///
+    /// Every byte in the slice must be in `0..=127`, or else this is UB.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[must_use]
+    #[inline]
+    pub const unsafe fn as_ascii_unchecked(&self) -> &[ascii::Char] {
+        let byte_ptr: *const [u8] = self;
+        let ascii_ptr = byte_ptr as *const [ascii::Char];
+        // SAFETY: The caller promised all the bytes are ASCII
+        unsafe { &*ascii_ptr }
+    }
+
     /// Checks that two slices are an ASCII case-insensitive match.
     ///
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index a13107fd0de..66fa9cf6f64 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -16,6 +16,7 @@ mod validations;
 use self::pattern::Pattern;
 use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
 
+use crate::ascii;
 use crate::char::{self, EscapeDebugExtArgs};
 use crate::mem;
 use crate::slice::{self, SliceIndex};
@@ -2366,6 +2367,16 @@ impl str {
         self.as_bytes().is_ascii()
     }
 
+    /// If this string slice [`is_ascii`](Self::is_ascii), returns it as a slice
+    /// of [ASCII characters](`ascii::Char`), otherwise returns `None`.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[must_use]
+    #[inline]
+    pub fn as_ascii(&self) -> Option<&[ascii::Char]> {
+        // Like in `is_ascii`, we can work on the bytes directly.
+        self.as_bytes().as_ascii()
+    }
+
     /// Checks that two strings are an ASCII case-insensitive match.
     ///
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
diff --git a/library/std/src/ascii.rs b/library/std/src/ascii.rs
index c29f015777f..b18ab50de12 100644
--- a/library/std/src/ascii.rs
+++ b/library/std/src/ascii.rs
@@ -16,6 +16,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::ascii::{escape_default, EscapeDefault};
 
+#[unstable(feature = "ascii_char", issue = "110998")]
+pub use core::ascii::Char;
+
 /// Extension methods for ASCII-subset only operations.
 ///
 /// Be aware that operations on seemingly non-ASCII characters can sometimes
diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs
index 951d509ec95..77f64588310 100644
--- a/library/std/src/sys/common/thread_local/mod.rs
+++ b/library/std/src/sys/common/thread_local/mod.rs
@@ -1,5 +1,10 @@
 #![unstable(feature = "thread_local_internals", reason = "should not be necessary", issue = "none")]
 
+// There are three thread-local implementations: "static", "fast", "OS".
+// The "OS" thread local key type is accessed via platform-specific API calls and is slow, while the
+// "fast" key type is accessed via code generated via LLVM, where TLS keys are set up by the linker.
+// "static" is for single-threaded platforms where a global static is sufficient.
+
 cfg_if::cfg_if! {
     if #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] {
         #[doc(hidden)]
diff --git a/library/std/src/sys/common/thread_local/os_local.rs b/library/std/src/sys/common/thread_local/os_local.rs
index d004897df28..5d48ce1e03b 100644
--- a/library/std/src/sys/common/thread_local/os_local.rs
+++ b/library/std/src/sys/common/thread_local/os_local.rs
@@ -18,7 +18,7 @@ pub macro thread_local_inner {
         ) -> $crate::option::Option<&'static $t> {
             const INIT_EXPR: $t = $init;
 
-                        // On platforms without `#[thread_local]` we fall back to the
+            // On platforms without `#[thread_local]` we fall back to the
             // same implementation as below for os thread locals.
             #[inline]
             const fn __init() -> $t { INIT_EXPR }
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 9cdc17a287c..f712c872708 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -193,22 +193,22 @@ pub use scoped::{scope, Scope, ScopedJoinHandle};
 #[macro_use]
 mod local;
 
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::local::{AccessError, LocalKey};
-
-// Provide the type used by the thread_local! macro to access TLS keys. This
-// needs to be kept in sync with the macro itself (in `local.rs`).
-// There are three types: "static", "fast", "OS". The "OS" thread local key
-// type is accessed via platform-specific API calls and is slow, while the "fast"
-// key type is accessed via code generated via LLVM, where TLS keys are set up
-// by the elf linker. "static" is for single-threaded platforms where a global
-// static is sufficient.
-
-// Implementation details used by the thread_local!{} macro.
-#[doc(hidden)]
-#[unstable(feature = "thread_local_internals", issue = "none")]
-pub mod local_impl {
-    pub use crate::sys::common::thread_local::{thread_local_inner, Key};
+cfg_if::cfg_if! {
+    if #[cfg(test)] {
+        // Avoid duplicating the global state assoicated with thread-locals between this crate and
+        // realstd. Miri relies on this.
+        pub use realstd::thread::{local_impl, AccessError, LocalKey};
+    } else {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub use self::local::{AccessError, LocalKey};
+
+        // Implementation details used by the thread_local!{} macro.
+        #[doc(hidden)]
+        #[unstable(feature = "thread_local_internals", issue = "none")]
+        pub mod local_impl {
+            pub use crate::sys::common::thread_local::{thread_local_inner, Key};
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml
new file mode 100644
index 00000000000..5356ee277cc
--- /dev/null
+++ b/library/sysroot/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+name = "sysroot"
+version = "0.0.0"
+edition = "2021"
+
+# this is a dummy crate to ensure that all required crates appear in the sysroot
+[dependencies]
+proc_macro = { path = "../proc_macro" }
+std = { path = "../std" }
+test = { path = "../test" }
+
+# Forward features to the `std` crate as necessary
+[features]
+default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
+backtrace = ["std/backtrace"]
+compiler-builtins-c = ["std/compiler-builtins-c"]
+compiler-builtins-mem = ["std/compiler-builtins-mem"]
+compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"]
+compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"]
+llvm-libunwind = ["std/llvm-libunwind"]
+system-llvm-libunwind = ["std/system-llvm-libunwind"]
+panic-unwind = ["std/panic_unwind"]
+panic_immediate_abort = ["std/panic_immediate_abort"]
+profiler = ["std/profiler"]
+std_detect_file_io = ["std/std_detect_file_io"]
+std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
+std_detect_env_override = ["std/std_detect_env_override"]
diff --git a/library/sysroot/src/lib.rs b/library/sysroot/src/lib.rs
new file mode 100644
index 00000000000..71ceb580a40
--- /dev/null
+++ b/library/sysroot/src/lib.rs
@@ -0,0 +1 @@
+// This is intentionally empty since this crate is only used to depend on other library crates.
diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml
index 18cb023d274..91a1abde059 100644
--- a/library/test/Cargo.toml
+++ b/library/test/Cargo.toml
@@ -12,23 +12,3 @@ std = { path = "../std" }
 core = { path = "../core" }
 panic_unwind = { path = "../panic_unwind" }
 panic_abort = { path = "../panic_abort" }
-
-# not actually used but needed to always have proc_macro in the sysroot
-proc_macro = { path = "../proc_macro" }
-
-# Forward features to the `std` crate as necessary
-[features]
-default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
-backtrace = ["std/backtrace"]
-compiler-builtins-c = ["std/compiler-builtins-c"]
-compiler-builtins-mem = ["std/compiler-builtins-mem"]
-compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"]
-compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"]
-llvm-libunwind = ["std/llvm-libunwind"]
-system-llvm-libunwind = ["std/system-llvm-libunwind"]
-panic-unwind = ["std/panic_unwind"]
-panic_immediate_abort = ["std/panic_immediate_abort"]
-profiler = ["std/profiler"]
-std_detect_file_io = ["std/std_detect_file_io"]
-std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
-std_detect_env_override = ["std/std_detect_env_override"]
diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs
index 2e07ce3c099..9f5bf24367e 100644
--- a/library/test/src/formatters/junit.rs
+++ b/library/test/src/formatters/junit.rs
@@ -11,7 +11,7 @@ use crate::{
 
 pub struct JunitFormatter<T> {
     out: OutputLocation<T>,
-    results: Vec<(TestDesc, TestResult, Duration)>,
+    results: Vec<(TestDesc, TestResult, Duration, Vec<u8>)>,
 }
 
 impl<T: Write> JunitFormatter<T> {
@@ -26,6 +26,18 @@ impl<T: Write> JunitFormatter<T> {
     }
 }
 
+fn str_to_cdata(s: &str) -> String {
+    // Drop the stdout in a cdata. Unfortunately, you can't put either of `]]>` or
+    // `<?'` in a CDATA block, so the escaping gets a little weird.
+    let escaped_output = s.replace("]]>", "]]]]><![CDATA[>");
+    let escaped_output = escaped_output.replace("<?", "<]]><![CDATA[?");
+    // We also smuggle newlines as &#xa so as to keep all the output on one line
+    let escaped_output = escaped_output.replace("\n", "]]>&#xA;<![CDATA[");
+    // Prune empty CDATA blocks resulting from any escaping
+    let escaped_output = escaped_output.replace("<![CDATA[]]>", "");
+    format!("<![CDATA[{}]]>", escaped_output)
+}
+
 impl<T: Write> OutputFormatter for JunitFormatter<T> {
     fn write_discovery_start(&mut self) -> io::Result<()> {
         Err(io::Error::new(io::ErrorKind::NotFound, "Not yet implemented!"))
@@ -63,14 +75,14 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
         desc: &TestDesc,
         result: &TestResult,
         exec_time: Option<&time::TestExecTime>,
-        _stdout: &[u8],
+        stdout: &[u8],
         _state: &ConsoleTestState,
     ) -> io::Result<()> {
         // Because the testsuite node holds some of the information as attributes, we can't write it
         // until all of the tests have finished. Instead of writing every result as they come in, we add
         // them to a Vec and write them all at once when run is complete.
         let duration = exec_time.map(|t| t.0).unwrap_or_default();
-        self.results.push((desc.clone(), result.clone(), duration));
+        self.results.push((desc.clone(), result.clone(), duration, stdout.to_vec()));
         Ok(())
     }
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
@@ -85,7 +97,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
              >",
             state.failed, state.total, state.ignored
         ))?;
-        for (desc, result, duration) in std::mem::take(&mut self.results) {
+        for (desc, result, duration, stdout) in std::mem::take(&mut self.results) {
             let (class_name, test_name) = parse_class_name(&desc);
             match result {
                 TestResult::TrIgnored => { /* no-op */ }
@@ -98,6 +110,11 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                         duration.as_secs_f64()
                     ))?;
                     self.write_message("<failure type=\"assert\"/>")?;
+                    if !stdout.is_empty() {
+                        self.write_message("<system-out>")?;
+                        self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?;
+                        self.write_message("</system-out>")?;
+                    }
                     self.write_message("</testcase>")?;
                 }
 
@@ -110,6 +127,11 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                         duration.as_secs_f64()
                     ))?;
                     self.write_message(&format!("<failure message=\"{m}\" type=\"assert\"/>"))?;
+                    if !stdout.is_empty() {
+                        self.write_message("<system-out>")?;
+                        self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?;
+                        self.write_message("</system-out>")?;
+                    }
                     self.write_message("</testcase>")?;
                 }
 
@@ -136,11 +158,19 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                 TestResult::TrOk => {
                     self.write_message(&format!(
                         "<testcase classname=\"{}\" \
-                         name=\"{}\" time=\"{}\"/>",
+                         name=\"{}\" time=\"{}\"",
                         class_name,
                         test_name,
                         duration.as_secs_f64()
                     ))?;
+                    if stdout.is_empty() || !state.options.display_output {
+                        self.write_message("/>")?;
+                    } else {
+                        self.write_message("><system-out>")?;
+                        self.write_message(&str_to_cdata(&String::from_utf8_lossy(&stdout)))?;
+                        self.write_message("</system-out>")?;
+                        self.write_message("</testcase>")?;
+                    }
                 }
             }
         }
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 60de46ce64c..956b82385f6 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -79,7 +79,7 @@ impl Step for Std {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("test").path("library")
+        run.all_krates("sysroot").path("library")
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs
index 7ebd0a8f270..0d9fd56b038 100644
--- a/src/bootstrap/clean.rs
+++ b/src/bootstrap/clean.rs
@@ -81,7 +81,7 @@ macro_rules! clean_crate_tree {
 
 clean_crate_tree! {
     Rustc, Mode::Rustc, "rustc-main";
-    Std, Mode::Std, "test";
+    Std, Mode::Std, "sysroot";
 }
 
 fn clean_default(build: &Build, all: bool) {
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 7d2a6862500..966ae00fa1d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -56,7 +56,7 @@ impl Step for Std {
         // When downloading stage1, the standard library has already been copied to the sysroot, so
         // there's no need to rebuild it.
         let builder = run.builder;
-        run.crate_or_deps("test")
+        run.crate_or_deps("sysroot")
             .path("library")
             .lazy_default_condition(Box::new(|| !builder.download_rustc()))
     }
@@ -364,7 +364,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
             .arg("--features")
             .arg(features)
             .arg("--manifest-path")
-            .arg(builder.src.join("library/test/Cargo.toml"));
+            .arg(builder.src.join("library/sysroot/Cargo.toml"));
 
         // Help the libc crate compile by assisting it in finding various
         // sysroot native libraries.
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 3b35ca1d15d..9cead7adc8c 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -822,6 +822,8 @@ fn copy_src_dirs(
             "llvm-project\\compiler-rt",
             "llvm-project/cmake",
             "llvm-project\\cmake",
+            "llvm-project/runtimes",
+            "llvm-project\\runtimes",
         ];
         if spath.contains("llvm-project")
             && !spath.ends_with("llvm-project")
@@ -976,6 +978,7 @@ impl Step for PlainSourceTarball {
             "config.example.toml",
             "Cargo.toml",
             "Cargo.lock",
+            ".gitmodules",
         ];
         let src_dirs = ["src", "compiler", "library", "tests"];
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 9ad98eb5702..8f5d9bb66e1 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -438,7 +438,7 @@ impl Step for Std {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.all_krates("test").path("library").default_condition(builder.config.docs)
+        run.all_krates("sysroot").path("library").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index aee84e9c9be..cfccb516627 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -2145,7 +2145,7 @@ impl Step for Crate {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.crate_or_deps("test")
+        run.crate_or_deps("sysroot")
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/tests/codegen/ascii-char.rs b/tests/codegen/ascii-char.rs
new file mode 100644
index 00000000000..4167becf5e9
--- /dev/null
+++ b/tests/codegen/ascii-char.rs
@@ -0,0 +1,37 @@
+// compile-flags: -C opt-level=1
+// ignore-debug (the extra assertions get in the way)
+
+#![crate_type = "lib"]
+#![feature(ascii_char)]
+
+use std::ascii::Char as AsciiChar;
+
+// CHECK-LABEL: i8 @unwrap_digit_from_remainder(i32
+#[no_mangle]
+pub fn unwrap_digit_from_remainder(v: u32) -> AsciiChar {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: panic
+
+    // CHECK: %[[R:.+]] = urem i32 %v, 10
+    // CHECK-NEXT: %[[T:.+]] = trunc i32 %[[R]] to i8
+    // CHECK-NEXT: %[[D:.+]] = or i8 %[[T]], 48
+    // CHECK-NEXT: ret i8 %[[D]]
+
+    // CHECK-NOT: icmp
+    // CHECK-NOT: panic
+    AsciiChar::digit((v % 10) as u8).unwrap()
+}
+
+// CHECK-LABEL: i8 @unwrap_from_masked(i8
+#[no_mangle]
+pub fn unwrap_from_masked(b: u8) -> AsciiChar {
+    // CHECK-NOT: icmp
+    // CHECK-NOT: panic
+
+    // CHECK: %[[M:.+]] = and i8 %b, 127
+    // CHECK-NEXT: ret i8 %[[M]]
+
+    // CHECK-NOT: icmp
+    // CHECK-NOT: panic
+    AsciiChar::from_u8(b & 0x7f).unwrap()
+}
diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs
index 8c35f6ca000..f518266016e 100644
--- a/tests/incremental/change_crate_dep_kind.rs
+++ b/tests/incremental/change_crate_dep_kind.rs
@@ -2,6 +2,7 @@
 // detected then -Zincremental-verify-ich will trigger an assertion.
 
 // ignore-wasm32-bare compiled with panic=abort by default
+// needs-unwind
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph -Cpanic=unwind
 // build-pass (FIXME(62277): could be check-pass?)
diff --git a/tests/incremental/issue-80691-bad-eval-cache.rs b/tests/incremental/issue-80691-bad-eval-cache.rs
index 1a644fd88d6..ad8a338a796 100644
--- a/tests/incremental/issue-80691-bad-eval-cache.rs
+++ b/tests/incremental/issue-80691-bad-eval-cache.rs
@@ -1,6 +1,7 @@
 // revisions: rfail1 rfail2
 // failure-status: 101
 // error-pattern: not implemented
+// needs-unwind -Cpanic=abort causes abort instead of exit(101)
 
 pub trait Interner {
     type InternedVariableKinds;
diff --git a/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff b/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff
new file mode 100644
index 00000000000..d50b12044ce
--- /dev/null
+++ b/tests/mir-opt/const_prop/address_of_pair.fn0.ConstProp.diff
@@ -0,0 +1,46 @@
+- // MIR for `fn0` before ConstProp
++ // MIR for `fn0` after ConstProp
+  
+  fn fn0() -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/address_of_pair.rs:+0:17: +0:21
+      let mut _1: !;                       // in scope 0 at $DIR/address_of_pair.rs:+0:22: +9:2
+      let mut _2: (i32, bool);             // in scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17
+      let _4: ();                          // in scope 0 at $DIR/address_of_pair.rs:+4:5: +6:6
+      let mut _6: bool;                    // in scope 0 at $DIR/address_of_pair.rs:+7:16: +7:22
+      scope 1 {
+          debug pair => _2;                // in scope 1 at $DIR/address_of_pair.rs:+1:9: +1:17
+          let _3: *mut bool;               // in scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12
+          scope 2 {
+              debug ptr => _3;             // in scope 2 at $DIR/address_of_pair.rs:+2:9: +2:12
+              let _5: bool;                // in scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12
+              scope 3 {
+              }
+              scope 4 {
+                  debug ret => _5;         // in scope 4 at $DIR/address_of_pair.rs:+7:9: +7:12
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17
+          _2 = (const 1_i32, const false); // scope 0 at $DIR/address_of_pair.rs:+1:20: +1:30
+          StorageLive(_3);                 // scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12
+          _3 = &raw mut (_2.1: bool);      // scope 1 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+          _2 = (const 1_i32, const false); // scope 2 at $DIR/address_of_pair.rs:+3:5: +3:22
+          StorageLive(_4);                 // scope 2 at $DIR/address_of_pair.rs:+4:5: +6:6
+          (*_3) = const true;              // scope 3 at $DIR/address_of_pair.rs:+5:9: +5:20
+          _4 = const ();                   // scope 3 at $DIR/address_of_pair.rs:+4:5: +6:6
+          StorageDead(_4);                 // scope 2 at $DIR/address_of_pair.rs:+6:5: +6:6
+          StorageLive(_5);                 // scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12
+          StorageLive(_6);                 // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22
+          _6 = (_2.1: bool);               // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22
+          _5 = Not(move _6);               // scope 2 at $DIR/address_of_pair.rs:+7:15: +7:22
+          StorageDead(_6);                 // scope 2 at $DIR/address_of_pair.rs:+7:21: +7:22
+          _0 = _5;                         // scope 4 at $DIR/address_of_pair.rs:+8:12: +8:15
+          StorageDead(_5);                 // scope 2 at $DIR/address_of_pair.rs:+9:1: +9:2
+          StorageDead(_3);                 // scope 1 at $DIR/address_of_pair.rs:+9:1: +9:2
+          StorageDead(_2);                 // scope 0 at $DIR/address_of_pair.rs:+9:1: +9:2
+          return;                          // scope 0 at $DIR/address_of_pair.rs:+9:2: +9:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/address_of_pair.rs b/tests/mir-opt/const_prop/address_of_pair.rs
new file mode 100644
index 00000000000..43dc9bae625
--- /dev/null
+++ b/tests/mir-opt/const_prop/address_of_pair.rs
@@ -0,0 +1,17 @@
+// unit-test: ConstProp
+
+// EMIT_MIR address_of_pair.fn0.ConstProp.diff
+pub fn fn0() -> bool {
+    let mut pair = (1, false);
+    let ptr = core::ptr::addr_of_mut!(pair.1);
+    pair = (1, false);
+    unsafe {
+        *ptr = true;
+    }
+    let ret = !pair.1;
+    return ret;
+}
+
+pub fn main() {
+    println!("{}", fn0());
+}
diff --git a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
index def9fc6428f..a5f52d08957 100644
--- a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
+++ b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
@@ -19,8 +19,7 @@
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
--         _1 = (const 1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
-+         _1 = const (1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+          _1 = (const 1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
           StorageLive(_2);                 // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
           StorageLive(_3);                 // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
           _3 = &raw mut (_1.0: i32);       // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
diff --git a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
index b54c10a140f..42ddc2a5620 100644
--- a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
+++ b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
@@ -16,8 +16,7 @@
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
--         _1 = (const 1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
-+         _1 = const (1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
+          _1 = (const 1_i32,);             // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
           StorageLive(_2);                 // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
           _2 = &mut (_1.0: i32);           // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
           (*_2) = const 5_i32;             // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +2:18
diff --git a/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff
new file mode 100644
index 00000000000..761c074ed94
--- /dev/null
+++ b/tests/mir-opt/dead-store-elimination/place_mention.main.DeadStoreElimination.diff
@@ -0,0 +1,25 @@
+- // MIR for `main` before DeadStoreElimination
++ // MIR for `main` after DeadStoreElimination
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/place_mention.rs:+0:11: +0:11
+      let mut _1: (&str, &str);            // in scope 0 at $DIR/place_mention.rs:+3:18: +3:36
+      scope 1 {
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/place_mention.rs:+3:18: +3:36
+          _1 = (const "Hello", const "World"); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36
+                                           // mir::Constant
+                                           // + span: $DIR/place_mention.rs:8:19: 8:26
+                                           // + literal: Const { ty: &str, val: Value(Slice(..)) }
+                                           // mir::Constant
+                                           // + span: $DIR/place_mention.rs:8:28: 8:35
+                                           // + literal: Const { ty: &str, val: Value(Slice(..)) }
+          PlaceMention(_1);                // scope 0 at $DIR/place_mention.rs:+3:18: +3:36
+          StorageDead(_1);                 // scope 0 at $DIR/place_mention.rs:+3:36: +3:37
+          _0 = const ();                   // scope 0 at $DIR/place_mention.rs:+0:11: +4:2
+          return;                          // scope 0 at $DIR/place_mention.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dead-store-elimination/place_mention.rs b/tests/mir-opt/dead-store-elimination/place_mention.rs
new file mode 100644
index 00000000000..59dc74454a4
--- /dev/null
+++ b/tests/mir-opt/dead-store-elimination/place_mention.rs
@@ -0,0 +1,9 @@
+// unit-test: DeadStoreElimination
+// compile-flags: -Zmir-keep-place-mention
+
+// EMIT_MIR place_mention.main.DeadStoreElimination.diff
+fn main() {
+    // Verify that we account for the `PlaceMention` statement as a use of the tuple,
+    // and don't remove it as a dead store.
+    let (_, _) = ("Hello", "World");
+}
diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile
index 9c41a5a717e..b8e0e9483cd 100644
--- a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile
+++ b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all: archive
diff --git a/tests/run-make/c-unwind-abi-catch-panic/Makefile b/tests/run-make/c-unwind-abi-catch-panic/Makefile
index 4398ac2ee24..1760ddb3061 100644
--- a/tests/run-make/c-unwind-abi-catch-panic/Makefile
+++ b/tests/run-make/c-unwind-abi-catch-panic/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all: $(call NATIVE_STATICLIB,add)
diff --git a/tests/run-make/const_fn_mir/Makefile b/tests/run-make/const_fn_mir/Makefile
index b2c268f0439..6d72c122723 100644
--- a/tests/run-make/const_fn_mir/Makefile
+++ b/tests/run-make/const_fn_mir/Makefile
@@ -1,3 +1,4 @@
+# needs-unwind -Cpanic=abort gives different MIR output
 include ../tools.mk
 
 all:
diff --git a/tests/run-make/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile
index e83337c597f..4501459e9d1 100644
--- a/tests/run-make/debug-assertions/Makefile
+++ b/tests/run-make/debug-assertions/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all:
diff --git a/tests/run-make/foreign-double-unwind/Makefile b/tests/run-make/foreign-double-unwind/Makefile
index f20fe3ce66e..b5e52808d2f 100644
--- a/tests/run-make/foreign-double-unwind/Makefile
+++ b/tests/run-make/foreign-double-unwind/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all: foo
diff --git a/tests/run-make/foreign-exceptions/Makefile b/tests/run-make/foreign-exceptions/Makefile
index a8e20ffb1f4..56c41b274fb 100644
--- a/tests/run-make/foreign-exceptions/Makefile
+++ b/tests/run-make/foreign-exceptions/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all: foo
diff --git a/tests/run-make/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile
index 0d007bf1c49..59cee284200 100644
--- a/tests/run-make/foreign-rust-exceptions/Makefile
+++ b/tests/run-make/foreign-rust-exceptions/Makefile
@@ -1,5 +1,6 @@
 # ignore-cross-compile
 # ignore-i686-pc-windows-gnu
+# needs-unwind
 
 # This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder
 # so cross-DLL unwinding does not work.
diff --git a/tests/run-make/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile
index 417637cf072..c8bc7b5dd4a 100644
--- a/tests/run-make/libtest-json/Makefile
+++ b/tests/run-make/libtest-json/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 # Test expected libtest's JSON output
diff --git a/tests/run-make/libtest-junit/Makefile b/tests/run-make/libtest-junit/Makefile
new file mode 100644
index 00000000000..d97cafccf1f
--- /dev/null
+++ b/tests/run-make/libtest-junit/Makefile
@@ -0,0 +1,19 @@
+# ignore-cross-compile
+include ../tools.mk
+
+# Test expected libtest's junit output
+
+OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-junit-output-default.xml
+OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-junit-output-stdout-success.xml
+
+all: f.rs validate_junit.py output-default.xml output-stdout-success.xml
+	$(RUSTC) --test f.rs
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit > $(OUTPUT_FILE_DEFAULT) || true
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=junit --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true
+
+	cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_junit.py
+	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_junit.py
+
+	# Normalize the actual output and compare to expected output file
+	cat $(OUTPUT_FILE_DEFAULT) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-default.xml -
+	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | sed 's/time="[0-9.]*"/time="$$TIME"/g' | diff output-stdout-success.xml -
diff --git a/tests/run-make/libtest-junit/f.rs b/tests/run-make/libtest-junit/f.rs
new file mode 100644
index 00000000000..d360d77317d
--- /dev/null
+++ b/tests/run-make/libtest-junit/f.rs
@@ -0,0 +1,23 @@
+#[test]
+fn a() {
+    println!("print from successful test");
+    // Should pass
+}
+
+#[test]
+fn b() {
+    println!("print from failing test");
+    assert!(false);
+}
+
+#[test]
+#[should_panic]
+fn c() {
+    assert!(false);
+}
+
+#[test]
+#[ignore = "msg"]
+fn d() {
+    assert!(false);
+}
diff --git a/tests/run-make/libtest-junit/output-default.xml b/tests/run-make/libtest-junit/output-default.xml
new file mode 100644
index 00000000000..d59e07b8ad8
--- /dev/null
+++ b/tests/run-make/libtest-junit/output-default.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"/><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;<![CDATA[thread 'b' panicked at 'assertion failed: false', f.rs:10:5]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
diff --git a/tests/run-make/libtest-junit/output-stdout-success.xml b/tests/run-make/libtest-junit/output-stdout-success.xml
new file mode 100644
index 00000000000..0c300611e1f
--- /dev/null
+++ b/tests/run-make/libtest-junit/output-stdout-success.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"><system-out><![CDATA[print from successful test]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;<![CDATA[thread 'b' panicked at 'assertion failed: false', f.rs:10:5]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"><system-out><![CDATA[thread 'c' panicked at 'assertion failed: false', f.rs:16:5]]>&#xA;<![CDATA[]]></system-out></testcase><system-out/><system-err/></testsuite></testsuites>
diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py
new file mode 100755
index 00000000000..47a8e70ccc3
--- /dev/null
+++ b/tests/run-make/libtest-junit/validate_junit.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+import sys
+import xml.etree.ElementTree as ET
+
+# Try to decode line in order to ensure it is a valid XML document
+for line in sys.stdin:
+    try:
+        ET.fromstring(line)
+    except ET.ParseError as pe:
+        print("Invalid xml: %r" % line)
+        raise
diff --git a/tests/run-make/static-unwinding/Makefile b/tests/run-make/static-unwinding/Makefile
index dec94fb16f4..4b093f93608 100644
--- a/tests/run-make/static-unwinding/Makefile
+++ b/tests/run-make/static-unwinding/Makefile
@@ -1,4 +1,5 @@
 # ignore-cross-compile
+# needs-unwind
 include ../tools.mk
 
 all:
diff --git a/tests/run-make/test-benches/Makefile b/tests/run-make/test-benches/Makefile
index 0253a52637f..11aed2e4c79 100644
--- a/tests/run-make/test-benches/Makefile
+++ b/tests/run-make/test-benches/Makefile
@@ -1,6 +1,7 @@
 include ../tools.mk
 
 # ignore-cross-compile
+# needs-unwind #[bench] and -Zpanic-abort-tests can't be combined
 
 all:
 	# Smoke-test that `#[bench]` isn't entirely broken.
diff --git a/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
index d45a6465b76..18a99398622 100644
--- a/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
+++ b/tests/ui/const-generics/generic_const_exprs/nested_uneval_unification-2.rs
@@ -2,28 +2,30 @@
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features, unused_parens, unused_braces)]
 
-fn zero_init<const N: usize>() -> Substs1<{ (N) }>
+fn zero_init<const N: usize>() -> Substs1<{{ N }}>
 where
-    [u8; { (N) }]: ,
+    [u8; {{ N }}]: ,
 {
-    Substs1([0; { (N) }])
+    Substs1([0; {{ N }}])
 }
 
-struct Substs1<const N: usize>([u8; { (N) }])
+struct Substs1<const N: usize>([u8; {{ N }}])
 where
-    [(); { (N) }]: ;
+    [(); {{ N }}]: ;
 
-fn substs2<const M: usize>() -> Substs1<{ (M) }> {
-    zero_init::<{ (M) }>()
+fn substs2<const M: usize>() -> Substs1<{{ M }}> {
+    zero_init::<{{ M }}>()
 }
 
-fn substs3<const L: usize>() -> Substs1<{ (L) }> {
-    substs2::<{ (L) }>()
+fn substs3<const L: usize>() -> Substs1<{{ L }}> {
+    substs2::<{{ L }}>()
 }
 
 fn main() {
     assert_eq!(substs3::<2>().0, [0; 2]);
 }
 
-// Test that the implicit ``{ (L) }`` bound on ``substs3`` satisfies the
-// ``{ (N) }`` bound on ``Substs1``
+// Test that the implicit ``{{ L }}`` bound on ``substs3`` satisfies the
+// ``{{ N }}`` bound on ``Substs1``
+// FIXME(generic_const_exprs): come up with a less brittle test for this using assoc consts
+// once normalization is implemented for them.
diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.rs b/tests/ui/const-generics/sneaky-array-repeat-expr.rs
index b147c246bda..cd1607608a6 100644
--- a/tests/ui/const-generics/sneaky-array-repeat-expr.rs
+++ b/tests/ui/const-generics/sneaky-array-repeat-expr.rs
@@ -10,6 +10,7 @@ impl<const N: usize> Trait<N> for () {
 pub const fn foo<const N: usize>() where (): Trait<N> {
     let bar = [(); <()>::Assoc];
     //~^ error: constant expression depends on a generic parameter
+    //~| error: constant expression depends on a generic parameter
 }
 
 trait Trait2<const N: usize> {
@@ -24,6 +25,7 @@ impl<const N: usize> Trait2<N> for () {
 pub const fn foo2<const N: usize>() where (): Trait2<N> {
     let bar2 = [(); <()>::Assoc2];
     //~^ error: constant expression depends on a generic parameter
+    //~| error: constant expression depends on a generic parameter
 }
 
 fn main() {
diff --git a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr
index 5c77375d399..e532f27a10d 100644
--- a/tests/ui/const-generics/sneaky-array-repeat-expr.stderr
+++ b/tests/ui/const-generics/sneaky-array-repeat-expr.stderr
@@ -7,12 +7,28 @@ LL |     let bar = [(); <()>::Assoc];
    = note: this may fail depending on what value the parameter takes
 
 error: constant expression depends on a generic parameter
-  --> $DIR/sneaky-array-repeat-expr.rs:25:21
+  --> $DIR/sneaky-array-repeat-expr.rs:11:15
+   |
+LL |     let bar = [(); <()>::Assoc];
+   |               ^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/sneaky-array-repeat-expr.rs:26:21
    |
 LL |     let bar2 = [(); <()>::Assoc2];
    |                     ^^^^^^^^^^^^
    |
    = note: this may fail depending on what value the parameter takes
 
-error: aborting due to 2 previous errors
+error: constant expression depends on a generic parameter
+  --> $DIR/sneaky-array-repeat-expr.rs:26:16
+   |
+LL |     let bar2 = [(); <()>::Assoc2];
+   |                ^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs
index 42aa0216b87..3704a1a5a39 100644
--- a/tests/ui/consts/const-block-const-bound.rs
+++ b/tests/ui/consts/const-block-const-bound.rs
@@ -11,15 +11,9 @@ impl Drop for UnconstDrop {
     fn drop(&mut self) {}
 }
 
-struct NonDrop;
-
-impl !Drop for NonDrop {}
-
 fn main() {
     const {
         f(UnconstDrop);
         //~^ ERROR can't drop
-        f(NonDrop);
-        //~^ ERROR can't drop
     }
 }
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index fef4914fad5..caf24e7afcf 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't drop `UnconstDrop` in const contexts
-  --> $DIR/const-block-const-bound.rs:20:9
+  --> $DIR/const-block-const-bound.rs:16:9
    |
 LL |         f(UnconstDrop);
    |         ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop`
@@ -12,20 +12,6 @@ LL |         &f(UnconstDrop);
 LL |         &mut f(UnconstDrop);
    |         ++++
 
-error[E0277]: can't drop `NonDrop` in const contexts
-  --> $DIR/const-block-const-bound.rs:22:9
-   |
-LL |         f(NonDrop);
-   |         ^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop`
-   |
-   = note: the trait bound `NonDrop: ~const Destruct` is not satisfied
-help: consider borrowing here
-   |
-LL |         &f(NonDrop);
-   |         +
-LL |         &mut f(NonDrop);
-   |         ++++
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/issue-50439.rs b/tests/ui/consts/issue-50439.rs
index 0be7c405473..d42347e136e 100644
--- a/tests/ui/consts/issue-50439.rs
+++ b/tests/ui/consts/issue-50439.rs
@@ -22,7 +22,9 @@ impl<T: Sized> PinDropInternal for Bears<T> {
     where
         Self: ReflectDrop,
     {
-        let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize]; //~ ERROR constant expression depends on a generic parameter
+        let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
+        //~^ ERROR constant expression depends on a generic parameter
+        //~| ERROR constant expression depends on a generic parameter
     }
 }
 
diff --git a/tests/ui/consts/issue-50439.stderr b/tests/ui/consts/issue-50439.stderr
index 3fbdf33b2d8..7a8cd45ecc7 100644
--- a/tests/ui/consts/issue-50439.stderr
+++ b/tests/ui/consts/issue-50439.stderr
@@ -6,5 +6,13 @@ LL |         let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usi
    |
    = note: this may fail depending on what value the parameter takes
 
-error: aborting due to previous error
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-50439.rs:25:17
+   |
+LL |         let _ = [(); 0 - !!(<Bears<T> as ReflectDrop>::REFLECT_DROP) as usize];
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/dropck/negative.rs b/tests/ui/dropck/negative.rs
new file mode 100644
index 00000000000..ae63632b55e
--- /dev/null
+++ b/tests/ui/dropck/negative.rs
@@ -0,0 +1,7 @@
+#![feature(negative_impls)]
+
+struct NonDrop;
+impl !Drop for NonDrop {}
+//~^ ERROR negative `Drop` impls are not supported
+
+fn main() {}
diff --git a/tests/ui/dropck/negative.stderr b/tests/ui/dropck/negative.stderr
new file mode 100644
index 00000000000..d613e30b5ea
--- /dev/null
+++ b/tests/ui/dropck/negative.stderr
@@ -0,0 +1,8 @@
+error: negative `Drop` impls are not supported
+  --> $DIR/negative.rs:4:1
+   |
+LL | impl !Drop for NonDrop {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/dropck/reservation.rs b/tests/ui/dropck/reservation.rs
new file mode 100644
index 00000000000..f7199d4ec44
--- /dev/null
+++ b/tests/ui/dropck/reservation.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+struct ReservedDrop;
+#[rustc_reservation_impl = "message"]
+impl Drop for ReservedDrop {
+//~^ ERROR reservation `Drop` impls are not supported
+    fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/dropck/reservation.stderr b/tests/ui/dropck/reservation.stderr
new file mode 100644
index 00000000000..19325d6ed44
--- /dev/null
+++ b/tests/ui/dropck/reservation.stderr
@@ -0,0 +1,8 @@
+error: reservation `Drop` impls are not supported
+  --> $DIR/reservation.rs:5:1
+   |
+LL | impl Drop for ReservedDrop {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
index ffeabe5c2ed..776006124dc 100644
--- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
@@ -5,10 +5,10 @@
 use std::ops::Deref;
 
 pub trait Foo {
-    fn bar() -> impl Deref<Target = impl Sized>;
+    fn bar(self) -> impl Deref<Target = impl Sized>;
 }
 
 pub struct Foreign;
 impl Foo for Foreign {
-    fn bar() -> &'static () { &() }
+    fn bar(self) -> &'static () { &() }
 }
diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs
new file mode 100644
index 00000000000..ecb5e62c433
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs
@@ -0,0 +1,8 @@
+// aux-build: rpitit.rs
+
+extern crate rpitit;
+
+fn main() {
+    let _: &dyn rpitit::Foo = todo!();
+    //~^ ERROR the trait `Foo` cannot be made into an object
+}
diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr
new file mode 100644
index 00000000000..6eef392c05f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr
@@ -0,0 +1,15 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/foreign-dyn-error.rs:6:12
+   |
+LL |     let _: &dyn rpitit::Foo = todo!();
+   |            ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/auxiliary/rpitit.rs:8:21
+   |
+LL |     fn bar(self) -> impl Deref<Target = impl Sized>;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait cannot be made into an object because method `bar` references an `impl Trait` type in its return type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs
index f4972d948b2..98417b343a1 100644
--- a/tests/ui/impl-trait/in-trait/foreign.rs
+++ b/tests/ui/impl-trait/in-trait/foreign.rs
@@ -5,17 +5,18 @@
 
 extern crate rpitit;
 
+use rpitit::{Foo, Foreign};
 use std::sync::Arc;
 
 // Implement an RPITIT from another crate.
 struct Local;
-impl rpitit::Foo for Local {
-    fn bar() -> Arc<String> { Arc::new(String::new()) }
+impl Foo for Local {
+    fn bar(self) -> Arc<String> { Arc::new(String::new()) }
 }
 
 fn main() {
     // Witness an RPITIT from another crate.
-    let &() = <rpitit::Foreign as rpitit::Foo>::bar();
+    let &() = Foreign.bar();
 
-    let x: Arc<String> = <Local as rpitit::Foo>::bar();
+    let x: Arc<String> = Local.bar();
 }
diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs
index 351243c6727..ec4fda322d0 100644
--- a/tests/ui/impl-trait/issues/issue-86800.rs
+++ b/tests/ui/impl-trait/issues/issue-86800.rs
@@ -1,14 +1,12 @@
 #![feature(type_alias_impl_trait)]
 
 // edition:2021
-// unset-rustc-env:RUST_BACKTRACE
 // compile-flags:-Z treat-err-as-bug=1
-// error-pattern:stack backtrace:
+// error-pattern: aborting due to `-Z treat-err-as-bug=1`
 // failure-status:101
-// normalize-stderr-test "note: .*" -> ""
-// normalize-stderr-test "thread 'rustc' .*" -> ""
-// normalize-stderr-test " +[0-9]+:.*\n" -> ""
-// normalize-stderr-test " +at .*\n" -> ""
+// normalize-stderr-test ".*note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
 
 use std::future::Future;
 
diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr
index f3a77383778..facab390d15 100644
--- a/tests/ui/impl-trait/issues/issue-86800.stderr
+++ b/tests/ui/impl-trait/issues/issue-86800.stderr
@@ -1,24 +1,12 @@
 error: unconstrained opaque type
-  --> $DIR/issue-86800.rs:33:34
+  --> $DIR/issue-86800.rs:31:34
    |
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = 
-
-
-stack backtrace:
-
 error: the compiler unexpectedly panicked. this is a bug.
 
-
-
-
-
-
-
 query stack during panic:
 #0 [type_of] computing type of `TransactionFuture::{opaque#0}`
 #1 [check_mod_item_types] checking item types in top-level module
-#2 [analysis] running analysis passes on this crate
 end of query stack
diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs
index fd86a3f9dfa..b40203c339d 100644
--- a/tests/ui/panics/default-backtrace-ice.rs
+++ b/tests/ui/panics/default-backtrace-ice.rs
@@ -2,8 +2,20 @@
 // compile-flags:-Z treat-err-as-bug=1
 // error-pattern:stack backtrace:
 // failure-status:101
+// ignore-msvc
 // normalize-stderr-test "note: .*" -> ""
 // normalize-stderr-test "thread 'rustc' .*" -> ""
-// normalize-stderr-test "  .*\n" -> ""
+// normalize-stderr-test " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)"
+// normalize-stderr-test " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)"
+// normalize-stderr-test " +\d+:.*\n" -> ""
+// normalize-stderr-test " +at .*\n" -> ""
+//
+// This test makes sure that full backtraces are used for ICEs when
+// RUST_BACKTRACE is not set. It does this by checking for the presence of
+// `__rust_{begin,end}_short_backtrace` markers, which only appear in full
+// backtraces. The rest of the backtrace is filtered out.
+//
+// Ignored on msvc becaue the `__rust_{begin,end}_short_backtrace` symbols
+// aren't reliable.
 
 fn main() { missing_ident; }
diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr
index 4bd4780e25f..ddbfc4e7f3a 100644
--- a/tests/ui/panics/default-backtrace-ice.stderr
+++ b/tests/ui/panics/default-backtrace-ice.stderr
@@ -1,8 +1,13 @@
 error[E0425]: cannot find value `missing_ident` in this scope
+  --> $DIR/default-backtrace-ice.rs:21:13
+   |
 LL | fn main() { missing_ident; }
+   |             ^^^^^^^^^^^^^ not found in this scope
 
 
 stack backtrace:
+(end_short_backtrace)
+(begin_short_backtrace)
 
 error: the compiler unexpectedly panicked. this is a bug.
 
diff --git a/tests/ui/self/elision/nested-item.rs b/tests/ui/self/elision/nested-item.rs
new file mode 100644
index 00000000000..4bcb645c60e
--- /dev/null
+++ b/tests/ui/self/elision/nested-item.rs
@@ -0,0 +1,13 @@
+// Regression test for #110899.
+// When looking for the elided lifetime for `wrap`,
+// we must not consider the lifetimes in `bar` as candidates.
+
+fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
+    //~^ ERROR `self` parameter is only allowed in associated functions
+    //~| ERROR `self` parameter is only allowed in associated functions
+    //~| ERROR missing lifetime specifier
+    //~| ERROR cannot find type `Wrap` in this scope
+    &()
+}
+
+fn main() {}
diff --git a/tests/ui/self/elision/nested-item.stderr b/tests/ui/self/elision/nested-item.stderr
new file mode 100644
index 00000000000..752fd82332c
--- /dev/null
+++ b/tests/ui/self/elision/nested-item.stderr
@@ -0,0 +1,38 @@
+error: `self` parameter is only allowed in associated functions
+  --> $DIR/nested-item.rs:5:9
+   |
+LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
+   |         ^^^^ not semantically valid as function parameter
+   |
+   = note: associated functions are those in `impl` or `trait` definitions
+
+error: `self` parameter is only allowed in associated functions
+  --> $DIR/nested-item.rs:5:29
+   |
+LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
+   |                             ^^^^^ not semantically valid as function parameter
+   |
+   = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/nested-item.rs:5:46
+   |
+LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
+   |                                              ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &'static () {
+   |                                               +++++++
+
+error[E0412]: cannot find type `Wrap` in this scope
+  --> $DIR/nested-item.rs:5:15
+   |
+LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() {
+   |               ^^^^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0106, E0412.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/self/self-ctor-inner-const.rs b/tests/ui/self/self-ctor-inner-const.rs
new file mode 100644
index 00000000000..b015397a5bc
--- /dev/null
+++ b/tests/ui/self/self-ctor-inner-const.rs
@@ -0,0 +1,17 @@
+// Verify that we ban usage of `Self` as constructor from inner items.
+
+struct S0<T>(T);
+
+impl<T> S0<T> {
+    fn foo() {
+        const C: S0<u8> = Self(0);
+        //~^ ERROR can't use generic parameters from outer function
+        fn bar() -> Self {
+            //~^ ERROR can't use generic parameters from outer function
+            Self(0)
+            //~^ ERROR can't use generic parameters from outer function
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/self-ctor-inner-const.stderr b/tests/ui/self/self-ctor-inner-const.stderr
new file mode 100644
index 00000000000..7287c64c659
--- /dev/null
+++ b/tests/ui/self/self-ctor-inner-const.stderr
@@ -0,0 +1,33 @@
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/self-ctor-inner-const.rs:7:27
+   |
+LL |         const C: S0<u8> = Self(0);
+   |                           ^^^^
+   |                           |
+   |                           use of generic parameter from outer function
+   |                           can't use `Self` here
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/self-ctor-inner-const.rs:9:21
+   |
+LL | impl<T> S0<T> {
+   | ---- `Self` type implicitly declared here, by this `impl`
+...
+LL |         fn bar() -> Self {
+   |                     ^^^^
+   |                     |
+   |                     use of generic parameter from outer function
+   |                     use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+  --> $DIR/self-ctor-inner-const.rs:11:13
+   |
+LL |             Self(0)
+   |             ^^^^
+   |             |
+   |             use of generic parameter from outer function
+   |             can't use `Self` here
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0401`.
diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs
index f99e476eaba..8416270fd81 100644
--- a/tests/ui/test-attrs/test-type.rs
+++ b/tests/ui/test-attrs/test-type.rs
@@ -3,6 +3,7 @@
 // check-run-results
 // normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
 // ignore-emscripten no threads support
+// needs-unwind
 // run-pass
 
 #[test]
diff --git a/tests/ui/typeck/repeat-expr-checks-wf.rs b/tests/ui/typeck/repeat-expr-checks-wf.rs
new file mode 100644
index 00000000000..b8a2a0ceb58
--- /dev/null
+++ b/tests/ui/typeck/repeat-expr-checks-wf.rs
@@ -0,0 +1,10 @@
+trait Foo {
+    const ASSOC: [u8];
+}
+
+fn bar<T: Foo>() {
+    let a = [T::ASSOC; 2];
+    //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/repeat-expr-checks-wf.stderr b/tests/ui/typeck/repeat-expr-checks-wf.stderr
new file mode 100644
index 00000000000..a821088a4b3
--- /dev/null
+++ b/tests/ui/typeck/repeat-expr-checks-wf.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/repeat-expr-checks-wf.rs:6:13
+   |
+LL |     let a = [T::ASSOC; 2];
+   |             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: slice and array elements must have `Sized` type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.