about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_arena/src/lib.rs141
-rw-r--r--compiler/rustc_ast/src/ast.rs4
-rw-r--r--compiler/rustc_ast/src/util/comments.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs47
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs13
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/nll.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs60
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs106
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs87
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs92
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs67
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs48
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs110
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs27
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs92
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/intrinsic.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs15
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs10
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/index_map.rs10
-rw-r--r--compiler/rustc_driver/src/lib.rs5
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0206.md9
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs50
-rw-r--r--compiler/rustc_expand/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs28
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs164
-rw-r--r--compiler/rustc_feature/src/accepted.rs442
-rw-r--r--compiler/rustc_feature/src/active.rs809
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs65
-rw-r--r--compiler/rustc_feature/src/removed.rs190
-rw-r--r--compiler/rustc_hir/src/arena.rs15
-rw-r--r--compiler/rustc_hir/src/def.rs7
-rw-r--r--compiler/rustc_hir/src/hir.rs16
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs26
-rw-r--r--compiler/rustc_index/src/vec.rs24
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs57
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs65
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs39
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs22
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs8
-rw-r--r--compiler/rustc_infer/src/traits/engine.rs15
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs5
-rw-r--r--compiler/rustc_infer/src/traits/util.rs17
-rw-r--r--compiler/rustc_interface/src/interface.rs16
-rw-r--r--compiler/rustc_interface/src/passes.rs8
-rw-r--r--compiler/rustc_interface/src/tests.rs4
-rw-r--r--compiler/rustc_interface/src/util.rs3
-rw-r--r--compiler/rustc_lint/src/builtin.rs11
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp16
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs15
-rw-r--r--compiler/rustc_middle/src/arena.rs15
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs10
-rw-r--r--compiler/rustc_middle/src/lint.rs8
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs15
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs79
-rw-r--r--compiler/rustc_middle/src/ty/error.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs14
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs72
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs10
-rw-r--r--compiler/rustc_middle/src/ty/util.rs30
-rw-r--r--compiler/rustc_middle/src/util/common.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs9
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs149
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs11
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs5
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs27
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs11
-rw-r--r--compiler/rustc_passes/src/check_attr.rs36
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/region.rs11
-rw-r--r--compiler/rustc_privacy/src/lib.rs10
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs15
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs3
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs6
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--compiler/rustc_resolve/src/macros.rs9
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/config.rs56
-rw-r--r--compiler/rustc_session/src/options.rs23
-rw-r--r--compiler/rustc_session/src/session.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/android_base.rs2
-rw-r--r--compiler/rustc_trait_selection/src/autoderef.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs44
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs81
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs52
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs38
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs2
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs6
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs2
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs84
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs11
-rw-r--r--compiler/rustc_typeck/src/check/check.rs21
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs8
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs2
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs25
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs13
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs189
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs26
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs97
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs7
-rw-r--r--compiler/rustc_typeck/src/check/method/confirm.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs22
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs12
-rw-r--r--compiler/rustc_typeck/src/check/op.rs5
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs4
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs32
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs15
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs25
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs6
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs6
-rw-r--r--compiler/rustc_typeck/src/coherence/mod.rs8
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs464
-rw-r--r--compiler/rustc_typeck/src/collect.rs46
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs3
-rw-r--r--compiler/rustc_typeck/src/hir_wf_check.rs3
-rw-r--r--compiler/rustc_typeck/src/lib.rs15
-rw-r--r--compiler/rustc_typeck/src/outlives/outlives_bounds.rs3
158 files changed, 2945 insertions, 2369 deletions
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index 6d5f47aceeb..e54fcaf6fc1 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -19,7 +19,6 @@
 #![feature(rustc_attrs)]
 #![cfg_attr(test, feature(test))]
 
-use rustc_data_structures::sync;
 use smallvec::SmallVec;
 
 use std::alloc::Layout;
@@ -517,130 +516,12 @@ impl DroplessArena {
     }
 }
 
-/// Calls the destructor for an object when dropped.
-struct DropType {
-    drop_fn: unsafe fn(*mut u8),
-    obj: *mut u8,
-}
-
-// SAFETY: we require `T: Send` before type-erasing into `DropType`.
-#[cfg(parallel_compiler)]
-unsafe impl sync::Send for DropType {}
-
-impl DropType {
-    #[inline]
-    unsafe fn new<T: sync::Send>(obj: *mut T) -> Self {
-        unsafe fn drop_for_type<T>(to_drop: *mut u8) {
-            std::ptr::drop_in_place(to_drop as *mut T)
-        }
-
-        DropType { drop_fn: drop_for_type::<T>, obj: obj as *mut u8 }
-    }
-}
-
-impl Drop for DropType {
-    fn drop(&mut self) {
-        unsafe { (self.drop_fn)(self.obj) }
-    }
-}
-
-/// An arena which can be used to allocate any type.
-///
-/// # Safety
-///
-/// Allocating in this arena is unsafe since the type system
-/// doesn't know which types it contains. In order to
-/// allocate safely, you must store a `PhantomData<T>`
-/// alongside this arena for each type `T` you allocate.
-#[derive(Default)]
-pub struct DropArena {
-    /// A list of destructors to run when the arena drops.
-    /// Ordered so `destructors` gets dropped before the arena
-    /// since its destructor can reference memory in the arena.
-    destructors: RefCell<Vec<DropType>>,
-    arena: DroplessArena,
-}
-
-impl DropArena {
-    #[inline]
-    pub unsafe fn alloc<T>(&self, object: T) -> &mut T
-    where
-        T: sync::Send,
-    {
-        let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T;
-        // Write into uninitialized memory.
-        ptr::write(mem, object);
-        let result = &mut *mem;
-        // Record the destructor after doing the allocation as that may panic
-        // and would cause `object`'s destructor to run twice if it was recorded before.
-        self.destructors.borrow_mut().push(DropType::new(result));
-        result
-    }
-
-    #[inline]
-    pub unsafe fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T]
-    where
-        T: sync::Send,
-        I: IntoIterator<Item = T>,
-    {
-        let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
-        if vec.is_empty() {
-            return &mut [];
-        }
-        let len = vec.len();
-
-        let start_ptr = self.arena.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T;
-
-        let mut destructors = self.destructors.borrow_mut();
-        // Reserve space for the destructors so we can't panic while adding them.
-        destructors.reserve(len);
-
-        // Move the content to the arena by copying it and then forgetting
-        // the content of the SmallVec.
-        vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
-        mem::forget(vec.drain(..));
-
-        // Record the destructors after doing the allocation as that may panic
-        // and would cause `object`'s destructor to run twice if it was recorded before.
-        for i in 0..len {
-            destructors.push(DropType::new(start_ptr.add(i)));
-        }
-
-        slice::from_raw_parts_mut(start_ptr, len)
-    }
-}
-
-pub macro arena_for_type {
-    ([][$ty:ty]) => {
-        $crate::TypedArena<$ty>
-    },
-    ([few $(, $attrs:ident)*][$ty:ty]) => {
-        ::std::marker::PhantomData<$ty>
-    },
-    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
-        $crate::arena_for_type!([$($attrs),*]$args)
-    },
-}
-
-pub macro which_arena_for_type {
-    ([][$arena:expr]) => {
-        ::std::option::Option::Some($arena)
-    },
-    ([few$(, $attrs:ident)*][$arena:expr]) => {
-        ::std::option::Option::None
-    },
-    ([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
-        $crate::which_arena_for_type!([$($attrs),*]$args)
-    },
-}
-
 #[rustc_macro_transparency = "semitransparent"]
 pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
     #[derive(Default)]
     pub struct Arena<$tcx> {
         pub dropless: $crate::DroplessArena,
-        drop: $crate::DropArena,
-        $($name: $crate::arena_for_type!($a[$ty]),)*
+        $($name: $crate::TypedArena<$ty>,)*
     }
 
     pub trait ArenaAllocatable<'tcx, T = Self>: Sized {
@@ -670,13 +551,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
             #[inline]
             fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self {
                 if !::std::mem::needs_drop::<Self>() {
-                    return arena.dropless.alloc(self);
-                }
-                match $crate::which_arena_for_type!($a[&arena.$name]) {
-                    ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => {
-                        ty_arena.alloc(self)
-                    }
-                    ::std::option::Option::None => unsafe { arena.drop.alloc(self) },
+                    arena.dropless.alloc(self)
+                } else {
+                    arena.$name.alloc(self)
                 }
             }
 
@@ -686,13 +563,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
                 iter: impl ::std::iter::IntoIterator<Item = Self>,
             ) -> &'a mut [Self] {
                 if !::std::mem::needs_drop::<Self>() {
-                    return arena.dropless.alloc_from_iter(iter);
-                }
-                match $crate::which_arena_for_type!($a[&arena.$name]) {
-                    ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => {
-                        ty_arena.alloc_from_iter(iter)
-                    }
-                    ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) },
+                    arena.dropless.alloc_from_iter(iter)
+                } else {
+                    arena.$name.alloc_from_iter(iter)
                 }
             }
         }
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f9e19d30fcc..abfe8360987 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2058,7 +2058,7 @@ pub struct InlineAsm {
     pub template: Vec<InlineAsmTemplatePiece>,
     pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
     pub operands: Vec<(InlineAsmOperand, Span)>,
-    pub clobber_abi: Option<(Symbol, Span)>,
+    pub clobber_abis: Vec<(Symbol, Span)>,
     pub options: InlineAsmOptions,
     pub line_spans: Vec<Span>,
 }
@@ -2715,7 +2715,7 @@ pub enum ItemKind {
     /// E.g., `extern {}` or `extern "C" {}`.
     ForeignMod(ForeignMod),
     /// Module-level inline assembly (from `global_asm!()`).
-    GlobalAsm(InlineAsm),
+    GlobalAsm(Box<InlineAsm>),
     /// A type alias (`type`).
     ///
     /// E.g., `type Foo = Bar<u8>;`.
diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs
index c40aec4b671..80a06fa5943 100644
--- a/compiler/rustc_ast/src/util/comments.rs
+++ b/compiler/rustc_ast/src/util/comments.rs
@@ -169,7 +169,7 @@ pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comme
                 if let Some(mut idx) = token_text.find('\n') {
                     code_to_the_left = false;
                     while let Some(next_newline) = &token_text[idx + 1..].find('\n') {
-                        idx = idx + 1 + next_newline;
+                        idx += 1 + next_newline;
                         comments.push(Comment {
                             style: CommentStyle::BlankLine,
                             lines: vec![],
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 95997a37d84..cfa97ff84ec 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -2,6 +2,7 @@ use super::LoweringContext;
 
 use rustc_ast::*;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_session::parse::feature_err;
@@ -49,22 +50,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 .emit();
         }
 
-        let mut clobber_abi = None;
+        let mut clobber_abis = FxHashMap::default();
         if let Some(asm_arch) = asm_arch {
-            if let Some((abi_name, abi_span)) = asm.clobber_abi {
-                match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, abi_name) {
-                    Ok(abi) => clobber_abi = Some((abi, abi_span)),
+            for (abi_name, abi_span) in &asm.clobber_abis {
+                match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
+                    Ok(abi) => {
+                        // If the abi was already in the list, emit an error
+                        match clobber_abis.get(&abi) {
+                            Some((prev_name, prev_sp)) => {
+                                let mut err = self.sess.struct_span_err(
+                                    *abi_span,
+                                    &format!("`{}` ABI specified multiple times", prev_name),
+                                );
+                                err.span_label(*prev_sp, "previously specified here");
+
+                                // Multiple different abi names may actually be the same ABI
+                                // If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
+                                let source_map = self.sess.source_map();
+                                if source_map.span_to_snippet(*prev_sp)
+                                    != source_map.span_to_snippet(*abi_span)
+                                {
+                                    err.note("these ABIs are equivalent on the current target");
+                                }
+
+                                err.emit();
+                            }
+                            None => {
+                                clobber_abis.insert(abi, (abi_name, *abi_span));
+                            }
+                        }
+                    }
                     Err(&[]) => {
                         self.sess
                             .struct_span_err(
-                                abi_span,
+                                *abi_span,
                                 "`clobber_abi` is not supported on this target",
                             )
                             .emit();
                     }
                     Err(supported_abis) => {
                         let mut err =
-                            self.sess.struct_span_err(abi_span, "invalid ABI for `clobber_abi`");
+                            self.sess.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
                         let mut abis = format!("`{}`", supported_abis[0]);
                         for m in &supported_abis[1..] {
                             let _ = write!(abis, ", `{}`", m);
@@ -348,8 +374,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         // If a clobber_abi is specified, add the necessary clobbers to the
         // operands list.
-        if let Some((abi, abi_span)) = clobber_abi {
+        let mut clobbered = FxHashSet::default();
+        for (abi, (_, abi_span)) in clobber_abis {
             for &clobber in abi.clobbered_regs() {
+                // Don't emit a clobber for a register already clobbered
+                if clobbered.contains(&clobber) {
+                    continue;
+                }
+
                 let mut output_used = false;
                 clobber.overlapping_regs(|reg| {
                     if used_output_regs.contains_key(&reg) {
@@ -366,6 +398,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         },
                         self.lower_span(abi_span),
                     ));
+                    clobbered.insert(clobber);
                 }
             }
         }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index f45a79f026f..b011a2e8117 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -3,7 +3,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId};
 use rustc_ast::{PatKind, RangeEnd, VariantData};
 use rustc_errors::struct_span_err;
-use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
+use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_feature::{Features, GateIssue};
 use rustc_session::parse::{feature_err, feature_err_issue};
 use rustc_session::Session;
@@ -301,11 +301,14 @@ impl<'a> PostExpansionVisitor<'a> {
 
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        let attr_info =
-            attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
+        let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
         // Check feature gates for built-in attributes.
-        if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
-            gate_feature_fn!(self, has_feature, attr.span, name, descr);
+        if let Some(BuiltinAttribute {
+            gate: AttributeGate::Gated(_, name, descr, has_feature),
+            ..
+        }) = attr_info
+        {
+            gate_feature_fn!(self, has_feature, attr.span, *name, descr);
         }
         // Check unstable flavors of the `#[doc]` attribute.
         if attr.has_name(sym::doc) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b59e49926ad..f1f2387866d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -2235,8 +2235,8 @@ impl<'a> State<'a> {
 
         let mut args = vec![AsmArg::Template(InlineAsmTemplatePiece::to_string(&asm.template))];
         args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o)));
-        if let Some((abi, _)) = asm.clobber_abi {
-            args.push(AsmArg::ClobberAbi(abi));
+        for (abi, _) in &asm.clobber_abis {
+            args.push(AsmArg::ClobberAbi(*abi));
         }
         if !asm.options.is_empty() {
             args.push(AsmArg::Options(asm.options));
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 15309ccd8df..1bc9f8cf3cc 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -339,7 +339,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
     // We generally shouldn't have errors here because the query was
     // already run, but there's no point using `delay_span_bug`
     // when we're going to emit an error here anyway.
-    let _errors = fulfill_cx.select_all_or_error(infcx).err().unwrap_or_else(Vec::new);
+    let _errors = fulfill_cx.select_all_or_error(infcx);
 
     let (sub_region, cause) = infcx.with_region_constraints(|region_constraints| {
         debug!("{:#?}", region_constraints);
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 439c728798d..46a3c0fa101 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -408,7 +408,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     let param = generics.type_param(&param_ty, tcx);
                     if let Some(generics) = tcx
                         .hir()
-                        .get_generics(tcx.closure_base_def_id(self.mir_def_id().to_def_id()))
+                        .get_generics(tcx.typeck_root_def_id(self.mir_def_id().to_def_id()))
                     {
                         suggest_constraining_type_param(
                             tcx,
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index aca7d3174f6..76d3a83b48d 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -3,7 +3,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(in_band_lifetimes)]
 #![feature(iter_zip)]
 #![feature(let_else)]
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index e5924f9d084..6ffab165779 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -376,7 +376,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
     errors_buffer: &mut Vec<Diagnostic>,
 ) {
     let tcx = infcx.tcx;
-    let base_def_id = tcx.closure_base_def_id(body.source.def_id());
+    let base_def_id = tcx.typeck_root_def_id(body.source.def_id());
     if !tcx.has_attr(base_def_id, sym::rustc_regions) {
         return;
     }
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index f4a5da1fe36..b39a28f79aa 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -569,7 +569,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // to store those. Otherwise, we'll pass in `None` to the
         // functions below, which will trigger them to report errors
         // eagerly.
-        let mut outlives_requirements = infcx.tcx.is_closure(mir_def_id).then(Vec::new);
+        let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
 
         self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer);
 
@@ -2229,7 +2229,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx
             tcx,
             closure_substs,
             self.num_external_vids,
-            tcx.closure_base_def_id(closure_def_id),
+            tcx.typeck_root_def_id(closure_def_id),
         );
         debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
 
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 24332690bec..92d2d04f23f 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -7,13 +7,16 @@
 //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
 //! contain revealed `impl Trait` values).
 
+use crate::type_check::constraint_conversion::ConstraintConversion;
 use rustc_index::vec::Idx;
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::mir::*;
-use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
-use rustc_trait_selection::traits::query::normalize::AtExt;
+use rustc_span::DUMMY_SP;
+use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
+use rustc_trait_selection::traits::query::Fallible;
+use type_op::TypeOpOutput;
 
 use crate::universal_regions::UniversalRegions;
 
@@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         let (&normalized_output_ty, normalized_input_tys) =
             normalized_inputs_and_output.split_last().unwrap();
 
+        debug!(?normalized_output_ty);
+        debug!(?normalized_input_tys);
+
         let mir_def_id = body.source.def_id().expect_local();
 
         // If the user explicitly annotated the input types, extract
@@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     .delay_span_bug(body.span, "found more normalized_input_ty than local_decls");
                 break;
             }
+
             // In MIR, argument N is stored in local N+1.
             let local = Local::new(argument_index + 1);
 
             let mir_input_ty = body.local_decls[local].ty;
+
             let mir_input_span = body.local_decls[local].source_info.span;
             self.equate_normalized_input_or_output(
                 normalized_input_ty,
@@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // If the user explicitly annotated the input types, enforce those.
                 let user_provided_input_ty =
                     self.normalize(user_provided_input_ty, Locations::All(mir_input_span));
+
                 self.equate_normalized_input_or_output(
                     user_provided_input_ty,
                     mir_input_ty,
@@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
             // like to normalize *before* inserting into `local_decls`, but
             // doing so ends up causing some other trouble.
-            let b = match self
-                .infcx
-                .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
-                .normalize(b)
-            {
-                Ok(n) => {
-                    debug!("equate_inputs_and_outputs: {:?}", n);
-                    if n.obligations.iter().all(|o| {
-                        matches!(
-                            o.predicate.kind().skip_binder(),
-                            ty::PredicateKind::RegionOutlives(_)
-                                | ty::PredicateKind::TypeOutlives(_)
-                        )
-                    }) {
-                        n.value
-                    } else {
-                        b
-                    }
-                }
+            let b = match self.normalize_and_add_constraints(b) {
+                Ok(n) => n,
                 Err(_) => {
                     debug!("equate_inputs_and_outputs: NoSolution");
                     b
                 }
             };
+
             // Note: if we have to introduce new placeholders during normalization above, then we won't have
             // added those universes to the universe info, which we would want in `relate_tys`.
             if let Err(terr) =
@@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
         }
     }
+
+    pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible<Ty<'tcx>> {
+        let TypeOpOutput { output: norm_ty, constraints, .. } =
+            self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?;
+
+        debug!("{:?} normalized to {:?}", t, norm_ty);
+
+        for data in constraints.into_iter().collect::<Vec<_>>() {
+            ConstraintConversion::new(
+                self.infcx,
+                &self.borrowck_context.universal_regions,
+                &self.region_bound_pairs,
+                Some(self.implicit_region_bound),
+                self.param_env,
+                Locations::All(DUMMY_SP),
+                ConstraintCategory::Internal,
+                &mut self.borrowck_context.constraints,
+            )
+            .convert_all(&*data);
+        }
+
+        Ok(norm_ty)
+    }
 }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 06e34bdce3f..da26d9c7b87 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -10,6 +10,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::vec_map::VecMap;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::vec::{Idx, IndexVec};
@@ -892,11 +893,11 @@ struct TypeChecker<'a, 'tcx> {
 }
 
 struct BorrowCheckContext<'a, 'tcx> {
-    universal_regions: &'a UniversalRegions<'tcx>,
+    pub(crate) universal_regions: &'a UniversalRegions<'tcx>,
     location_table: &'a LocationTable,
     all_facts: &'a mut Option<AllFacts>,
     borrow_set: &'a BorrowSet<'tcx>,
-    constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
+    pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
     upvars: &'a [Upvar<'tcx>],
 }
 
@@ -1156,6 +1157,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category)
     }
 
+    #[instrument(skip(self, category), level = "debug")]
     fn eq_types(
         &mut self,
         expected: Ty<'tcx>,
@@ -1343,13 +1345,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // though.
                 let category = match place.as_local() {
                     Some(RETURN_PLACE) => {
-                        if let BorrowCheckContext {
-                            universal_regions:
-                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
-                            ..
-                        } = self.borrowck_context
-                        {
-                            if tcx.is_static(*def_id) {
+                        let defining_ty = &self.borrowck_context.universal_regions.defining_ty;
+                        if defining_ty.is_const() {
+                            if tcx.is_static(defining_ty.def_id()) {
                                 ConstraintCategory::UseAsStatic
                             } else {
                                 ConstraintCategory::UseAsConst
@@ -1527,6 +1525,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
             TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
+                self.check_operand(discr, term_location);
+
                 let discr_ty = discr.ty(body, tcx);
                 if let Err(terr) = self.sub_types(
                     discr_ty,
@@ -1549,6 +1549,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // FIXME: check the values
             }
             TerminatorKind::Call { ref func, ref args, ref destination, from_hir_call, .. } => {
+                self.check_operand(func, term_location);
+                for arg in args {
+                    self.check_operand(arg, term_location);
+                }
+
                 let func_ty = func.ty(body, tcx);
                 debug!("check_terminator: call, func_ty={:?}", func_ty);
                 let sig = match func_ty.kind() {
@@ -1593,6 +1598,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
             }
             TerminatorKind::Assert { ref cond, ref msg, .. } => {
+                self.check_operand(cond, term_location);
+
                 let cond_ty = cond.ty(body, tcx);
                 if cond_ty != tcx.types.bool {
                     span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
@@ -1608,6 +1615,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
             TerminatorKind::Yield { ref value, .. } => {
+                self.check_operand(value, term_location);
+
                 let value_ty = value.ty(body, tcx);
                 match body.yield_ty() {
                     None => span_mirbug!(self, term, "yield in non-generator"),
@@ -1650,7 +1659,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     Some(RETURN_PLACE) => {
                         if let BorrowCheckContext {
                             universal_regions:
-                                UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. },
+                                UniversalRegions {
+                                    defining_ty:
+                                        DefiningTy::Const(def_id, _)
+                                        | DefiningTy::InlineConst(def_id, _),
+                                    ..
+                                },
                             ..
                         } = self.borrowck_context
                         {
@@ -1931,15 +1945,51 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         }
     }
 
+    fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
+        if let Operand::Constant(constant) = op {
+            let maybe_uneval = match constant.literal {
+                ConstantKind::Ty(ct) => match ct.val {
+                    ty::ConstKind::Unevaluated(uv) => Some(uv),
+                    _ => None,
+                },
+                _ => None,
+            };
+            if let Some(uv) = maybe_uneval {
+                if uv.promoted.is_none() {
+                    let tcx = self.tcx();
+                    let def_id = uv.def.def_id_for_type_of();
+                    if tcx.def_kind(def_id) == DefKind::InlineConst {
+                        let predicates = self.prove_closure_bounds(
+                            tcx,
+                            def_id.expect_local(),
+                            uv.substs(tcx),
+                            location,
+                        );
+                        self.normalize_and_prove_instantiated_predicates(
+                            def_id,
+                            predicates,
+                            location.to_locations(),
+                        );
+                    }
+                }
+            }
+        }
+    }
+
     fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         let tcx = self.tcx();
 
         match rvalue {
             Rvalue::Aggregate(ak, ops) => {
+                for op in ops {
+                    self.check_operand(op, location);
+                }
                 self.check_aggregate_rvalue(&body, rvalue, ak, ops, location)
             }
 
             Rvalue::Repeat(operand, len) => {
+                self.check_operand(operand, location);
+
                 // 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
@@ -1990,7 +2040,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
 
-            Rvalue::NullaryOp(_, ty) | Rvalue::ShallowInitBox(_, ty) => {
+            Rvalue::NullaryOp(_, ty) => {
+                let trait_ref = ty::TraitRef {
+                    def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
+                    substs: tcx.mk_substs_trait(ty, &[]),
+                };
+
+                self.prove_trait_ref(
+                    trait_ref,
+                    location.to_locations(),
+                    ConstraintCategory::SizedBound,
+                );
+            }
+
+            Rvalue::ShallowInitBox(operand, ty) => {
+                self.check_operand(operand, location);
+
                 let trait_ref = ty::TraitRef {
                     def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
                     substs: tcx.mk_substs_trait(ty, &[]),
@@ -2004,6 +2069,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
 
             Rvalue::Cast(cast_kind, op, ty) => {
+                self.check_operand(op, location);
+
                 match cast_kind {
                     CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
@@ -2250,6 +2317,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
                 box (left, right),
             ) => {
+                self.check_operand(left, location);
+                self.check_operand(right, location);
+
                 let ty_left = left.ty(body, tcx);
                 match ty_left.kind() {
                     // Types with regions are comparable if they have a common super-type.
@@ -2300,13 +2370,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
 
+            Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => {
+                self.check_operand(operand, location);
+            }
+
+            Rvalue::BinaryOp(_, box (left, right))
+            | Rvalue::CheckedBinaryOp(_, box (left, right)) => {
+                self.check_operand(left, location);
+                self.check_operand(right, location);
+            }
+
             Rvalue::AddressOf(..)
             | Rvalue::ThreadLocalRef(..)
-            | Rvalue::Use(..)
             | Rvalue::Len(..)
-            | Rvalue::BinaryOp(..)
-            | Rvalue::CheckedBinaryOp(..)
-            | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..) => {}
         }
     }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 147e2aead64..b986df403f9 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -23,7 +23,7 @@ use rustc_index::vec::{Idx, IndexVec};
 use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
+use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt};
 use std::iter;
 
 use crate::nll::ToRegionVid;
@@ -108,6 +108,10 @@ pub enum DefiningTy<'tcx> {
     /// is that it has no inputs and a single return value, which is
     /// the value of the constant.
     Const(DefId, SubstsRef<'tcx>),
+
+    /// The MIR represents an inline const. The signature has no inputs and a
+    /// single return value found via `InlineConstSubsts::ty`.
+    InlineConst(DefId, SubstsRef<'tcx>),
 }
 
 impl<'tcx> DefiningTy<'tcx> {
@@ -121,7 +125,7 @@ impl<'tcx> DefiningTy<'tcx> {
             DefiningTy::Generator(_, substs, _) => {
                 Either::Right(Either::Left(substs.as_generator().upvar_tys()))
             }
-            DefiningTy::FnDef(..) | DefiningTy::Const(..) => {
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
                 Either::Right(Either::Right(iter::empty()))
             }
         }
@@ -133,7 +137,7 @@ impl<'tcx> DefiningTy<'tcx> {
     pub fn implicit_inputs(self) -> usize {
         match self {
             DefiningTy::Closure(..) | DefiningTy::Generator(..) => 1,
-            DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0,
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0,
         }
     }
 
@@ -142,7 +146,7 @@ impl<'tcx> DefiningTy<'tcx> {
     }
 
     pub fn is_const(&self) -> bool {
-        matches!(*self, DefiningTy::Const(..))
+        matches!(*self, DefiningTy::Const(..) | DefiningTy::InlineConst(..))
     }
 
     pub fn def_id(&self) -> DefId {
@@ -150,7 +154,8 @@ impl<'tcx> DefiningTy<'tcx> {
             DefiningTy::Closure(def_id, ..)
             | DefiningTy::Generator(def_id, ..)
             | DefiningTy::FnDef(def_id, ..)
-            | DefiningTy::Const(def_id, ..) => def_id,
+            | DefiningTy::Const(def_id, ..)
+            | DefiningTy::InlineConst(def_id, ..) => def_id,
         }
     }
 }
@@ -242,7 +247,7 @@ impl<'tcx> UniversalRegions<'tcx> {
         tcx: TyCtxt<'tcx>,
         closure_substs: SubstsRef<'tcx>,
         expected_num_vars: usize,
-        closure_base_def_id: DefId,
+        typeck_root_def_id: DefId,
     ) -> IndexVec<RegionVid, ty::Region<'tcx>> {
         let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
         region_mapping.push(tcx.lifetimes.re_static);
@@ -250,7 +255,7 @@ impl<'tcx> UniversalRegions<'tcx> {
             region_mapping.push(fr);
         });
 
-        for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+        for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
             region_mapping.push(r);
         });
 
@@ -344,8 +349,8 @@ impl<'tcx> UniversalRegions<'tcx> {
                 // tests, and the resulting print-outs include def-ids
                 // and other things that are not stable across tests!
                 // So we just include the region-vid. Annoying.
-                let closure_base_def_id = tcx.closure_base_def_id(def_id);
-                for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+                let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
+                for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
                     err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
                 });
             }
@@ -359,8 +364,8 @@ impl<'tcx> UniversalRegions<'tcx> {
                 // FIXME: As above, we'd like to print out the region
                 // `r` but doing so is not stable across architectures
                 // and so forth.
-                let closure_base_def_id = tcx.closure_base_def_id(def_id);
-                for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+                let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
+                for_each_late_bound_region_defined_on(tcx, typeck_root_def_id, |r| {
                     err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),));
                 });
             }
@@ -376,6 +381,12 @@ impl<'tcx> UniversalRegions<'tcx> {
                     tcx.def_path_str_with_substs(def_id, substs),
                 ));
             }
+            DefiningTy::InlineConst(def_id, substs) => {
+                err.note(&format!(
+                    "defining inline constant type: {}",
+                    tcx.def_path_str_with_substs(def_id, substs),
+                ));
+            }
         }
     }
 }
@@ -411,7 +422,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         let mut indices = self.compute_indices(fr_static, defining_ty);
         debug!("build: indices={:?}", indices);
 
-        let closure_base_def_id = self.infcx.tcx.closure_base_def_id(self.mir_def.did.to_def_id());
+        let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
 
         // If this is a closure or generator, then the late-bound regions from the enclosing
         // function are actually external regions to us. For example, here, 'a is not local
@@ -419,7 +430,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         // fn foo<'a>() {
         //     let c = || { let x: &'a u32 = ...; }
         // }
-        if self.mir_def.did.to_def_id() != closure_base_def_id {
+        if self.mir_def.did.to_def_id() != typeck_root_def_id {
             self.infcx
                 .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices)
         }
@@ -437,7 +448,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         );
         // Converse of above, if this is a function then the late-bound regions declared on its
         // signature are local to the fn.
-        if self.mir_def.did.to_def_id() == closure_base_def_id {
+        if self.mir_def.did.to_def_id() == typeck_root_def_id {
             self.infcx
                 .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
         }
@@ -502,12 +513,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
     /// see `DefiningTy` for details.
     fn defining_ty(&self) -> DefiningTy<'tcx> {
         let tcx = self.infcx.tcx;
-        let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did.to_def_id());
+        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
 
         match tcx.hir().body_owner_kind(self.mir_hir_id) {
             BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
-                let defining_ty = if self.mir_def.did.to_def_id() == closure_base_def_id {
-                    tcx.type_of(closure_base_def_id)
+                let defining_ty = if self.mir_def.did.to_def_id() == typeck_root_def_id {
+                    tcx.type_of(typeck_root_def_id)
                 } else {
                     let tables = tcx.typeck(self.mir_def.did);
                     tables.node_type(self.mir_hir_id)
@@ -534,11 +545,21 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             }
 
             BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
-                assert_eq!(self.mir_def.did.to_def_id(), closure_base_def_id);
-                let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id);
-                let substs =
-                    self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
-                DefiningTy::Const(self.mir_def.did.to_def_id(), substs)
+                let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
+                if self.mir_def.did.to_def_id() == typeck_root_def_id {
+                    let substs =
+                        self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs);
+                    DefiningTy::Const(self.mir_def.did.to_def_id(), substs)
+                } else {
+                    let ty = tcx.typeck(self.mir_def.did).node_type(self.mir_hir_id);
+                    let substs = InlineConstSubsts::new(
+                        tcx,
+                        InlineConstSubstsParts { parent_substs: identity_substs, ty },
+                    )
+                    .substs;
+                    let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs);
+                    DefiningTy::InlineConst(self.mir_def.did.to_def_id(), substs)
+                }
             }
         }
     }
@@ -553,17 +574,19 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         defining_ty: DefiningTy<'tcx>,
     ) -> UniversalRegionIndices<'tcx> {
         let tcx = self.infcx.tcx;
-        let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did.to_def_id());
-        let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id);
+        let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id());
+        let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
         let fr_substs = match defining_ty {
-            DefiningTy::Closure(_, ref substs) | DefiningTy::Generator(_, ref substs, _) => {
+            DefiningTy::Closure(_, ref substs)
+            | DefiningTy::Generator(_, ref substs, _)
+            | DefiningTy::InlineConst(_, ref substs) => {
                 // In the case of closures, we rely on the fact that
                 // the first N elements in the ClosureSubsts are
-                // inherited from the `closure_base_def_id`.
+                // inherited from the `typeck_root_def_id`.
                 // Therefore, when we zip together (below) with
                 // `identity_substs`, we will get only those regions
                 // that correspond to early-bound regions declared on
-                // the `closure_base_def_id`.
+                // the `typeck_root_def_id`.
                 assert!(substs.len() >= identity_substs.len());
                 assert_eq!(substs.regions().count(), identity_substs.regions().count());
                 substs
@@ -648,6 +671,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 let ty = indices.fold_to_region_vids(tcx, ty);
                 ty::Binder::dummy(tcx.intern_type_list(&[ty]))
             }
+
+            DefiningTy::InlineConst(def_id, substs) => {
+                assert_eq!(self.mir_def.did.to_def_id(), def_id);
+                let ty = substs.as_inline_const().ty();
+                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
+            }
         }
     }
 }
@@ -736,8 +765,8 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
         indices: &mut UniversalRegionIndices<'tcx>,
     ) {
         debug!("replace_late_bound_regions_with_nll_infer_vars(mir_def_id={:?})", mir_def_id);
-        let closure_base_def_id = self.tcx.closure_base_def_id(mir_def_id.to_def_id());
-        for_each_late_bound_region_defined_on(self.tcx, closure_base_def_id, |r| {
+        let typeck_root_def_id = self.tcx.typeck_root_def_id(mir_def_id.to_def_id());
+        for_each_late_bound_region_defined_on(self.tcx, typeck_root_def_id, |r| {
             debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r);
             if !indices.indices.contains_key(&r) {
                 let region_vid = self.next_nll_region_var(FR);
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 50127b5b15c..41662f46f11 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -19,7 +19,7 @@ struct AsmArgs {
     operands: Vec<(ast::InlineAsmOperand, Span)>,
     named_args: FxHashMap<Symbol, usize>,
     reg_args: FxHashSet<usize>,
-    clobber_abi: Option<(Symbol, Span)>,
+    clobber_abis: Vec<(Symbol, Span)>,
     options: ast::InlineAsmOptions,
     options_spans: Vec<Span>,
 }
@@ -64,7 +64,7 @@ fn parse_args<'a>(
         operands: vec![],
         named_args: FxHashMap::default(),
         reg_args: FxHashSet::default(),
-        clobber_abi: None,
+        clobber_abis: Vec::new(),
         options: ast::InlineAsmOptions::empty(),
         options_spans: vec![],
     };
@@ -210,9 +210,9 @@ fn parse_args<'a>(
                 .span_labels(args.options_spans.clone(), "previous options")
                 .span_label(span, "argument")
                 .emit();
-        } else if let Some((_, abi_span)) = args.clobber_abi {
+        } else if let Some((_, abi_span)) = args.clobber_abis.last() {
             ecx.struct_span_err(span, "arguments are not allowed after clobber_abi")
-                .span_label(abi_span, "clobber_abi")
+                .span_label(*abi_span, "clobber_abi")
                 .span_label(span, "argument")
                 .emit();
         }
@@ -322,10 +322,13 @@ fn parse_args<'a>(
         // Bail out now since this is likely to confuse MIR
         return Err(err);
     }
-    if let Some((_, abi_span)) = args.clobber_abi {
+
+    if args.clobber_abis.len() > 0 {
         if is_global_asm {
-            let err =
-                ecx.struct_span_err(abi_span, "`clobber_abi` cannot be used with `global_asm!`");
+            let err = ecx.struct_span_err(
+                args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
+                "`clobber_abi` cannot be used with `global_asm!`",
+            );
 
             // Bail out now since this is likely to confuse later stages
             return Err(err);
@@ -335,7 +338,10 @@ fn parse_args<'a>(
                 regclass_outputs.clone(),
                 "asm with `clobber_abi` must specify explicit registers for outputs",
             )
-            .span_label(abi_span, "clobber_abi")
+            .span_labels(
+                args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
+                "clobber_abi",
+            )
             .span_labels(regclass_outputs, "generic outputs")
             .emit();
         }
@@ -439,37 +445,61 @@ fn parse_clobber_abi<'a>(
 
     p.expect(&token::OpenDelim(token::DelimToken::Paren))?;
 
-    let clobber_abi = match p.parse_str_lit() {
-        Ok(str_lit) => str_lit.symbol_unescaped,
-        Err(opt_lit) => {
-            let span = opt_lit.map_or(p.token.span, |lit| lit.span);
-            let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
-            err.span_label(span, "not a string literal");
-            return Err(err);
-        }
-    };
+    if p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
+        let err = p.sess.span_diagnostic.struct_span_err(
+            p.token.span,
+            "at least one abi must be provided as an argument to `clobber_abi`",
+        );
+        return Err(err);
+    }
 
-    p.expect(&token::CloseDelim(token::DelimToken::Paren))?;
+    let mut new_abis = Vec::new();
+    loop {
+        match p.parse_str_lit() {
+            Ok(str_lit) => {
+                new_abis.push((str_lit.symbol_unescaped, str_lit.span));
+            }
+            Err(opt_lit) => {
+                // If the non-string literal is a closing paren then it's the end of the list and is fine
+                if p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
+                    break;
+                }
+                let span = opt_lit.map_or(p.token.span, |lit| lit.span);
+                let mut err =
+                    p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
+                err.span_label(span, "not a string literal");
+                return Err(err);
+            }
+        };
 
-    let new_span = span_start.to(p.prev_token.span);
+        // Allow trailing commas
+        if p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
+            break;
+        }
+        p.expect(&token::Comma)?;
+    }
 
-    if let Some((_, prev_span)) = args.clobber_abi {
-        let mut err = p
-            .sess
-            .span_diagnostic
-            .struct_span_err(new_span, "clobber_abi specified multiple times");
-        err.span_label(prev_span, "clobber_abi previously specified here");
-        return Err(err);
-    } else if !args.options_spans.is_empty() {
+    let full_span = span_start.to(p.prev_token.span);
+
+    if !args.options_spans.is_empty() {
         let mut err = p
             .sess
             .span_diagnostic
-            .struct_span_err(new_span, "clobber_abi is not allowed after options");
+            .struct_span_err(full_span, "clobber_abi is not allowed after options");
         err.span_labels(args.options_spans.clone(), "options");
         return Err(err);
     }
 
-    args.clobber_abi = Some((clobber_abi, new_span));
+    match &new_abis[..] {
+        // should have errored above during parsing
+        [] => unreachable!(),
+        [(abi, _span)] => args.clobber_abis.push((*abi, full_span)),
+        [abis @ ..] => {
+            for (abi, span) in abis {
+                args.clobber_abis.push((*abi, *span));
+            }
+        }
+    }
 
     Ok(())
 }
@@ -770,7 +800,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
         template,
         template_strs: template_strs.into_boxed_slice(),
         operands: args.operands,
-        clobber_abi: args.clobber_abi,
+        clobber_abis: args.clobber_abis,
         options: args.options,
         line_spans,
     })
@@ -815,7 +845,7 @@ pub fn expand_global_asm<'cx>(
                     ident: Ident::empty(),
                     attrs: Vec::new(),
                     id: ast::DUMMY_NODE_ID,
-                    kind: ast::ItemKind::GlobalAsm(inline_asm),
+                    kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
                     vis: ast::Visibility {
                         span: sp.shrink_to_lo(),
                         kind: ast::VisibilityKind::Inherited,
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index f0056cb7976..097eaddb874 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -527,17 +527,9 @@ impl<'a, 'b> Context<'a, 'b> {
                         self.verify_arg_type(Exact(idx), ty)
                     }
                     None => {
-                        let capture_feature_enabled = self
-                            .ecx
-                            .ecfg
-                            .features
-                            .map_or(false, |features| features.format_args_capture);
-
                         // For the moment capturing variables from format strings expanded from macros is
                         // disabled (see RFC #2795)
-                        let can_capture = capture_feature_enabled && self.is_literal;
-
-                        if can_capture {
+                        if self.is_literal {
                             // Treat this name as a variable to capture from the surrounding scope
                             let idx = self.args.len();
                             self.arg_types.push(Vec::new());
@@ -559,23 +551,15 @@ impl<'a, 'b> Context<'a, 'b> {
                             };
                             let mut err = self.ecx.struct_span_err(sp, &msg[..]);
 
-                            if capture_feature_enabled && !self.is_literal {
-                                err.note(&format!(
-                                    "did you intend to capture a variable `{}` from \
-                                     the surrounding scope?",
-                                    name
-                                ));
-                                err.note(
-                                    "to avoid ambiguity, `format_args!` cannot capture variables \
-                                     when the format string is expanded from a macro",
-                                );
-                            } else if self.ecx.parse_sess().unstable_features.is_nightly_build() {
-                                err.help(&format!(
-                                    "if you intended to capture `{}` from the surrounding scope, add \
-                                     `#![feature(format_args_capture)]` to the crate attributes",
-                                    name
-                                ));
-                            }
+                            err.note(&format!(
+                                "did you intend to capture a variable `{}` from \
+                                 the surrounding scope?",
+                                name
+                            ));
+                            err.note(
+                                "to avoid ambiguity, `format_args!` cannot capture variables \
+                                 when the format string is expanded from a macro",
+                            );
 
                             err.emit();
                         }
@@ -760,16 +744,11 @@ impl<'a, 'b> Context<'a, 'b> {
     /// Actually builds the expression which the format_args! block will be
     /// expanded to.
     fn into_expr(self) -> P<ast::Expr> {
-        let mut locals =
-            Vec::with_capacity((0..self.args.len()).map(|i| self.arg_unique_types[i].len()).sum());
-        let mut counts = Vec::with_capacity(self.count_args.len());
-        let mut pats = Vec::with_capacity(self.args.len());
+        let mut args = Vec::with_capacity(
+            self.arg_unique_types.iter().map(|v| v.len()).sum::<usize>() + self.count_args.len(),
+        );
         let mut heads = Vec::with_capacity(self.args.len());
 
-        let names_pos: Vec<_> = (0..self.args.len())
-            .map(|i| Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
-            .collect();
-
         // First, build up the static array which will become our precompiled
         // format "string"
         let pieces = self.ecx.expr_vec_slice(self.fmtsp, self.str_pieces);
@@ -787,11 +766,8 @@ impl<'a, 'b> Context<'a, 'b> {
         // of each variable because we don't want to move out of the arguments
         // passed to this function.
         for (i, e) in self.args.into_iter().enumerate() {
-            let name = names_pos[i];
-            let span = self.ecx.with_def_site_ctxt(e.span);
-            pats.push(self.ecx.pat_ident(span, name));
             for arg_ty in self.arg_unique_types[i].iter() {
-                locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
+                args.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, i));
             }
             heads.push(self.ecx.expr_addr_of(e.span, e));
         }
@@ -800,15 +776,11 @@ impl<'a, 'b> Context<'a, 'b> {
                 Exact(i) => i,
                 _ => panic!("should never happen"),
             };
-            let name = names_pos[index];
             let span = spans_pos[index];
-            counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count, name));
+            args.push(Context::format_arg(self.ecx, self.macsp, span, &Count, index));
         }
 
-        // Now create a vector containing all the arguments
-        let args = locals.into_iter().chain(counts.into_iter());
-
-        let args_array = self.ecx.expr_vec(self.macsp, args.collect());
+        let args_array = self.ecx.expr_vec(self.macsp, args);
 
         // Constructs an AST equivalent to:
         //
@@ -838,7 +810,7 @@ impl<'a, 'b> Context<'a, 'b> {
         // But the nested match expression is proved to perform not as well
         // as series of let's; the first approach does.
         let args_match = {
-            let pat = self.ecx.pat_tuple(self.macsp, pats);
+            let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::_args, self.macsp));
             let arm = self.ecx.arm(self.macsp, pat, args_array);
             let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads));
             self.ecx.expr_match(self.macsp, head, vec![arm])
@@ -877,10 +849,11 @@ impl<'a, 'b> Context<'a, 'b> {
         macsp: Span,
         mut sp: Span,
         ty: &ArgumentType,
-        arg: Ident,
+        arg_index: usize,
     ) -> P<ast::Expr> {
         sp = ecx.with_def_site_ctxt(sp);
-        let arg = ecx.expr_ident(sp, arg);
+        let arg = ecx.expr_ident(sp, Ident::new(sym::_args, sp));
+        let arg = ecx.expr(sp, ast::ExprKind::Field(arg, Ident::new(sym::integer(arg_index), sp)));
         let trait_ = match *ty {
             Placeholder(trait_) if trait_ == "<invalid>" => return DummyResult::raw_expr(sp, true),
             Placeholder(trait_) => trait_,
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 64bd586662d..f3a2382ef32 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -316,7 +316,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     extended_asm.add_input_operand(None, "r", result.llval);
                     extended_asm.add_clobber("memory");
                     extended_asm.set_volatile_flag(true);
-                    
+
                     // We have copied the value to `result` already.
                     return;
                 }
@@ -363,10 +363,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
         cond
     }
 
-    fn sideeffect(&mut self) {
-        // TODO(antoyo)
-    }
-
     fn type_test(&mut self, _pointer: Self::Value, _typeid: Self::Value) -> Self::Value {
         // Unsupported.
         self.context.new_rvalue_from_int(self.int_type, 0)
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 82c3c2006eb..3d05fc15b38 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -17,6 +17,7 @@ use rustc_codegen_ssa::back::write::{
 };
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
+use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_errors::{FatalError, Handler, Level};
 use rustc_fs_util::{link_or_copy, path_to_c_string};
@@ -53,6 +54,7 @@ pub fn write_output_file(
     output: &Path,
     dwo_output: Option<&Path>,
     file_type: llvm::FileType,
+    self_profiler_ref: &SelfProfilerRef,
 ) -> Result<(), FatalError> {
     unsafe {
         let output_c = path_to_c_string(output);
@@ -76,6 +78,19 @@ pub fn write_output_file(
                 file_type,
             )
         };
+
+        // Record artifact sizes for self-profiling
+        if result == llvm::LLVMRustResult::Success {
+            let artifact_kind = match file_type {
+                llvm::FileType::ObjectFile => "object_file",
+                llvm::FileType::AssemblyFile => "assembly_file",
+            };
+            record_artifact_size(self_profiler_ref, artifact_kind, output);
+            if let Some(dwo_file) = dwo_output {
+                record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
+            }
+        }
+
         result.into_result().map_err(|()| {
             let msg = format!("could not write output to {}", output.display());
             llvm_err(handler, &msg)
@@ -286,7 +301,7 @@ fn report_inline_asm(
         cookie = 0;
     }
     let level = match level {
-        llvm::DiagnosticLevel::Error => Level::Error,
+        llvm::DiagnosticLevel::Error => Level::Error { lint: false },
         llvm::DiagnosticLevel::Warning => Level::Warning,
         llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
     };
@@ -752,6 +767,14 @@ pub(crate) unsafe fn codegen(
             let thin = ThinBuffer::new(llmod);
             let data = thin.data();
 
+            if let Some(bitcode_filename) = bc_out.file_name() {
+                cgcx.prof.artifact_size(
+                    "llvm_bitcode",
+                    bitcode_filename.to_string_lossy(),
+                    data.len() as u64,
+                );
+            }
+
             if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
                 let _timer = cgcx.prof.generic_activity_with_arg(
                     "LLVM_module_codegen_emit_bitcode",
@@ -812,6 +835,11 @@ pub(crate) unsafe fn codegen(
             }
 
             let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
+
+            if result == llvm::LLVMRustResult::Success {
+                record_artifact_size(&cgcx.prof, "llvm_ir", &out);
+            }
+
             result.into_result().map_err(|()| {
                 let msg = format!("failed to write LLVM IR to {}", out.display());
                 llvm_err(diag_handler, &msg)
@@ -842,6 +870,7 @@ pub(crate) unsafe fn codegen(
                     &path,
                     None,
                     llvm::FileType::AssemblyFile,
+                    &cgcx.prof,
                 )
             })?;
         }
@@ -875,6 +904,7 @@ pub(crate) unsafe fn codegen(
                         &obj_out,
                         dwo_out,
                         llvm::FileType::ObjectFile,
+                        &cgcx.prof,
                     )
                 })?;
             }
@@ -1131,3 +1161,19 @@ fn create_msvc_imps(
         symbol_name.starts_with(b"__llvm_profile_")
     }
 }
+
+fn record_artifact_size(
+    self_profiler_ref: &SelfProfilerRef,
+    artifact_kind: &'static str,
+    path: &Path,
+) {
+    // Don't stat the file if we are not going to record its size.
+    if !self_profiler_ref.enabled() {
+        return;
+    }
+
+    if let Some(artifact_name) = path.file_name() {
+        let file_size = std::fs::metadata(path).map(|m| m.len()).unwrap_or(0);
+        self_profiler_ref.artifact_size(artifact_kind, artifact_name.to_string_lossy(), file_size);
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 1dba264a961..613a8df891c 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -597,7 +597,6 @@ impl CodegenCx<'b, 'tcx> {
         ifn!("llvm.trap", fn() -> void);
         ifn!("llvm.debugtrap", fn() -> void);
         ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
-        ifn!("llvm.sideeffect", fn() -> void);
 
         ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
         ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 1f1bd73c7d0..2a6bf7d9b1a 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -322,7 +322,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         type_names::push_item_name(self.tcx(), def_id, false, &mut name);
 
         // Find the enclosing function, in case this is a closure.
-        let enclosing_fn_def_id = self.tcx().closure_base_def_id(def_id);
+        let enclosing_fn_def_id = self.tcx().typeck_root_def_id(def_id);
 
         // Get_template_parameters() will append a `<...>` clause to the function
         // name if necessary.
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e63fb22829a..a7e34b08059 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
 use rustc_middle::ty::{self, Ty};
 use rustc_middle::{bug, span_bug};
 use rustc_span::{sym, symbol::kw, Span, Symbol};
-use rustc_target::abi::{self, HasDataLayout, Primitive};
+use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
 use rustc_target::spec::{HasTargetSpec, PanicStrategy};
 
 use std::cmp::Ordering;
@@ -392,15 +392,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
     }
 
-    fn sideeffect(&mut self) {
-        // This kind of check would make a ton of sense in the caller, but currently the only
-        // caller of this function is in `rustc_codegen_ssa`, which is agnostic to whether LLVM
-        // codegen backend being used, and so is unable to check the LLVM version.
-        if unsafe { llvm::LLVMRustVersionMajor() } < 12 {
-            self.call_intrinsic("llvm.sideeffect", &[]);
-        }
-    }
-
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value {
         // Test the called operand using llvm.type.test intrinsic. The LowerTypeTests link-time
         // optimization pass replaces calls to this intrinsic with code to test type membership.
@@ -857,28 +848,39 @@ fn generic_simd_intrinsic(
     let arg_tys = sig.inputs();
 
     if name == sym::simd_select_bitmask {
-        let in_ty = arg_tys[0];
-        let m_len = match in_ty.kind() {
-            // Note that this `.unwrap()` crashes for isize/usize, that's sort
-            // of intentional as there's not currently a use case for that.
-            ty::Int(i) => i.bit_width().unwrap(),
-            ty::Uint(i) => i.bit_width().unwrap(),
-            _ => return_error!("`{}` is not an integral type", in_ty),
-        };
         require_simd!(arg_tys[1], "argument");
-        let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
-        require!(
-            // Allow masks for vectors with fewer than 8 elements to be
-            // represented with a u8 or i8.
-            m_len == v_len || (m_len == 8 && v_len < 8),
-            "mismatched lengths: mask length `{}` != other vector length `{}`",
-            m_len,
-            v_len
-        );
+        let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
+
+        let expected_int_bits = (len.max(8) - 1).next_power_of_two();
+        let expected_bytes = len / 8 + ((len % 8 > 0) as u64);
+
+        let mask_ty = arg_tys[0];
+        let mask = match mask_ty.kind() {
+            ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
+            ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
+            ty::Array(elem, len)
+                if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
+                    && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all())
+                        == Some(expected_bytes) =>
+            {
+                let place = PlaceRef::alloca(bx, args[0].layout);
+                args[0].val.store(bx, place);
+                let int_ty = bx.type_ix(expected_bytes * 8);
+                let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty));
+                bx.load(int_ty, ptr, Align::ONE)
+            }
+            _ => return_error!(
+                "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`",
+                mask_ty,
+                expected_int_bits,
+                expected_bytes
+            ),
+        };
+
         let i1 = bx.type_i1();
-        let im = bx.type_ix(v_len);
-        let i1xn = bx.type_vector(i1, v_len);
-        let m_im = bx.trunc(args[0].immediate(), im);
+        let im = bx.type_ix(len);
+        let i1xn = bx.type_vector(i1, len);
+        let m_im = bx.trunc(mask, im);
         let m_i1s = bx.bitcast(m_im, i1xn);
         return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
     }
@@ -1056,16 +1058,16 @@ fn generic_simd_intrinsic(
 
     if name == sym::simd_bitmask {
         // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a
-        // vector mask and returns an unsigned integer containing the most
-        // significant bit (MSB) of each lane.
-
-        // If the vector has less than 8 lanes, a u8 is returned with zeroed
-        // trailing bits.
+        // vector mask and returns the most significant bit (MSB) of each lane in the form
+        // of either:
+        // * an unsigned integer
+        // * an array of `u8`
+        // If the vector has less than 8 lanes, a u8 is returned with zeroed trailing bits.
+        //
+        // The bit order of the result depends on the byte endianness, LSB-first for little
+        // endian and MSB-first for big endian.
         let expected_int_bits = in_len.max(8);
-        match ret_ty.kind() {
-            ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => (),
-            _ => return_error!("bitmask `{}`, expected `u{}`", ret_ty, expected_int_bits),
-        }
+        let expected_bytes = expected_int_bits / 8 + ((expected_int_bits % 8 > 0) as u64);
 
         // Integer vector <i{in_bitwidth} x in_len>:
         let (i_xn, in_elem_bitwidth) = match in_elem.kind() {
@@ -1095,8 +1097,34 @@ fn generic_simd_intrinsic(
         let i1xn = bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len));
         // Bitcast <i1 x N> to iN:
         let i_ = bx.bitcast(i1xn, bx.type_ix(in_len));
-        // Zero-extend iN to the bitmask type:
-        return Ok(bx.zext(i_, bx.type_ix(expected_int_bits)));
+
+        match ret_ty.kind() {
+            ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {
+                // Zero-extend iN to the bitmask type:
+                return Ok(bx.zext(i_, bx.type_ix(expected_int_bits)));
+            }
+            ty::Array(elem, len)
+                if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
+                    && len.try_eval_usize(bx.tcx, ty::ParamEnv::reveal_all())
+                        == Some(expected_bytes) =>
+            {
+                // Zero-extend iN to the array lengh:
+                let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8));
+
+                // Convert the integer to a byte array
+                let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE);
+                bx.store(ze, ptr, Align::ONE);
+                let array_ty = bx.type_array(bx.type_i8(), expected_bytes);
+                let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty));
+                return Ok(bx.load(array_ty, ptr, Align::ONE));
+            }
+            _ => return_error!(
+                "cannot return `{}`, expected `u{}` or `[u8; {}]`",
+                ret_ty,
+                expected_int_bits,
+                expected_bytes
+            ),
+        }
     }
 
     fn simd_simple_float_intrinsic(
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6c02543bd7c..638b2a7b5a9 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -121,6 +121,19 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
             if sess.opts.json_artifact_notifications {
                 sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename, "link");
             }
+
+            if sess.prof.enabled() {
+                if let Some(artifact_name) = out_filename.file_name() {
+                    // Record size for self-profiling
+                    let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0);
+
+                    sess.prof.artifact_size(
+                        "linked_artifact",
+                        artifact_name.to_string_lossy(),
+                        file_size,
+                    );
+                }
+            }
         }
     }
 
@@ -1021,8 +1034,10 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
         SplitDebuginfo::Packed => link_dwarf_object(sess, &out_filename),
     }
 
+    let strip = strip_value(sess);
+
     if sess.target.is_like_osx {
-        match sess.opts.debugging_opts.strip {
+        match strip {
             Strip::Debuginfo => strip_symbols_in_osx(sess, &out_filename, Some("-S")),
             Strip::Symbols => strip_symbols_in_osx(sess, &out_filename, None),
             Strip::None => {}
@@ -1030,6 +1045,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
     }
 }
 
+// Temporarily support both -Z strip and -C strip
+fn strip_value(sess: &Session) -> Strip {
+    match (sess.opts.debugging_opts.strip, sess.opts.cg.strip) {
+        (s, Strip::None) => s,
+        (_, s) => s,
+    }
+}
+
 fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Option<&str>) {
     let mut cmd = Command::new("strip");
     if let Some(option) = option {
@@ -2001,7 +2024,7 @@ fn add_order_independent_options(
     cmd.optimize();
 
     // Pass debuginfo and strip flags down to the linker.
-    cmd.debuginfo(sess.opts.debugging_opts.strip);
+    cmd.debuginfo(strip_value(sess));
 
     // We want to prevent the compiler from accidentally leaking in any system libraries,
     // so by default we tell linkers not to link to any default libraries.
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 429dc45d6a4..15d16e7d3d6 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -219,19 +219,36 @@ pub struct GccLinker<'a> {
 }
 
 impl<'a> GccLinker<'a> {
-    /// Argument that must be passed *directly* to the linker
+    /// Passes an argument directly to the linker.
     ///
-    /// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used.
-    fn linker_arg<S>(&mut self, arg: S) -> &mut Self
-    where
-        S: AsRef<OsStr>,
-    {
-        if !self.is_ld {
-            let mut os = OsString::from("-Wl,");
-            os.push(arg.as_ref());
-            self.cmd.arg(os);
+    /// When the linker is not ld-like such as when using a compiler as a linker, the argument is
+    /// prepended by `-Wl,`.
+    fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+        self.linker_args(&[arg]);
+        self
+    }
+
+    /// Passes a series of arguments directly to the linker.
+    ///
+    /// When the linker is ld-like, the arguments are simply appended to the command. When the
+    /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
+    /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
+    /// single argument is appended to the command to ensure that the order of the arguments is
+    /// preserved by the compiler.
+    fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self {
+        if self.is_ld {
+            args.into_iter().for_each(|a| {
+                self.cmd.arg(a);
+            });
         } else {
-            self.cmd.arg(arg);
+            if !args.is_empty() {
+                let mut s = OsString::from("-Wl");
+                for a in args {
+                    s.push(",");
+                    s.push(a);
+                }
+                self.cmd.arg(s);
+            }
         }
         self
     }
@@ -289,14 +306,19 @@ impl<'a> GccLinker<'a> {
         if let Some(path) = &self.sess.opts.debugging_opts.profile_sample_use {
             self.linker_arg(&format!("-plugin-opt=sample-profile={}", path.display()));
         };
-        self.linker_arg(&format!("-plugin-opt={}", opt_level));
-        self.linker_arg(&format!("-plugin-opt=mcpu={}", self.target_cpu));
+        self.linker_args(&[
+            &format!("-plugin-opt={}", opt_level),
+            &format!("-plugin-opt=mcpu={}", self.target_cpu),
+        ]);
     }
 
     fn build_dylib(&mut self, out_filename: &Path) {
         // On mac we need to tell the linker to let this library be rpathed
         if self.sess.target.is_like_osx {
-            self.cmd.arg("-dynamiclib");
+            if !self.is_ld {
+                self.cmd.arg("-dynamiclib");
+            }
+
             self.linker_arg("-dylib");
 
             // Note that the `osx_rpath_install_name` option here is a hack
@@ -304,10 +326,9 @@ impl<'a> GccLinker<'a> {
             // principled solution at some point to force the compiler to pass
             // the right `-Wl,-install_name` with an `@rpath` in it.
             if self.sess.opts.cg.rpath || self.sess.opts.debugging_opts.osx_rpath_install_name {
-                self.linker_arg("-install_name");
-                let mut v = OsString::from("@rpath/");
-                v.push(out_filename.file_name().unwrap());
-                self.linker_arg(&v);
+                let mut rpath = OsString::from("@rpath/");
+                rpath.push(out_filename.file_name().unwrap());
+                self.linker_args(&[OsString::from("-install_name"), rpath]);
             }
         } else {
             self.cmd.arg("-shared");
@@ -381,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> {
                 self.build_dylib(out_filename);
             }
             LinkOutputKind::WasiReactorExe => {
-                self.linker_arg("--entry");
-                self.linker_arg("_initialize");
+                self.linker_args(&["--entry", "_initialize"]);
             }
         }
         // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc,
@@ -454,8 +474,7 @@ impl<'a> Linker for GccLinker<'a> {
         self.cmd.arg(path);
     }
     fn full_relro(&mut self) {
-        self.linker_arg("-zrelro");
-        self.linker_arg("-znow");
+        self.linker_args(&["-zrelro", "-znow"]);
     }
     fn partial_relro(&mut self) {
         self.linker_arg("-zrelro");
@@ -639,7 +658,6 @@ impl<'a> Linker for GccLinker<'a> {
         }
 
         let is_windows = self.sess.target.is_like_windows;
-        let mut arg = OsString::new();
         let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
 
         debug!("EXPORTED SYMBOLS:");
@@ -691,27 +709,18 @@ impl<'a> Linker for GccLinker<'a> {
         }
 
         if self.sess.target.is_like_osx {
-            if !self.is_ld {
-                arg.push("-Wl,")
-            }
-            arg.push("-exported_symbols_list,");
+            self.linker_args(&[OsString::from("-exported_symbols_list"), path.into()]);
         } else if self.sess.target.is_like_solaris {
-            if !self.is_ld {
-                arg.push("-Wl,")
-            }
-            arg.push("-M,");
+            self.linker_args(&[OsString::from("-M"), path.into()]);
         } else {
-            if !self.is_ld {
-                arg.push("-Wl,")
-            }
-            // Both LD and LLD accept export list in *.def file form, there are no flags required
-            if !is_windows {
-                arg.push("--version-script=")
+            if is_windows {
+                self.linker_arg(path);
+            } else {
+                let mut arg = OsString::from("--version-script=");
+                arg.push(path);
+                self.linker_arg(arg);
             }
         }
-
-        arg.push(&path);
-        self.cmd.arg(arg);
     }
 
     fn subsystem(&mut self, subsystem: &str) {
@@ -769,8 +778,7 @@ impl<'a> Linker for GccLinker<'a> {
             self.linker_arg("--as-needed");
         } else if self.sess.target.is_like_solaris {
             // -z ignore is the Solaris equivalent to the GNU ld --as-needed option
-            self.linker_arg("-z");
-            self.linker_arg("ignore");
+            self.linker_args(&["-z", "ignore"]);
         }
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index b2edc6c0183..85d51ea9a20 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1757,7 +1757,7 @@ impl SharedEmitterMain {
                     let msg = msg.strip_prefix("error: ").unwrap_or(&msg);
 
                     let mut err = match level {
-                        Level::Error => sess.struct_err(&msg),
+                        Level::Error { lint: false } => sess.struct_err(&msg),
                         Level::Warning => sess.struct_warn(&msg),
                         Level::Note => sess.struct_note_without_error(&msg),
                         _ => bug!("Invalid inline asm diagnostic level"),
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a9471f7b771..c8f388bfa1d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -980,17 +980,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             mir::TerminatorKind::Goto { target } => {
-                if bb == target {
-                    // This is an unconditional branch back to this same basic block. That means we
-                    // have something like a `loop {}` statement. LLVM versions before 12.0
-                    // miscompile this because they assume forward progress. For older versions
-                    // try to handle just this specific case which comes up commonly in practice
-                    // (e.g., in embedded code).
-                    //
-                    // NB: the `sideeffect` currently checks for the LLVM version used internally.
-                    bx.sideeffect();
-                }
-
                 helper.funclet_br(self, &mut bx, target);
             }
 
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index caeeb23feb4..b4420df5df4 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -20,6 +20,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("aes", Some(sym::arm_target_feature)),
     ("sha2", Some(sym::arm_target_feature)),
     ("i8mm", Some(sym::arm_target_feature)),
+    ("dotprod", Some(sym::arm_target_feature)),
     ("v5te", Some(sym::arm_target_feature)),
     ("v6", Some(sym::arm_target_feature)),
     ("v6k", Some(sym::arm_target_feature)),
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 78bf22ef9f2..02be6cd360c 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -20,10 +20,6 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
     fn abort(&mut self);
     fn assume(&mut self, val: Self::Value);
     fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value;
-    /// Emits a forced side effect.
-    ///
-    /// Currently has any effect only when LLVM versions prior to 12.0 are used as the backend.
-    fn sideeffect(&mut self);
     /// Trait method used to test whether a given pointer is associated with a type identifier.
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value;
     /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 57af0ff0714..6d3a89c0a8a 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -42,6 +42,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
                     | DefKind::Static
                     | DefKind::ConstParam
                     | DefKind::AnonConst
+                    | DefKind::InlineConst
                     | DefKind::AssocConst
             ),
         "Unexpected DefKind: {:?}",
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 323e102b872..51207828935 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -131,6 +131,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// Whether to enforce the validity invariant
     fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
+    /// Whether to enforce validity (e.g., initialization and not having ptr provenance)
+    /// of integers and floats.
+    fn enforce_number_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
+
     /// Whether function calls should be [ABI](Abi)-checked.
     fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
         true
@@ -427,6 +431,11 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     }
 
     #[inline(always)]
+    fn enforce_number_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
+        true
+    }
+
+    #[inline(always)]
     fn call_extra_fn(
         _ecx: &mut InterpCx<$mir, $tcx, Self>,
         fn_val: !,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index b8b6ff93753..4aa3c83cc02 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(dest_ptr) => dest_ptr,
         };
 
+        // This checks relocation edges on the src, which needs to happen before
+        // `prepare_relocation_copy`.
+        let src_bytes = src_alloc
+            .get_bytes_with_uninit_and_ptr(&tcx, src_range)
+            .map_err(|e| e.to_interp_error(src_alloc_id))?
+            .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
         // first copy the relocations to a temporary buffer, because
         // `get_bytes_mut` will clear the relocations, which is correct,
         // since we don't want to keep any relocations at the target.
-        // (`get_bytes_with_uninit_and_ptr` below checks that there are no
-        // relocations overlapping the edges; those would not be handled correctly).
         let relocations =
             src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
         // Prepare a copy of the initialization mask.
         let compressed = src_alloc.compress_uninit_range(src_range);
-        // This checks relocation edges on the src.
-        let src_bytes = src_alloc
-            .get_bytes_with_uninit_and_ptr(&tcx, src_range)
-            .map_err(|e| e.to_interp_error(src_alloc_id))?
-            .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
 
         // Destination alloc preparations and access hooks.
         let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?;
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index fc69770bf6a..6be3e19a833 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -520,7 +520,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 let value = self.read_scalar(value)?;
                 // NOTE: Keep this in sync with the array optimization for int/float
                 // types below!
-                if self.ctfe_mode.is_some() {
+                if M::enforce_number_validity(self.ecx) {
                     // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
                     let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
                     if !is_bits {
@@ -528,9 +528,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                             { "{}", value } expected { "initialized plain (non-pointer) bytes" }
                         )
                     }
-                } else {
-                    // At run-time, for now, we accept *anything* for these types, including
-                    // uninit. We should fix that, but let's start low.
                 }
                 Ok(true)
             }
@@ -855,9 +852,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                     }
                 };
 
+                let allow_uninit_and_ptr = !M::enforce_number_validity(self.ecx);
                 match alloc.check_bytes(
                     alloc_range(Size::ZERO, size),
-                    /*allow_uninit_and_ptr*/ self.ctfe_mode.is_none(),
+                    allow_uninit_and_ptr,
                 ) {
                     // In the happy case, we needn't check anything else.
                     Ok(()) => {}
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 3785c170f6b..2854e6fd396 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -722,7 +722,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
         match elem {
             ProjectionElem::Deref => {
                 let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;
-                if let ty::RawPtr(_) = base_ty.kind() {
+                if base_ty.is_unsafe_ptr() {
                     if proj_base.is_empty() {
                         let decl = &self.body.local_decls[place_local];
                         if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
@@ -731,7 +731,13 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
                             return;
                         }
                     }
-                    self.check_op(ops::RawPtrDeref);
+
+                    // `*const T` is stable, `*mut T` is not
+                    if !base_ty.is_mutable_ptr() {
+                        return;
+                    }
+
+                    self.check_op(ops::RawMutPtrDeref);
                 }
 
                 if context.is_mutating_use() {
@@ -1054,8 +1060,9 @@ fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId)
         let mut fulfillment_cx = traits::FulfillmentContext::new();
         let sync_def_id = tcx.require_lang_item(LangItem::Sync, Some(body.span));
         fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
-        if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(&err, None, false);
+        let errors = fulfillment_cx.select_all_or_error(&infcx);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
         }
     });
 }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 230d023efb9..6391c886009 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -400,18 +400,18 @@ impl NonConstOp for RawPtrComparison {
 }
 
 #[derive(Debug)]
-pub struct RawPtrDeref;
-impl NonConstOp for RawPtrDeref {
+pub struct RawMutPtrDeref;
+impl NonConstOp for RawMutPtrDeref {
     fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
-        Status::Unstable(sym::const_raw_ptr_deref)
+        Status::Unstable(sym::const_mut_refs)
     }
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
             &ccx.tcx.sess.parse_sess,
-            sym::const_raw_ptr_deref,
+            sym::const_mut_refs,
             span,
-            &format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
+            &format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
         )
     }
 }
diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
index e92db9ea128..61c7239c55f 100644
--- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
@@ -34,39 +34,47 @@ pub struct SortedIndexMultiMap<I: Idx, K, V> {
 }
 
 impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
+    #[inline]
     pub fn new() -> Self {
         SortedIndexMultiMap { items: IndexVec::new(), idx_sorted_by_item_key: Vec::new() }
     }
 
+    #[inline]
     pub fn len(&self) -> usize {
         self.items.len()
     }
 
+    #[inline]
     pub fn is_empty(&self) -> bool {
         self.items.is_empty()
     }
 
     /// Returns an iterator over the items in the map in insertion order.
+    #[inline]
     pub fn into_iter(self) -> impl DoubleEndedIterator<Item = (K, V)> {
         self.items.into_iter()
     }
 
     /// Returns an iterator over the items in the map in insertion order along with their indices.
+    #[inline]
     pub fn into_iter_enumerated(self) -> impl DoubleEndedIterator<Item = (I, (K, V))> {
         self.items.into_iter_enumerated()
     }
 
     /// Returns an iterator over the items in the map in insertion order.
+    #[inline]
     pub fn iter(&self) -> impl '_ + DoubleEndedIterator<Item = (&K, &V)> {
         self.items.iter().map(|(ref k, ref v)| (k, v))
     }
 
     /// Returns an iterator over the items in the map in insertion order along with their indices.
+    #[inline]
     pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator<Item = (I, (&K, &V))> {
         self.items.iter_enumerated().map(|(i, (ref k, ref v))| (i, (k, v)))
     }
 
     /// Returns the item in the map with the given index.
+    #[inline]
     pub fn get(&self, idx: I) -> Option<&(K, V)> {
         self.items.get(idx)
     }
@@ -75,6 +83,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
+    #[inline]
     pub fn get_by_key(&'a self, key: K) -> impl 'a + Iterator<Item = &'a V> {
         self.get_by_key_enumerated(key).map(|(_, v)| v)
     }
@@ -84,6 +93,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
+    #[inline]
     pub fn get_by_key_enumerated(&'a self, key: K) -> impl '_ + Iterator<Item = (I, &V)> {
         let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key);
         self.idx_sorted_by_item_key[lower_bound..].iter().map_while(move |&i| {
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 9a57ec99144..09fe3a552a0 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -267,6 +267,7 @@ fn run_compiler(
                         None,
                         compiler.output_dir(),
                         compiler.output_file(),
+                        compiler.temps_dir(),
                     );
 
                     if should_stop == Compilation::Stop {
@@ -295,6 +296,7 @@ fn run_compiler(
             Some(compiler.input()),
             compiler.output_dir(),
             compiler.output_file(),
+            compiler.temps_dir(),
         )
         .and_then(|| {
             RustcDefaultCalls::list_metadata(
@@ -647,6 +649,7 @@ impl RustcDefaultCalls {
         input: Option<&Input>,
         odir: &Option<PathBuf>,
         ofile: &Option<PathBuf>,
+        temps_dir: &Option<PathBuf>,
     ) -> Compilation {
         use rustc_session::config::PrintRequest::*;
         // PrintRequest::NativeStaticLibs is special - printed during linking
@@ -685,7 +688,7 @@ impl RustcDefaultCalls {
                     });
                     let attrs = attrs.as_ref().unwrap();
                     let t_outputs = rustc_interface::util::build_output_filenames(
-                        input, odir, ofile, attrs, sess,
+                        input, odir, ofile, temps_dir, attrs, sess,
                     );
                     let id = rustc_session::output::find_crate_name(sess, attrs, input);
                     if *req == PrintRequest::CrateName {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0206.md b/compiler/rustc_error_codes/src/error_codes/E0206.md
index da53b671ad0..4405a2149ce 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0206.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0206.md
@@ -4,15 +4,12 @@ enum.
 Erroneous code example:
 
 ```compile_fail,E0206
-type Foo = [u8; 256];
-impl Copy for Foo { } // error!
-
 #[derive(Copy, Clone)]
 struct Bar;
 
 impl Copy for &'static mut Bar { } // error!
 ```
 
-You can only implement `Copy` for a struct or an enum. Both of the previous
-examples will fail, because neither `[u8; 256]` nor `&'static mut Bar`
-(mutable reference to `Bar`) is a struct or enum.
+You can only implement `Copy` for a struct or an enum.
+The previous example will fail because `&'static mut Bar`
+is not a struct or enum.
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 1eb497460e6..9db8f751390 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -66,7 +66,7 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String {
 /// Maps `Diagnostic::Level` to `snippet::AnnotationType`
 fn annotation_type_for_level(level: Level) -> AnnotationType {
     match level {
-        Level::Bug | Level::Fatal | Level::Error => AnnotationType::Error,
+        Level::Bug | Level::Fatal | Level::Error { .. } => AnnotationType::Error,
         Level::Warning => AnnotationType::Warning,
         Level::Note => AnnotationType::Note,
         Level::Help => AnnotationType::Help,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index f2381d75c56..e5116cd8dfe 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -114,7 +114,7 @@ impl Diagnostic {
 
     pub fn is_error(&self) -> bool {
         match self.level {
-            Level::Bug | Level::Fatal | Level::Error | Level::FailureNote => true,
+            Level::Bug | Level::Fatal | Level::Error { .. } | Level::FailureNote => true,
 
             Level::Warning | Level::Note | Level::Help | Level::Cancelled | Level::Allow => false,
         }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index b6cf332f511..bb3d3a415e7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -6,7 +6,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(backtrace)]
 #![feature(if_let_guard)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(let_else)]
 #![feature(nll)]
@@ -411,6 +411,8 @@ pub struct Handler {
 /// as well as inconsistent state observation.
 struct HandlerInner {
     flags: HandlerFlags,
+    /// The number of lint errors that have been emitted.
+    lint_err_count: usize,
     /// The number of errors that have been emitted, including duplicates.
     ///
     /// This is not necessarily the count that's reported to the user once
@@ -550,6 +552,7 @@ impl Handler {
             flags,
             inner: Lock::new(HandlerInner {
                 flags,
+                lint_err_count: 0,
                 err_count: 0,
                 warn_count: 0,
                 deduplicated_err_count: 0,
@@ -726,7 +729,13 @@ impl Handler {
     /// Construct a builder at the `Error` level with the `msg`.
     // FIXME: This method should be removed (every error should have an associated error code).
     pub fn struct_err(&self, msg: &str) -> DiagnosticBuilder<'_> {
-        DiagnosticBuilder::new(self, Level::Error, msg)
+        DiagnosticBuilder::new(self, Level::Error { lint: false }, msg)
+    }
+
+    /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors.
+    #[doc(hidden)]
+    pub fn struct_err_lint(&self, msg: &str) -> DiagnosticBuilder<'_> {
+        DiagnosticBuilder::new(self, Level::Error { lint: true }, msg)
     }
 
     /// Construct a builder at the `Error` level with the `msg` and the `code`.
@@ -790,11 +799,14 @@ impl Handler {
     }
 
     pub fn span_err(&self, span: impl Into<MultiSpan>, msg: &str) {
-        self.emit_diag_at_span(Diagnostic::new(Error, msg), span);
+        self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span);
     }
 
     pub fn span_err_with_code(&self, span: impl Into<MultiSpan>, msg: &str, code: DiagnosticId) {
-        self.emit_diag_at_span(Diagnostic::new_with_code(Error, Some(code), msg), span);
+        self.emit_diag_at_span(
+            Diagnostic::new_with_code(Error { lint: false }, Some(code), msg),
+            span,
+        );
     }
 
     pub fn span_warn(&self, span: impl Into<MultiSpan>, msg: &str) {
@@ -862,6 +874,9 @@ impl Handler {
     pub fn has_errors(&self) -> bool {
         self.inner.borrow().has_errors()
     }
+    pub fn has_errors_or_lint_errors(&self) -> bool {
+        self.inner.borrow().has_errors_or_lint_errors()
+    }
     pub fn has_errors_or_delayed_span_bugs(&self) -> bool {
         self.inner.borrow().has_errors_or_delayed_span_bugs()
     }
@@ -979,7 +994,11 @@ impl HandlerInner {
             }
         }
         if diagnostic.is_error() {
-            self.bump_err_count();
+            if matches!(diagnostic.level, Level::Error { lint: true }) {
+                self.bump_lint_err_count();
+            } else {
+                self.bump_err_count();
+            }
         } else {
             self.bump_warn_count();
         }
@@ -1073,11 +1092,14 @@ impl HandlerInner {
     fn has_errors(&self) -> bool {
         self.err_count() > 0
     }
+    fn has_errors_or_lint_errors(&self) -> bool {
+        self.has_errors() || self.lint_err_count > 0
+    }
     fn has_errors_or_delayed_span_bugs(&self) -> bool {
         self.has_errors() || !self.delayed_span_bugs.is_empty()
     }
     fn has_any_message(&self) -> bool {
-        self.err_count() > 0 || self.warn_count > 0
+        self.err_count() > 0 || self.lint_err_count > 0 || self.warn_count > 0
     }
 
     fn abort_if_errors(&mut self) {
@@ -1131,7 +1153,7 @@ impl HandlerInner {
     }
 
     fn err(&mut self, msg: &str) {
-        self.emit_error(Error, msg);
+        self.emit_error(Error { lint: false }, msg);
     }
 
     /// Emit an error; level should be `Error` or `Fatal`.
@@ -1167,6 +1189,11 @@ impl HandlerInner {
         }
     }
 
+    fn bump_lint_err_count(&mut self) {
+        self.lint_err_count += 1;
+        self.panic_if_treat_err_as_bug();
+    }
+
     fn bump_err_count(&mut self) {
         self.err_count += 1;
         self.panic_if_treat_err_as_bug();
@@ -1210,7 +1237,10 @@ impl DelayedDiagnostic {
 pub enum Level {
     Bug,
     Fatal,
-    Error,
+    Error {
+        /// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called.
+        lint: bool,
+    },
     Warning,
     Note,
     Help,
@@ -1229,7 +1259,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | Fatal | Error => {
+            Bug | Fatal | Error { .. } => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
             Warning => {
@@ -1250,7 +1280,7 @@ impl Level {
     pub fn to_str(self) -> &'static str {
         match self {
             Bug => "error: internal compiler error",
-            Fatal | Error => "error",
+            Fatal | Error { .. } => "error",
             Warning => "warning",
             Note => "note",
             Help => "help",
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 521ca2135c6..4e84a9df6c9 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,7 +1,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(destructuring_assignment)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(if_let_guard)]
 #![feature(iter_zip)]
 #![feature(let_else)]
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 3f84979ac05..42c17a60a5d 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -24,8 +24,9 @@ impl base::ProcMacro for BangProcMacro {
         span: Span,
         input: TokenStream,
     ) -> Result<TokenStream, ErrorReported> {
+        let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
         let server = proc_macro_server::Rustc::new(ecx);
-        self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace).map_err(|e| {
+        self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
             let mut err = ecx.struct_span_err(span, "proc macro panicked");
             if let Some(s) = e.as_str() {
                 err.help(&format!("message: {}", s));
@@ -48,9 +49,10 @@ impl base::AttrProcMacro for AttrProcMacro {
         annotation: TokenStream,
         annotated: TokenStream,
     ) -> Result<TokenStream, ErrorReported> {
+        let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
         let server = proc_macro_server::Rustc::new(ecx);
         self.client
-            .run(&EXEC_STRATEGY, server, annotation, annotated, ecx.ecfg.proc_macro_backtrace)
+            .run(&EXEC_STRATEGY, server, annotation, annotated, proc_macro_backtrace)
             .map_err(|e| {
                 let mut err = ecx.struct_span_err(span, "custom attribute panicked");
                 if let Some(s) = e.as_str() {
@@ -97,19 +99,19 @@ impl MultiItemModifier for ProcMacroDerive {
             nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
         };
 
+        let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
         let server = proc_macro_server::Rustc::new(ecx);
-        let stream =
-            match self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace) {
-                Ok(stream) => stream,
-                Err(e) => {
-                    let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
-                    if let Some(s) = e.as_str() {
-                        err.help(&format!("message: {}", s));
-                    }
-                    err.emit();
-                    return ExpandResult::Ready(vec![]);
+        let stream = match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
+            Ok(stream) => stream,
+            Err(e) => {
+                let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
+                if let Some(s) = e.as_str() {
+                    err.help(&format!("message: {}", s));
                 }
-            };
+                err.emit();
+                return ExpandResult::Ready(vec![]);
+            }
+        };
 
         let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count();
         let mut parser =
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 5cb97198765..fa9e98be9e8 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -1,4 +1,4 @@
-use crate::base::{ExtCtxt, ResolverExpand};
+use crate::base::ExtCtxt;
 
 use rustc_ast as ast;
 use rustc_ast::token::{self, Nonterminal, NtIdent};
@@ -7,7 +7,7 @@ use rustc_ast::tokenstream::{DelimSpan, Spacing::*, TokenStream, TreeAndSpacing}
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::Diagnostic;
+use rustc_errors::{Diagnostic, PResult};
 use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
 use rustc_lint_defs::BuiltinLintDiagnostics;
 use rustc_parse::lexer::nfc_normalize;
@@ -53,11 +53,11 @@ impl ToInternal<token::DelimToken> for Delimiter {
     }
 }
 
-impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)>
+impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
     for TokenTree<Group, Punct, Ident, Literal>
 {
     fn from_internal(
-        ((tree, spacing), stack, rustc): (TreeAndSpacing, &mut Vec<Self>, &mut Rustc<'_>),
+        ((tree, spacing), stack, rustc): (TreeAndSpacing, &mut Vec<Self>, &mut Rustc<'_, '_>),
     ) -> Self {
         use rustc_ast::token::*;
 
@@ -146,10 +146,10 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)>
             SingleQuote => op!('\''),
 
             Ident(name, false) if name == kw::DollarCrate => tt!(Ident::dollar_crate()),
-            Ident(name, is_raw) => tt!(Ident::new(rustc.sess, name, is_raw)),
+            Ident(name, is_raw) => tt!(Ident::new(rustc.sess(), name, is_raw)),
             Lifetime(name) => {
                 let ident = symbol::Ident::new(name, span).without_first_quote();
-                stack.push(tt!(Ident::new(rustc.sess, ident.name, false)));
+                stack.push(tt!(Ident::new(rustc.sess(), ident.name, false)));
                 tt!(Punct::new('\'', true))
             }
             Literal(lit) => tt!(Literal { lit }),
@@ -181,15 +181,15 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)>
             Interpolated(nt)
                 if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) =>
             {
-                TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span))
+                TokenTree::Ident(Ident::new(rustc.sess(), name.name, is_raw, name.span))
             }
             Interpolated(nt) => {
-                let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No);
+                let stream = nt_to_tokenstream(&nt, rustc.sess(), CanSynthesizeMissingTokens::No);
                 TokenTree::Group(Group {
                     delimiter: Delimiter::None,
                     stream,
                     span: DelimSpan::from_single(span),
-                    flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess),
+                    flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess()),
                 })
             }
 
@@ -273,7 +273,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
 impl ToInternal<rustc_errors::Level> for Level {
     fn to_internal(self) -> rustc_errors::Level {
         match self {
-            Level::Error => rustc_errors::Level::Error,
+            Level::Error => rustc_errors::Level::Error { lint: false },
             Level::Warning => rustc_errors::Level::Warning,
             Level::Note => rustc_errors::Level::Note,
             Level::Help => rustc_errors::Level::Help,
@@ -355,38 +355,38 @@ pub struct Literal {
     span: Span,
 }
 
-pub(crate) struct Rustc<'a> {
-    resolver: &'a dyn ResolverExpand,
-    sess: &'a ParseSess,
+pub(crate) struct Rustc<'a, 'b> {
+    ecx: &'a mut ExtCtxt<'b>,
     def_site: Span,
     call_site: Span,
     mixed_site: Span,
-    span_debug: bool,
     krate: CrateNum,
     rebased_spans: FxHashMap<usize, Span>,
 }
 
-impl<'a> Rustc<'a> {
-    pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
-        let expn_data = cx.current_expansion.id.expn_data();
+impl<'a, 'b> Rustc<'a, 'b> {
+    pub fn new(ecx: &'a mut ExtCtxt<'b>) -> Self {
+        let expn_data = ecx.current_expansion.id.expn_data();
         Rustc {
-            resolver: cx.resolver,
-            sess: cx.parse_sess(),
-            def_site: cx.with_def_site_ctxt(expn_data.def_site),
-            call_site: cx.with_call_site_ctxt(expn_data.call_site),
-            mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site),
-            span_debug: cx.ecfg.span_debug,
+            def_site: ecx.with_def_site_ctxt(expn_data.def_site),
+            call_site: ecx.with_call_site_ctxt(expn_data.call_site),
+            mixed_site: ecx.with_mixed_site_ctxt(expn_data.call_site),
             krate: expn_data.macro_def_id.unwrap().krate,
             rebased_spans: FxHashMap::default(),
+            ecx,
         }
     }
 
+    fn sess(&self) -> &ParseSess {
+        self.ecx.parse_sess()
+    }
+
     fn lit(&mut self, kind: token::LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Literal {
         Literal { lit: token::Lit::new(kind, symbol, suffix), span: server::Span::call_site(self) }
     }
 }
 
-impl server::Types for Rustc<'_> {
+impl server::Types for Rustc<'_, '_> {
     type FreeFunctions = FreeFunctions;
     type TokenStream = TokenStream;
     type TokenStreamBuilder = tokenstream::TokenStreamBuilder;
@@ -401,17 +401,20 @@ impl server::Types for Rustc<'_> {
     type Span = Span;
 }
 
-impl server::FreeFunctions for Rustc<'_> {
+impl server::FreeFunctions for Rustc<'_, '_> {
     fn track_env_var(&mut self, var: &str, value: Option<&str>) {
-        self.sess.env_depinfo.borrow_mut().insert((Symbol::intern(var), value.map(Symbol::intern)));
+        self.sess()
+            .env_depinfo
+            .borrow_mut()
+            .insert((Symbol::intern(var), value.map(Symbol::intern)));
     }
 
     fn track_path(&mut self, path: &str) {
-        self.sess.file_depinfo.borrow_mut().insert(Symbol::intern(path));
+        self.sess().file_depinfo.borrow_mut().insert(Symbol::intern(path));
     }
 }
 
-impl server::TokenStream for Rustc<'_> {
+impl server::TokenStream for Rustc<'_, '_> {
     fn new(&mut self) -> Self::TokenStream {
         TokenStream::default()
     }
@@ -422,13 +425,62 @@ impl server::TokenStream for Rustc<'_> {
         parse_stream_from_source_str(
             FileName::proc_macro_source_code(src),
             src.to_string(),
-            self.sess,
+            self.sess(),
             Some(self.call_site),
         )
     }
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
         pprust::tts_to_string(stream)
     }
+    fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
+        // Parse the expression from our tokenstream.
+        let expr: PResult<'_, _> = try {
+            let mut p = rustc_parse::stream_to_parser(
+                self.sess(),
+                stream.clone(),
+                Some("proc_macro expand expr"),
+            );
+            let expr = p.parse_expr()?;
+            if p.token != token::Eof {
+                p.unexpected()?;
+            }
+            expr
+        };
+        let expr = expr.map_err(|mut err| err.emit())?;
+
+        // Perform eager expansion on the expression.
+        let expr = self
+            .ecx
+            .expander()
+            .fully_expand_fragment(crate::expand::AstFragment::Expr(expr))
+            .make_expr();
+
+        // NOTE: For now, limit `expand_expr` to exclusively expand to literals.
+        // This may be relaxed in the future.
+        // We don't use `nt_to_tokenstream` as the tokenstream currently cannot
+        // be recovered in the general case.
+        match &expr.kind {
+            ast::ExprKind::Lit(l) => {
+                Ok(tokenstream::TokenTree::token(token::Literal(l.token), l.span).into())
+            }
+            ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {
+                ast::ExprKind::Lit(l) => match l.token {
+                    token::Lit { kind: token::Integer | token::Float, .. } => {
+                        Ok(std::array::IntoIter::new([
+                            // FIXME: The span of the `-` token is lost when
+                            // parsing, so we cannot faithfully recover it here.
+                            tokenstream::TokenTree::token(token::BinOp(token::Minus), e.span),
+                            tokenstream::TokenTree::token(token::Literal(l.token), l.span),
+                        ])
+                        .collect())
+                    }
+                    _ => Err(()),
+                },
+                _ => Err(()),
+            },
+            _ => Err(()),
+        }
+    }
     fn from_token_tree(
         &mut self,
         tree: TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>,
@@ -440,7 +492,7 @@ impl server::TokenStream for Rustc<'_> {
     }
 }
 
-impl server::TokenStreamBuilder for Rustc<'_> {
+impl server::TokenStreamBuilder for Rustc<'_, '_> {
     fn new(&mut self) -> Self::TokenStreamBuilder {
         tokenstream::TokenStreamBuilder::new()
     }
@@ -452,7 +504,7 @@ impl server::TokenStreamBuilder for Rustc<'_> {
     }
 }
 
-impl server::TokenStreamIter for Rustc<'_> {
+impl server::TokenStreamIter for Rustc<'_, '_> {
     fn next(
         &mut self,
         iter: &mut Self::TokenStreamIter,
@@ -477,7 +529,7 @@ impl server::TokenStreamIter for Rustc<'_> {
     }
 }
 
-impl server::Group for Rustc<'_> {
+impl server::Group for Rustc<'_, '_> {
     fn new(&mut self, delimiter: Delimiter, stream: Self::TokenStream) -> Self::Group {
         Group {
             delimiter,
@@ -506,7 +558,7 @@ impl server::Group for Rustc<'_> {
     }
 }
 
-impl server::Punct for Rustc<'_> {
+impl server::Punct for Rustc<'_, '_> {
     fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
         Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self))
     }
@@ -524,9 +576,9 @@ impl server::Punct for Rustc<'_> {
     }
 }
 
-impl server::Ident for Rustc<'_> {
+impl server::Ident for Rustc<'_, '_> {
     fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
-        Ident::new(self.sess, Symbol::intern(string), is_raw, span)
+        Ident::new(self.sess(), Symbol::intern(string), is_raw, span)
     }
     fn span(&mut self, ident: Self::Ident) -> Self::Span {
         ident.span
@@ -536,10 +588,10 @@ impl server::Ident for Rustc<'_> {
     }
 }
 
-impl server::Literal for Rustc<'_> {
+impl server::Literal for Rustc<'_, '_> {
     fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
         let name = FileName::proc_macro_source_code(s);
-        let mut parser = rustc_parse::new_parser_from_source_str(self.sess, name, s.to_owned());
+        let mut parser = rustc_parse::new_parser_from_source_str(self.sess(), name, s.to_owned());
 
         let first_span = parser.token.span.data();
         let minus_present = parser.eat(&token::BinOp(token::Minus));
@@ -675,7 +727,7 @@ impl server::Literal for Rustc<'_> {
     }
 }
 
-impl server::SourceFile for Rustc<'_> {
+impl server::SourceFile for Rustc<'_, '_> {
     fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
         Lrc::ptr_eq(file1, file2)
     }
@@ -695,7 +747,7 @@ impl server::SourceFile for Rustc<'_> {
     }
 }
 
-impl server::MultiSpan for Rustc<'_> {
+impl server::MultiSpan for Rustc<'_, '_> {
     fn new(&mut self) -> Self::MultiSpan {
         vec![]
     }
@@ -704,7 +756,7 @@ impl server::MultiSpan for Rustc<'_> {
     }
 }
 
-impl server::Diagnostic for Rustc<'_> {
+impl server::Diagnostic for Rustc<'_, '_> {
     fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
         let mut diag = Diagnostic::new(level.to_internal(), msg);
         diag.set_span(MultiSpan::from_spans(spans));
@@ -720,13 +772,13 @@ impl server::Diagnostic for Rustc<'_> {
         diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
     }
     fn emit(&mut self, diag: Self::Diagnostic) {
-        self.sess.span_diagnostic.emit_diagnostic(&diag);
+        self.sess().span_diagnostic.emit_diagnostic(&diag);
     }
 }
 
-impl server::Span for Rustc<'_> {
+impl server::Span for Rustc<'_, '_> {
     fn debug(&mut self, span: Self::Span) -> String {
-        if self.span_debug {
+        if self.ecx.ecfg.span_debug {
             format!("{:?}", span)
         } else {
             format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0)
@@ -742,7 +794,7 @@ impl server::Span for Rustc<'_> {
         self.mixed_site
     }
     fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
-        self.sess.source_map().lookup_char_pos(span.lo()).file
+        self.sess().source_map().lookup_char_pos(span.lo()).file
     }
     fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
         span.parent_callsite()
@@ -751,11 +803,11 @@ impl server::Span for Rustc<'_> {
         span.source_callsite()
     }
     fn start(&mut self, span: Self::Span) -> LineColumn {
-        let loc = self.sess.source_map().lookup_char_pos(span.lo());
+        let loc = self.sess().source_map().lookup_char_pos(span.lo());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
     fn end(&mut self, span: Self::Span) -> LineColumn {
-        let loc = self.sess.source_map().lookup_char_pos(span.hi());
+        let loc = self.sess().source_map().lookup_char_pos(span.hi());
         LineColumn { line: loc.line, column: loc.col.to_usize() }
     }
     fn before(&mut self, span: Self::Span) -> Self::Span {
@@ -765,8 +817,8 @@ impl server::Span for Rustc<'_> {
         span.shrink_to_hi()
     }
     fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
-        let self_loc = self.sess.source_map().lookup_char_pos(first.lo());
-        let other_loc = self.sess.source_map().lookup_char_pos(second.lo());
+        let self_loc = self.sess().source_map().lookup_char_pos(first.lo());
+        let other_loc = self.sess().source_map().lookup_char_pos(second.lo());
 
         if self_loc.file.name != other_loc.file.name {
             return None;
@@ -778,7 +830,7 @@ impl server::Span for Rustc<'_> {
         span.with_ctxt(at.ctxt())
     }
     fn source_text(&mut self, span: Self::Span) -> Option<String> {
-        self.sess.source_map().span_to_snippet(span).ok()
+        self.sess().source_map().span_to_snippet(span).ok()
     }
     /// Saves the provided span into the metadata of
     /// *the crate we are currently compiling*, which must
@@ -805,10 +857,10 @@ impl server::Span for Rustc<'_> {
     /// since we've loaded `my_proc_macro` from disk in order to execute it).
     /// In this way, we have obtained a span pointing into `my_proc_macro`
     fn save_span(&mut self, span: Self::Span) -> usize {
-        self.sess.save_proc_macro_span(span)
+        self.sess().save_proc_macro_span(span)
     }
     fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
-        let (resolver, krate, def_site) = (self.resolver, self.krate, self.def_site);
+        let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site);
         *self.rebased_spans.entry(id).or_insert_with(|| {
             // FIXME: `SyntaxContext` for spans from proc macro crates is lost during encoding,
             // replace it with a def-site context until we are encoding it properly.
@@ -821,11 +873,11 @@ impl server::Span for Rustc<'_> {
 fn ident_name_compatibility_hack(
     nt: &Nonterminal,
     orig_span: Span,
-    rustc: &mut Rustc<'_>,
+    rustc: &mut Rustc<'_, '_>,
 ) -> Option<(rustc_span::symbol::Ident, bool)> {
     if let NtIdent(ident, is_raw) = nt {
         if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
-            let source_map = rustc.sess.source_map();
+            let source_map = rustc.sess().source_map();
             let filename = source_map.span_to_filename(orig_span);
             if let FileName::Real(RealFileName::LocalPath(path)) = filename {
                 let matches_prefix = |prefix, filename| {
@@ -846,7 +898,7 @@ fn ident_name_compatibility_hack(
                     let snippet = source_map.span_to_snippet(orig_span);
                     if snippet.as_deref() == Ok("$name") {
                         if time_macros_impl {
-                            rustc.sess.buffer_lint_with_diagnostic(
+                            rustc.sess().buffer_lint_with_diagnostic(
                                 &PROC_MACRO_BACK_COMPAT,
                                 orig_span,
                                 ast::CRATE_NODE_ID,
@@ -871,7 +923,7 @@ fn ident_name_compatibility_hack(
                                         .and_then(|c| c.parse::<u32>().ok())
                                         .map_or(false, |v| v < 40)
                                 {
-                                    rustc.sess.buffer_lint_with_diagnostic(
+                                    rustc.sess().buffer_lint_with_diagnostic(
                                         &PROC_MACRO_BACK_COMPAT,
                                         orig_span,
                                         ast::CRATE_NODE_ID,
@@ -894,7 +946,7 @@ fn ident_name_compatibility_hack(
                             source_map.span_to_filename(rustc.def_site)
                         {
                             if macro_path.to_string_lossy().contains("pin-project-internal-0.") {
-                                rustc.sess.buffer_lint_with_diagnostic(
+                                rustc.sess().buffer_lint_with_diagnostic(
                                     &PROC_MACRO_BACK_COMPAT,
                                     orig_span,
                                     ast::CRATE_NODE_ID,
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 941d957103c..6950fae898f 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -34,6 +34,9 @@ declare_features! (
     /// These are used to test this portion of the compiler,
     /// they don't actually mean anything.
     (accepted, test_accepted_feature, "1.0.0", None, None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: for testing purposes
@@ -43,262 +46,269 @@ declare_features! (
     // feature-group-start: accepted features
     // -------------------------------------------------------------------------
 
+    /// Allows the sysV64 ABI to be specified on all platforms
+    /// instead of just the platforms on which it is the C ABI.
+    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
+    /// Allows the definition of associated constants in `trait` or `impl` blocks.
+    (accepted, associated_consts, "1.20.0", Some(29646), None),
     /// Allows using associated `type`s in `trait`s.
     (accepted, associated_types, "1.0.0", None, None),
-    /// Allows using assigning a default type to type parameters in algebraic data type definitions.
-    (accepted, default_type_params, "1.0.0", None, None),
-    // FIXME: explain `globs`.
-    (accepted, globs, "1.0.0", None, None),
-    /// Allows `macro_rules!` items.
-    (accepted, macro_rules, "1.0.0", None, None),
-    /// Allows use of `&foo[a..b]` as a slicing syntax.
-    (accepted, slicing_syntax, "1.0.0", None, None),
-    /// Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
-    (accepted, struct_variant, "1.0.0", None, None),
-    /// Allows indexing tuples.
-    (accepted, tuple_indexing, "1.0.0", None, None),
-    /// Allows the use of `if let` expressions.
-    (accepted, if_let, "1.0.0", None, None),
-    /// Allows the use of `while let` expressions.
-    (accepted, while_let, "1.0.0", None, None),
-    /// Allows using `#![no_std]`.
-    (accepted, no_std, "1.6.0", None, None),
+    /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
+    (accepted, async_await, "1.39.0", Some(50547), None),
+    /// Allows all literals in attribute lists and values of key-value pairs.
+    (accepted, attr_literals, "1.30.0", Some(34981), None),
     /// Allows overloading augmented assignment operations like `a += b`.
     (accepted, augmented_assignments, "1.8.0", Some(28235), None),
+    /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
+    (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
+    /// Allows bindings in the subpattern of a binding pattern.
+    /// For example, you can write `x @ Some(y)`.
+    (accepted, bindings_after_at, "1.56.0", Some(65490), None),
     /// Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
-    /// Allows `#[deprecated]` attribute.
-    (accepted, deprecated, "1.9.0", Some(29935), None),
-    /// Allows macros to appear in the type position.
-    (accepted, type_macros, "1.13.0", Some(27245), None),
-    /// Allows use of the postfix `?` operator in expressions.
-    (accepted, question_mark, "1.13.0", Some(31436), None),
-    /// Allows `..` in tuple (struct) patterns.
-    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
-    /// Allows some increased flexibility in the name resolution rules,
-    /// especially around globs and shadowing (RFC 1560).
-    (accepted, item_like_imports, "1.15.0", Some(35120), None),
-    /// Allows using `Self` and associated types in struct expressions and patterns.
-    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
-    /// Allows elision of `'static` lifetimes in `static`s and `const`s.
-    (accepted, static_in_const, "1.17.0", Some(35897), None),
-    /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
-    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
-    /// Allows the definition recursive static items.
-    (accepted, static_recursion, "1.17.0", Some(29719), None),
-    /// Allows `pub(restricted)` visibilities (RFC 1422).
-    (accepted, pub_restricted, "1.18.0", Some(32409), None),
-    /// Allows `#![windows_subsystem]`.
-    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
-    /// Allows `break {expr}` with a value inside `loop`s.
-    (accepted, loop_break_value, "1.19.0", Some(37339), None),
-    /// Allows numeric fields in struct expressions and patterns.
-    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
+    /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
+    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
+    /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
+    (accepted, cfg_doctest, "1.40.0", Some(62210), None),
+    /// Allows `cfg(target_feature = "...")`.
+    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
+    /// Allows `cfg(target_vendor = "...")`.
+    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
+    /// Allows implementing `Clone` for closures where possible (RFC 2132).
+    (accepted, clone_closures, "1.26.0", Some(44490), None),
     /// Allows coercing non capturing closures to function pointers.
     (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
-    /// Allows attributes on struct literal fields.
-    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
-    /// Allows the definition of associated constants in `trait` or `impl` blocks.
-    (accepted, associated_consts, "1.20.0", Some(29646), None),
     /// Allows usage of the `compile_error!` macro.
     (accepted, compile_error, "1.20.0", Some(40872), None),
-    /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
-    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
-    /// Allows `Drop` types in constants (RFC 1440).
-    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
-    /// Allows the sysV64 ABI to be specified on all platforms
-    /// instead of just the platforms on which it is the C ABI.
-    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
-    /// Allows `repr(align(16))` struct attribute (RFC 1358).
-    (accepted, repr_align, "1.25.0", Some(33626), None),
-    /// Allows '|' at beginning of match arms (RFC 1925).
-    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
-    /// Allows nested groups in `use` items (RFC 2128).
-    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
+    /// Allows `impl Trait` in function return types.
+    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
+    /// Allows calling constructor functions in `const fn`.
+    (accepted, const_constructor, "1.40.0", Some(61456), None),
+    /// Allows calling `transmute` in const fn
+    (accepted, const_fn_transmute, "1.56.0", Some(53605), None),
+    /// Allows accessing fields of unions inside `const` functions.
+    (accepted, const_fn_union, "1.56.0", Some(51909), None),
+    /// Allows unsizing coercions in `const fn`.
+    (accepted, const_fn_unsize, "1.54.0", Some(64992), None),
+    /// Allows the use of `if` and `match` in constants.
+    (accepted, const_if_match, "1.46.0", Some(49146), None),
     /// Allows indexing into constant arrays.
     (accepted, const_indexing, "1.26.0", Some(29947), None),
-    /// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
-    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
-    /// Allows `..=` in patterns (RFC 1192).
-    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
-    /// Allows `fn main()` with return types which implements `Termination` (RFC 1937).
-    (accepted, termination_trait, "1.26.0", Some(43301), None),
-    /// Allows implementing `Clone` for closures where possible (RFC 2132).
-    (accepted, clone_closures, "1.26.0", Some(44490), None),
+    /// Allows let bindings, assignments and destructuring in `const` functions and constants.
+    /// As long as control flow is not implemented in const eval, `&&` and `||` may not be used
+    /// at the same time as let bindings.
+    (accepted, const_let, "1.33.0", Some(48821), None),
+    /// Allows the use of `loop` and `while` in constants.
+    (accepted, const_loop, "1.46.0", Some(52000), None),
+    /// Allows panicking during const eval (producing compile-time errors).
+    (accepted, const_panic, "1.57.0", Some(51999), None),
+    /// Allows dereferencing raw pointers during const eval.
+    (accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None),
     /// Allows implementing `Copy` for closures where possible (RFC 2132).
     (accepted, copy_closures, "1.26.0", Some(44490), None),
-    /// Allows `impl Trait` in function arguments.
-    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
-    /// Allows `impl Trait` in function return types.
-    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
-    /// Allows using the `u128` and `i128` types.
-    (accepted, i128_type, "1.26.0", Some(35118), None),
-    /// Allows default match binding modes (RFC 2005).
-    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
-    /// Allows `'_` placeholder lifetimes.
-    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
-    /// Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
-    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
-    /// Allows `cfg(target_feature = "...")`.
-    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
-    /// Allows `#[target_feature(...)]`.
-    (accepted, target_feature, "1.27.0", None, None),
-    /// Allows using `dyn Trait` as a syntax for trait objects.
-    (accepted, dyn_trait, "1.27.0", Some(44662), None),
-    /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
-    (accepted, fn_must_use, "1.27.0", Some(43302), None),
-    /// Allows use of the `:lifetime` macro fragment specifier.
-    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
-    /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
-    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
-    /// Allows the `#[global_allocator]` attribute.
-    (accepted, global_allocator, "1.28.0", Some(27389), None),
-    /// Allows `#[repr(transparent)]` attribute on newtype structs.
-    (accepted, repr_transparent, "1.28.0", Some(43036), None),
-    /// Allows procedural macros in `proc-macro` crates.
-    (accepted, proc_macro, "1.29.0", Some(38356), None),
-    /// Allows `foo.rs` as an alternative to `foo/mod.rs`.
-    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
-    /// Allows use of the `:vis` macro fragment specifier
-    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
-    /// Allows importing and reexporting macros with `use`,
-    /// enables macro modularization in general.
-    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
-    /// Allows keywords to be escaped for use as identifiers.
-    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
-    /// Allows attributes scoped to tools.
-    (accepted, tool_attributes, "1.30.0", Some(44690), None),
-    /// Allows multi-segment paths in attributes and derives.
-    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
-    /// Allows all literals in attribute lists and values of key-value pairs.
-    (accepted, attr_literals, "1.30.0", Some(34981), None),
-    /// Allows inferring outlives requirements (RFC 2093).
-    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
-    /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
-    /// This defines the behavior of panics.
-    (accepted, panic_handler, "1.30.0", Some(44489), None),
-    /// Allows `#[used]` to preserve symbols (see llvm.compiler.used).
-    (accepted, used, "1.30.0", Some(40289), None),
     /// Allows `crate` in paths.
     (accepted, crate_in_paths, "1.30.0", Some(45477), None),
+    /// Allows using assigning a default type to type parameters in algebraic data type definitions.
+    (accepted, default_type_params, "1.0.0", None, None),
+    /// Allows `#[deprecated]` attribute.
+    (accepted, deprecated, "1.9.0", Some(29935), None),
+    /// Allows `#[doc(alias = "...")]`.
+    (accepted, doc_alias, "1.48.0", Some(50146), None),
+    /// Allows `..` in tuple (struct) patterns.
+    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
+    /// Allows `..=` in patterns (RFC 1192).
+    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
+    /// Allows `Drop` types in constants (RFC 1440).
+    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
+    /// Allows using `dyn Trait` as a syntax for trait objects.
+    (accepted, dyn_trait, "1.27.0", Some(44662), None),
+    /// Allows integer match exhaustiveness checking (RFC 2591).
+    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
+    /// Allows arbitrary expressions in key-value attributes at parse time.
+    (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
     /// Allows resolving absolute paths as paths from other crates.
     (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
+    /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
+    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
+    /// Allows `extern crate self as foo;`.
+    /// This puts local crate root into extern prelude under name `foo`.
+    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
     /// Allows access to crate names passed via `--extern` through prelude.
     (accepted, extern_prelude, "1.30.0", Some(44660), None),
-    /// Allows parentheses in patterns.
-    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
-    /// Allows the definition of `const fn` functions.
-    (accepted, min_const_fn, "1.31.0", Some(53555), None),
-    /// Allows scoped lints.
-    (accepted, tool_lints, "1.31.0", Some(44690), None),
+    /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
+    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
+    /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
+    (accepted, fn_must_use, "1.27.0", Some(43302), None),
+    /// Allows capturing variables in scope using format_args!
+    (accepted, format_args_capture, "1.58.0", Some(67984), None),
+    /// Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
+    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
+    /// Allows the `#[global_allocator]` attribute.
+    (accepted, global_allocator, "1.28.0", Some(27389), None),
+    // FIXME: explain `globs`.
+    (accepted, globs, "1.0.0", None, None),
+    /// Allows using the `u128` and `i128` types.
+    (accepted, i128_type, "1.26.0", Some(35118), None),
+    /// Allows the use of `if let` expressions.
+    (accepted, if_let, "1.0.0", None, None),
+    /// Allows top level or-patterns (`p | q`) in `if let` and `while let`.
+    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
     /// Allows lifetime elision in `impl` headers. For example:
     /// + `impl<I:Iterator> Iterator for &mut Iterator`
     /// + `impl Debug for Foo<'_>`
     (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
-    /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
-    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
-    /// Allows use of the `:literal` macro fragment specifier (RFC 1576).
-    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
-    /// Allows use of `?` as the Kleene "at most one" operator in macros.
-    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
-    /// Allows `Self` struct constructor (RFC 2302).
-    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
-    /// Allows `Self` in type definitions (RFC 2300).
-    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
-    /// Allows `use x::y;` to search `x` in the current scope.
-    (accepted, uniform_paths, "1.32.0", Some(53130), None),
-    /// Allows integer match exhaustiveness checking (RFC 2591).
-    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
-    /// Allows `use path as _;` and `extern crate c as _;`.
-    (accepted, underscore_imports, "1.33.0", Some(48216), None),
-    /// Allows `#[repr(packed(N))]` attribute on structs.
-    (accepted, repr_packed, "1.33.0", Some(33158), None),
+    /// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
+    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
+    /// Allows inferring outlives requirements (RFC 2093).
+    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
     /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
     (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
-    /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
-    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
-    /// Allows let bindings, assignments and destructuring in `const` functions and constants.
-    /// As long as control flow is not implemented in const eval, `&&` and `||` may not be used
-    /// at the same time as let bindings.
-    (accepted, const_let, "1.33.0", Some(48821), None),
-    /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
-    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
-    /// Allows top level or-patterns (`p | q`) in `if let` and `while let`.
-    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
-    /// Allows `cfg(target_vendor = "...")`.
-    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
-    /// Allows `extern crate self as foo;`.
-    /// This puts local crate root into extern prelude under name `foo`.
-    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
-    /// Allows arbitrary delimited token streams in non-macro attributes.
-    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
-    /// Allows paths to enum variants on type aliases including `Self`.
-    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
-    /// Allows using `#[repr(align(X))]` on enums with equivalent semantics
-    /// to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
-    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
-    /// Allows `const _: TYPE = VALUE`.
-    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
-    /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
-    (accepted, async_await, "1.39.0", Some(50547), None),
-    /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
-    (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
-    /// Allows attributes in formal function parameters.
-    (accepted, param_attrs, "1.39.0", Some(60406), None),
+    /// Allows some increased flexibility in the name resolution rules,
+    /// especially around globs and shadowing (RFC 1560).
+    (accepted, item_like_imports, "1.15.0", Some(35120), None),
+    /// Allows `break {expr}` with a value inside `loop`s.
+    (accepted, loop_break_value, "1.19.0", Some(37339), None),
+    /// Allows use of `?` as the Kleene "at most one" operator in macros.
+    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
+    /// Allows macro attributes to observe output of `#[derive]`.
+    (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None),
+    /// Allows use of the `:lifetime` macro fragment specifier.
+    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
+    /// Allows use of the `:literal` macro fragment specifier (RFC 1576).
+    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
+    /// Allows `macro_rules!` items.
+    (accepted, macro_rules, "1.0.0", None, None),
+    /// Allows use of the `:vis` macro fragment specifier
+    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
     /// Allows macro invocations in `extern {}` blocks.
     (accepted, macros_in_extern, "1.40.0", Some(49476), None),
+    /// Allows '|' at beginning of match arms (RFC 1925).
+    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
+    /// Allows default match binding modes (RFC 2005).
+    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
+    /// Allows `impl Trait` with multiple unrelated lifetimes.
+    (accepted, member_constraints, "1.54.0", Some(61997), None),
+    /// Allows the definition of `const fn` functions.
+    (accepted, min_const_fn, "1.31.0", Some(53555), None),
+    /// The smallest useful subset of const generics.
+    (accepted, min_const_generics, "1.51.0", Some(74878), None),
+    /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
+    /// Allows using `Self` and associated types in struct expressions and patterns.
+    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
+    /// Allows patterns with concurrent by-move and by-ref bindings.
+    /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
+    (accepted, move_ref_pattern, "1.49.0", Some(68354), None),
+    /// Allows using `#![no_std]`.
+    (accepted, no_std, "1.6.0", None, None),
+    /// Allows defining identifiers beyond ASCII.
+    (accepted, non_ascii_idents, "1.53.0", Some(55467), None),
     /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
     (accepted, non_exhaustive, "1.40.0", Some(44109), None),
-    /// Allows calling constructor functions in `const fn`.
-    (accepted, const_constructor, "1.40.0", Some(61456), None),
-    /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
-    (accepted, cfg_doctest, "1.40.0", Some(62210), None),
+    /// Allows `foo.rs` as an alternative to `foo/mod.rs`.
+    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
+    /// Allows the use of or-patterns (e.g., `0 | 1`).
+    (accepted, or_patterns, "1.53.0", Some(54883), None),
+    /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
+    /// This defines the behavior of panics.
+    (accepted, panic_handler, "1.30.0", Some(44489), None),
+    /// Allows attributes in formal function parameters.
+    (accepted, param_attrs, "1.39.0", Some(60406), None),
+    /// Allows parentheses in patterns.
+    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
+    /// Allows procedural macros in `proc-macro` crates.
+    (accepted, proc_macro, "1.29.0", Some(38356), None),
+    /// Allows multi-segment paths in attributes and derives.
+    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
+    /// Allows `pub(restricted)` visibilities (RFC 1422).
+    (accepted, pub_restricted, "1.18.0", Some(32409), None),
+    /// Allows use of the postfix `?` operator in expressions.
+    (accepted, question_mark, "1.13.0", Some(31436), None),
+    /// Allows keywords to be escaped for use as identifiers.
+    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
     /// Allows relaxing the coherence rules such that
     /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
     (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
-    /// Allows #[repr(transparent)] on univariant enums (RFC 2645).
-    (accepted, transparent_enums, "1.42.0", Some(60405), None),
+    /// Allows numeric fields in struct expressions and patterns.
+    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
+    /// Lessens the requirements for structs to implement `Unsize`.
+    (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
+    /// Allows `repr(align(16))` struct attribute (RFC 1358).
+    (accepted, repr_align, "1.25.0", Some(33626), None),
+    /// Allows using `#[repr(align(X))]` on enums with equivalent semantics
+    /// to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
+    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
+    /// Allows `#[repr(packed(N))]` attribute on structs.
+    (accepted, repr_packed, "1.33.0", Some(33158), None),
+    /// Allows `#[repr(transparent)]` attribute on newtype structs.
+    (accepted, repr_transparent, "1.28.0", Some(43036), None),
+    /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
+    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
+    /// Allows `Self` in type definitions (RFC 2300).
+    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
+    /// Allows `Self` struct constructor (RFC 2302).
+    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
     /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
     (accepted, slice_patterns, "1.42.0", Some(62254), None),
-    /// Allows the use of `if` and `match` in constants.
-    (accepted, const_if_match, "1.46.0", Some(49146), None),
-    /// Allows the use of `loop` and `while` in constants.
-    (accepted, const_loop, "1.46.0", Some(52000), None),
+    /// Allows use of `&foo[a..b]` as a slicing syntax.
+    (accepted, slicing_syntax, "1.0.0", None, None),
+    /// Allows elision of `'static` lifetimes in `static`s and `const`s.
+    (accepted, static_in_const, "1.17.0", Some(35897), None),
+    /// Allows the definition recursive static items.
+    (accepted, static_recursion, "1.17.0", Some(29719), None),
+    /// Allows attributes on struct literal fields.
+    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
+    /// Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
+    (accepted, struct_variant, "1.0.0", None, None),
+    /// Allows `#[target_feature(...)]`.
+    (accepted, target_feature, "1.27.0", None, None),
+    /// Allows `fn main()` with return types which implements `Termination` (RFC 1937).
+    (accepted, termination_trait, "1.26.0", Some(43301), None),
+    /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
+    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
+    /// Allows attributes scoped to tools.
+    (accepted, tool_attributes, "1.30.0", Some(44690), None),
+    /// Allows scoped lints.
+    (accepted, tool_lints, "1.31.0", Some(44690), None),
     /// Allows `#[track_caller]` to be used which provides
     /// accurate caller location reporting during panic (RFC 2091).
     (accepted, track_caller, "1.46.0", Some(47809), None),
-    /// Allows `#[doc(alias = "...")]`.
-    (accepted, doc_alias, "1.48.0", Some(50146), None),
-    /// Allows patterns with concurrent by-move and by-ref bindings.
-    /// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
-    (accepted, move_ref_pattern, "1.49.0", Some(68354), None),
-    /// The smallest useful subset of const generics.
-    (accepted, min_const_generics, "1.51.0", Some(74878), None),
+    /// Allows #[repr(transparent)] on univariant enums (RFC 2645).
+    (accepted, transparent_enums, "1.42.0", Some(60405), None),
+    /// Allows indexing tuples.
+    (accepted, tuple_indexing, "1.0.0", None, None),
+    /// Allows paths to enum variants on type aliases including `Self`.
+    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
+    /// Allows macros to appear in the type position.
+    (accepted, type_macros, "1.13.0", Some(27245), None),
+    /// Allows `const _: TYPE = VALUE`.
+    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
+    /// Allows `use path as _;` and `extern crate c as _;`.
+    (accepted, underscore_imports, "1.33.0", Some(48216), None),
+    /// Allows `'_` placeholder lifetimes.
+    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
+    /// Allows `use x::y;` to search `x` in the current scope.
+    (accepted, uniform_paths, "1.32.0", Some(53130), None),
+    /// Allows `impl Trait` in function arguments.
+    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
+    /// Allows arbitrary delimited token streams in non-macro attributes.
+    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
     /// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
     (accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668), None),
-    /// Allows the use of or-patterns (e.g., `0 | 1`).
-    (accepted, or_patterns, "1.53.0", Some(54883), None),
-    /// Allows defining identifiers beyond ASCII.
-    (accepted, non_ascii_idents, "1.53.0", Some(55467), None),
-    /// Allows arbitrary expressions in key-value attributes at parse time.
-    (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
-    /// Allows unsizing coercions in `const fn`.
-    (accepted, const_fn_unsize, "1.54.0", Some(64992), None),
-    /// Allows `impl Trait` with multiple unrelated lifetimes.
-    (accepted, member_constraints, "1.54.0", Some(61997), None),
-    /// Allows bindings in the subpattern of a binding pattern.
-    /// For example, you can write `x @ Some(y)`.
-    (accepted, bindings_after_at, "1.56.0", Some(65490), None),
-    /// Allows calling `transmute` in const fn
-    (accepted, const_fn_transmute, "1.56.0", Some(53605), None),
-    /// Allows accessing fields of unions inside `const` functions.
-    (accepted, const_fn_union, "1.56.0", Some(51909), None),
-    /// Allows macro attributes to observe output of `#[derive]`.
-    (accepted, macro_attributes_in_derive_output, "1.57.0", Some(81119), None),
-    /// Allows panicking during const eval (producing compile-time errors).
-    (accepted, const_panic, "1.57.0", Some(51999), None),
-    /// Lessens the requirements for structs to implement `Unsize`.
-    (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
+    /// Allows importing and reexporting macros with `use`,
+    /// enables macro modularization in general.
+    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
+    /// Allows nested groups in `use` items (RFC 2128).
+    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
+    /// Allows `#[used]` to preserve symbols (see llvm.compiler.used).
+    (accepted, used, "1.30.0", Some(40289), None),
+    /// Allows the use of `while let` expressions.
+    (accepted, while_let, "1.0.0", None, None),
+    /// Allows `#![windows_subsystem]`.
+    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 0266b7844ba..608581306be 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -122,130 +122,101 @@ impl Feature {
 #[rustfmt::skip]
 declare_features! (
     // -------------------------------------------------------------------------
-    // feature-group-start: internal feature gates
+    // feature-group-start: internal feature gates (no tracking issue)
     // -------------------------------------------------------------------------
-
     // no-tracking-issue-start
 
-    /// Allows using `rustc_*` attributes (RFC 572).
-    (active, rustc_attrs, "1.0.0", None, None),
-
-    /// Allows using compiler's own crates.
-    (active, rustc_private, "1.0.0", Some(27812), None),
-
-    /// Allows using the `rust-intrinsic`'s "ABI".
-    (active, intrinsics, "1.0.0", None, None),
-
-    /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
-    (active, lang_items, "1.0.0", None, None),
-
-    /// Allows using the `#[stable]` and `#[unstable]` attributes.
-    (active, staged_api, "1.0.0", None, None),
-
-    /// Allows using `#[allow_internal_unstable]`. This is an
+    /// Allows using the `thiscall` ABI.
+    (active, abi_thiscall, "1.19.0", None, None),
+    /// Allows using the `unadjusted` ABI; perma-unstable.
+    (active, abi_unadjusted, "1.16.0", None, None),
+    /// Allows using the `vectorcall` ABI.
+    (active, abi_vectorcall, "1.7.0", None, None),
+    /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
+    (active, allocator_internals, "1.20.0", None, None),
+    /// Allows using `#[allow_internal_unsafe]`. This is an
     /// attribute on `macro_rules!` and can't use the attribute handling
     /// below (it has to be checked before expansion possibly makes
     /// macros disappear).
-    (active, allow_internal_unstable, "1.0.0", None, None),
-
-    /// Allows using `#[allow_internal_unsafe]`. This is an
+    (active, allow_internal_unsafe, "1.0.0", None, None),
+    /// Allows using `#[allow_internal_unstable]`. This is an
     /// attribute on `macro_rules!` and can't use the attribute handling
     /// below (it has to be checked before expansion possibly makes
     /// macros disappear).
-    (active, allow_internal_unsafe, "1.0.0", None, None),
-
-    /// no-tracking-issue-end
-
-    /// Allows using `#[link_name="llvm.*"]`.
-    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
-
-    /// Allows using the `box $expr` syntax.
-    (active, box_syntax, "1.0.0", Some(49733), None),
-
-    /// Allows using `#[start]` on a function indicating that it is the program entrypoint.
-    (active, start, "1.0.0", Some(29633), None),
-
-    /// Allows using the `#[fundamental]` attribute.
-    (active, fundamental, "1.0.0", Some(29635), None),
-
-    /// Allows using the `rust-call` ABI.
-    (active, unboxed_closures, "1.0.0", Some(29625), None),
-
-    /// Allows using the `#[linkage = ".."]` attribute.
-    (active, linkage, "1.0.0", Some(29603), None),
-
-    /// Allows using `box` in patterns (RFC 469).
-    (active, box_patterns, "1.0.0", Some(29641), None),
-
-    // no-tracking-issue-start
-
-    /// Allows using `#[prelude_import]` on glob `use` items.
-    (active, prelude_import, "1.2.0", None, None),
-
-    // no-tracking-issue-end
-
-    // no-tracking-issue-start
-
-    /// Allows using `#[omit_gdb_pretty_printer_section]`.
-    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
-
-    /// Allows using the `vectorcall` ABI.
-    (active, abi_vectorcall, "1.7.0", None, None),
-
-    // no-tracking-issue-end
-
-    /// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
-    /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
-    /// feature with the same name exists.
-    (active, structural_match, "1.8.0", Some(31434), None),
-
-    /// Allows using the `may_dangle` attribute (RFC 1327).
-    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
-
-    /// Allows using the `#![panic_runtime]` attribute.
-    (active, panic_runtime, "1.10.0", Some(32837), None),
-
-    /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
-    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
-
-    // no-tracking-issue-start
-
+    (active, allow_internal_unstable, "1.0.0", None, None),
     /// Allows identifying the `compiler_builtins` crate.
     (active, compiler_builtins, "1.13.0", None, None),
-
-    /// Allows using the `unadjusted` ABI; perma-unstable.
-    (active, abi_unadjusted, "1.16.0", None, None),
-
+    /// Allows using the `rust-intrinsic`'s "ABI".
+    (active, intrinsics, "1.0.0", None, None),
+    /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
+    (active, lang_items, "1.0.0", None, None),
+    /// Allows `#[repr(no_niche)]` (an implementation detail of `rustc`,
+    /// it is not on path for eventual stabilization).
+    (active, no_niche, "1.42.0", None, None),
+    /// Allows using `#[omit_gdb_pretty_printer_section]`.
+    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
+    /// Allows using `#[prelude_import]` on glob `use` items.
+    (active, prelude_import, "1.2.0", None, None),
     /// Used to identify crates that contain the profiler runtime.
     (active, profiler_runtime, "1.18.0", None, None),
-
-    /// Allows using the `thiscall` ABI.
-    (active, abi_thiscall, "1.19.0", None, None),
-
-    /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
-    (active, allocator_internals, "1.20.0", None, None),
-
+    /// Allows using `rustc_*` attributes (RFC 572).
+    (active, rustc_attrs, "1.0.0", None, None),
+    /// Allows using the `#[stable]` and `#[unstable]` attributes.
+    (active, staged_api, "1.0.0", None, None),
     /// Added for testing E0705; perma-unstable.
     (active, test_2018_feature, "1.31.0", None, Some(Edition::Edition2018)),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
-    /// Allows `#[repr(no_niche)]` (an implementation detail of `rustc`,
-    /// it is not on path for eventual stabilization).
-    (active, no_niche, "1.42.0", None, None),
+    // no-tracking-issue-end
+    // -------------------------------------------------------------------------
+    // feature-group-end: internal feature gates (no tracking issue)
+    // -------------------------------------------------------------------------
 
-    /// Allows using `#[rustc_allow_const_fn_unstable]`.
-    /// This is an attribute on `const fn` for the same
-    /// purpose as `#[allow_internal_unstable]`.
-    (active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),
+    // -------------------------------------------------------------------------
+    // feature-group-start: internal feature gates
+    // -------------------------------------------------------------------------
 
     /// Allows features specific to auto traits.
     /// Renamed from `optin_builtin_traits`.
     (active, auto_traits, "1.50.0", Some(13231), None),
-
+    /// Allows using `box` in patterns (RFC 469).
+    (active, box_patterns, "1.0.0", Some(29641), None),
+    /// Allows using the `box $expr` syntax.
+    (active, box_syntax, "1.0.0", Some(49733), None),
     /// Allows `#[doc(notable_trait)]`.
     /// Renamed from `doc_spotlight`.
     (active, doc_notable_trait, "1.52.0", Some(45040), None),
-
-    // no-tracking-issue-end
+    /// Allows using the `may_dangle` attribute (RFC 1327).
+    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
+    /// Allows using the `#[fundamental]` attribute.
+    (active, fundamental, "1.0.0", Some(29635), None),
+    /// Allows using `#[link_name="llvm.*"]`.
+    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
+    /// Allows using the `#[linkage = ".."]` attribute.
+    (active, linkage, "1.0.0", Some(29603), None),
+    /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
+    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
+    /// Allows using the `#![panic_runtime]` attribute.
+    (active, panic_runtime, "1.10.0", Some(32837), None),
+    /// Allows using `#[rustc_allow_const_fn_unstable]`.
+    /// This is an attribute on `const fn` for the same
+    /// purpose as `#[allow_internal_unstable]`.
+    (active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),
+    /// Allows using compiler's own crates.
+    (active, rustc_private, "1.0.0", Some(27812), None),
+    /// Allows using `#[start]` on a function indicating that it is the program entrypoint.
+    (active, start, "1.0.0", Some(29633), None),
+    /// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
+    /// FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library
+    /// feature with the same name exists.
+    (active, structural_match, "1.8.0", Some(31434), None),
+    /// Allows using the `rust-call` ABI.
+    (active, unboxed_closures, "1.0.0", Some(29625), None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: internal feature gates
@@ -258,23 +229,26 @@ declare_features! (
     // FIXME: Document these and merge with the list below.
 
     // Unstable `#[target_feature]` directives.
-    (active, arm_target_feature, "1.27.0", Some(44839), None),
     (active, aarch64_target_feature, "1.27.0", Some(44839), None),
+    (active, adx_target_feature, "1.32.0", Some(44839), None),
+    (active, arm_target_feature, "1.27.0", Some(44839), None),
+    (active, avx512_target_feature, "1.27.0", Some(44839), None),
+    (active, bpf_target_feature, "1.54.0", Some(44839), None),
+    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
+    (active, ermsb_target_feature, "1.49.0", Some(44839), None),
+    (active, f16c_target_feature, "1.36.0", Some(44839), None),
     (active, hexagon_target_feature, "1.27.0", Some(44839), None),
-    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
     (active, mips_target_feature, "1.27.0", Some(44839), None),
-    (active, avx512_target_feature, "1.27.0", Some(44839), None),
+    (active, movbe_target_feature, "1.34.0", Some(44839), None),
+    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
+    (active, riscv_target_feature, "1.45.0", Some(44839), None),
+    (active, rtm_target_feature, "1.35.0", Some(44839), None),
     (active, sse4a_target_feature, "1.27.0", Some(44839), None),
     (active, tbm_target_feature, "1.27.0", Some(44839), None),
     (active, wasm_target_feature, "1.30.0", Some(44839), None),
-    (active, adx_target_feature, "1.32.0", Some(44839), None),
-    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
-    (active, movbe_target_feature, "1.34.0", Some(44839), None),
-    (active, rtm_target_feature, "1.35.0", Some(44839), None),
-    (active, f16c_target_feature, "1.36.0", Some(44839), None),
-    (active, riscv_target_feature, "1.45.0", Some(44839), None),
-    (active, ermsb_target_feature, "1.49.0", Some(44839), None),
-    (active, bpf_target_feature, "1.54.0", Some(44839), None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates (target features)
@@ -284,422 +258,287 @@ declare_features! (
     // feature-group-start: actual feature gates
     // -------------------------------------------------------------------------
 
-    /// Allows using `#![plugin(myplugin)]`.
-    (active, plugin, "1.0.0", Some(29597), None),
-
-    /// Allows using `#[thread_local]` on `static` items.
-    (active, thread_local, "1.0.0", Some(29594), None),
-
-    /// Allows the use of SIMD types in functions declared in `extern` blocks.
-    (active, simd_ffi, "1.0.0", Some(27731), None),
-
-    /// Allows using non lexical lifetimes (RFC 2094).
-    (active, nll, "1.0.0", Some(43234), None),
-
-    /// Allows associated type defaults.
-    (active, associated_type_defaults, "1.2.0", Some(29661), None),
-
-    /// Allows `#![no_core]`.
-    (active, no_core, "1.3.0", Some(29639), None),
-
-    /// Allows default type parameters to influence type inference.
-    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
-
-    /// Allows `repr(simd)` and importing the various simd intrinsics.
-    (active, repr_simd, "1.4.0", Some(27731), None),
-
-    /// Allows `extern "platform-intrinsic" { ... }`.
-    (active, platform_intrinsics, "1.4.0", Some(27731), None),
-
-    /// Allows attributes on expressions and non-item statements.
-    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
-
-    /// Allows the use of type ascription in expressions.
-    (active, type_ascription, "1.6.0", Some(23416), None),
-
-    /// Allows `cfg(target_thread_local)`.
-    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
-
-    /// Allows specialization of implementations (RFC 1210).
-    (incomplete, specialization, "1.7.0", Some(31844), None),
-
-    /// A minimal, sound subset of specialization intended to be used by the
-    /// standard library until the soundness issues with specialization
-    /// are fixed.
-    (active, min_specialization, "1.7.0", Some(31844), None),
-
-    /// Allows using `#[naked]` on functions.
-    (active, naked_functions, "1.9.0", Some(32408), None),
-
-    /// Allows `cfg(target_has_atomic = "...")`.
-    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
-
-    /// Allows `X..Y` patterns.
-    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
-
-    /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
-    (active, never_type, "1.13.0", Some(35121), None),
-
-    /// Allows exhaustive pattern matching on types that contain uninhabited types.
-    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
-
-    /// Allows `union`s to implement `Drop`. Moreover, `union`s may now include fields
-    /// that don't implement `Copy` as long as they don't have any drop glue.
-    /// This is checked recursively. On encountering type variable where no progress can be made,
-    /// `T: Copy` is used as a substitute for "no drop glue".
-    ///
-    /// NOTE: A limited form of `union U { ... }` was accepted in 1.19.0.
-    (active, untagged_unions, "1.13.0", Some(55149), None),
-
-    /// Allows `#[link(..., cfg(..))]`.
-    (active, link_cfg, "1.14.0", Some(37406), None),
-
-    /// Allows `extern "ptx-*" fn()`.
-    (active, abi_ptx, "1.15.0", Some(38788), None),
-
-    /// Allows the `#[repr(i128)]` attribute for enums.
-    (incomplete, repr128, "1.16.0", Some(56071), None),
-
-    /// Allows `#[link(kind="static-nobundle"...)]`.
-    (active, static_nobundle, "1.16.0", Some(37403), None),
-
+    /// Allows using the `amdgpu-kernel` ABI.
+    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
+    /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.
+    (active, abi_avr_interrupt, "1.45.0", Some(69664), None),
+    /// Allows `extern "C-cmse-nonsecure-call" fn()`.
+    (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
+    /// Allows using the `efiapi` ABI.
+    (active, abi_efiapi, "1.40.0", Some(65815), None),
     /// Allows `extern "msp430-interrupt" fn()`.
     (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
-
-    /// Allows declarative macros 2.0 (`macro`).
-    (active, decl_macro, "1.17.0", Some(39412), None),
-
+    /// Allows `extern "ptx-*" fn()`.
+    (active, abi_ptx, "1.15.0", Some(38788), None),
     /// Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
-
+    /// Allows additional const parameter types, such as `&'static str` or user defined types
+    (incomplete, adt_const_params, "1.56.0", Some(44580), None),
+    /// Allows defining an `#[alloc_error_handler]`.
+    (active, alloc_error_handler, "1.29.0", Some(51540), None),
     /// Allows a test to fail without failing the whole suite.
     (active, allow_fail, "1.19.0", Some(46488), None),
-
-    /// Allows unsized tuple coercion.
-    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
-
-    /// Allows defining generators.
-    (active, generators, "1.21.0", Some(43122), None),
-
-    /// Allows `#[doc(cfg(...))]`.
-    (active, doc_cfg, "1.21.0", Some(43781), None),
-
-    /// Allows `#[doc(masked)]`.
-    (active, doc_masked, "1.21.0", Some(44027), None),
-
-    /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
-    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
-
-    /// Allows defining `extern type`s.
-    (active, extern_types, "1.23.0", Some(43467), None),
-
+    /// Allows explicit discriminants on non-unit enum variants.
+    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
     /// Allows trait methods with arbitrary self types.
     (active, arbitrary_self_types, "1.23.0", Some(44874), None),
-
-    /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
-    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
-
-    /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
-    (active, generic_associated_types, "1.23.0", Some(44265), None),
-
-    /// Allows defining `trait X = A + B;` alias items.
-    (active, trait_alias, "1.24.0", Some(41517), None),
-
-    /// Allows inferring `'static` outlives requirements (RFC 2093).
-    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
-
-    /// Allows dereferencing raw pointers during const eval.
-    (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
-
-    /// Allows inconsistent bounds in where clauses.
-    (active, trivial_bounds, "1.28.0", Some(48214), None),
-
-    /// Allows `'a: { break 'a; }`.
-    (active, label_break_value, "1.28.0", Some(48594), None),
-
-    /// Allows using `#[doc(keyword = "...")]`.
-    (active, doc_keyword, "1.28.0", Some(51315), None),
-
-    /// Allows using `try {...}` expressions.
-    (active, try_blocks, "1.29.0", Some(31436), None),
-
-    /// Allows defining an `#[alloc_error_handler]`.
-    (active, alloc_error_handler, "1.29.0", Some(51540), None),
-
-    /// Allows using the `amdgpu-kernel` ABI.
-    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
-
-    /// Allows `#[marker]` on certain traits allowing overlapping implementations.
-    (active, marker_trait_attr, "1.30.0", Some(29864), None),
-
-    /// Allows macro attributes on expressions, statements and non-inline modules.
-    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
-
-    /// Allows unsized rvalues at arguments and parameters.
-    (incomplete, unsized_locals, "1.30.0", Some(48055), None),
-
-    /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
-    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
-
-    /// Allows non-builtin attributes in inner attribute position.
-    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
-
-    /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
-    (active, lint_reasons, "1.31.0", Some(54503), None),
-
-    /// Allows exhaustive integer pattern matching on `usize` and `isize`.
-    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
-
-    /// Allows using `#[ffi_returns_twice]` on foreign functions.
-    (active, ffi_returns_twice, "1.34.0", Some(58314), None),
-
-    /// Allows using `#[optimize(X)]`.
-    (active, optimize_attribute, "1.34.0", Some(54882), None),
-
-    /// Allows using C-variadics.
-    (active, c_variadic, "1.34.0", Some(44930), None),
-
+    /// Allows using `const` operands in inline assembly.
+    (active, asm_const, "1.58.0", Some(72016), None),
+    /// Enables experimental inline assembly support for additional architectures.
+    (active, asm_experimental_arch, "1.58.0", Some(72016), None),
+    /// Allows using `sym` operands in inline assembly.
+    (active, asm_sym, "1.58.0", Some(72016), None),
     /// Allows the user of associated type bounds.
     (active, associated_type_bounds, "1.34.0", Some(52662), None),
-
-    /// Allows `if/while p && let q = r && ...` chains.
-    (incomplete, let_chains, "1.37.0", Some(53667), None),
-
-    /// Allows #[repr(transparent)] on unions (RFC 2645).
-    (active, transparent_unions, "1.37.0", Some(60405), None),
-
-    /// Allows explicit discriminants on non-unit enum variants.
-    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
-
+    /// Allows associated type defaults.
+    (active, associated_type_defaults, "1.2.0", Some(29661), None),
     /// Allows `async || body` closures.
     (active, async_closure, "1.37.0", Some(62290), None),
-
-    /// Allows `impl Trait` to be used inside type aliases (RFC 2515).
-    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
-
-    /// Allows the definition of `const extern fn` and `const unsafe extern fn`.
-    (active, const_extern_fn, "1.40.0", Some(64926), None),
-
-    /// Allows the use of raw-dylibs (RFC 2627).
-    (incomplete, raw_dylib, "1.40.0", Some(58713), None),
-
-    /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
-    /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
-    /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
-    (active, object_safe_for_dispatch, "1.40.0", Some(43561), None),
-
-    /// Allows using the `efiapi` ABI.
-    (active, abi_efiapi, "1.40.0", Some(65815), None),
-
-    /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
-    (active, raw_ref_op, "1.41.0", Some(64490), None),
-
-    /// Allows diverging expressions to fall back to `!` rather than `()`.
-    (active, never_type_fallback, "1.41.0", Some(65992), None),
-
-    /// Allows using the `#[register_attr]` attribute.
-    (active, register_attr, "1.41.0", Some(66080), None),
-
-    /// Allows using the `#[register_tool]` attribute.
-    (active, register_tool, "1.41.0", Some(66079), None),
-
+    /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
+    (active, c_unwind, "1.52.0", Some(74990), None),
+    /// Allows using C-variadics.
+    (active, c_variadic, "1.34.0", Some(44930), None),
+    /// Allows capturing disjoint fields in a closure/generator (RFC 2229).
+    (incomplete, capture_disjoint_fields, "1.49.0", Some(53488), None),
+    /// Enables `#[cfg(panic = "...")]` config key.
+    (active, cfg_panic, "1.49.0", Some(77443), None),
     /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
     (active, cfg_sanitize, "1.41.0", Some(39699), None),
-
-    /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern.
-    (active, half_open_range_patterns, "1.41.0", Some(67264), None),
-
-    /// Allows using `&mut` in constant functions.
-    (active, const_mut_refs, "1.41.0", Some(57349), None),
-
-    /// Allows `impl const Trait for T` syntax.
-    (active, const_trait_impl, "1.42.0", Some(67792), None),
-
-    /// Allows the use of `no_sanitize` attribute.
-    (active, no_sanitize, "1.42.0", Some(39699), None),
-
-    // Allows limiting the evaluation steps of const expressions
-    (active, const_eval_limit, "1.43.0", Some(67217), None),
-
-    /// Allow negative trait implementations.
-    (active, negative_impls, "1.44.0", Some(68318), None),
-
-    /// Allows the use of `#[target_feature]` on safe functions.
-    (active, target_feature_11, "1.45.0", Some(69098), None),
-
+    /// Allows `cfg(target_abi = "...")`.
+    (active, cfg_target_abi, "1.55.0", Some(80970), None),
+    /// Allows `cfg(target_has_atomic = "...")`.
+    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
+    /// Allows `cfg(target_thread_local)`.
+    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
     /// Allow conditional compilation depending on rust version
     (active, cfg_version, "1.45.0", Some(64796), None),
-
-    /// Allows the use of `#[ffi_pure]` on foreign functions.
-    (active, ffi_pure, "1.45.0", Some(58329), None),
-
-    /// Allows the use of `#[ffi_const]` on foreign functions.
-    (active, ffi_const, "1.45.0", Some(58328), None),
-
-    /// Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.
-    (active, abi_avr_interrupt, "1.45.0", Some(69664), None),
-
-    /// Be more precise when looking for live drops in a const context.
-    (active, const_precise_live_drops, "1.46.0", Some(73255), None),
-
-    /// Allows capturing variables in scope using format_args!
-    (active, format_args_capture, "1.46.0", Some(67984), None),
-
-    /// Allows `if let` guard in match arms.
-    (active, if_let_guard, "1.47.0", Some(51114), None),
-
+    /// Allows `#[track_caller]` on closures and generators.
+    (active, closure_track_caller, "1.57.0", Some(87417), None),
+    /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
+    (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None),
+    /// Allows `async {}` expressions in const contexts.
+    (active, const_async_blocks, "1.53.0", Some(85368), None),
+    // Allows limiting the evaluation steps of const expressions
+    (active, const_eval_limit, "1.43.0", Some(67217), None),
+    /// Allows the definition of `const extern fn` and `const unsafe extern fn`.
+    (active, const_extern_fn, "1.40.0", Some(64926), None),
     /// Allows basic arithmetic on floating point types in a `const fn`.
     (active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
-
     /// Allows using and casting function pointers in a `const fn`.
     (active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
-
-    /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
-    (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None),
-
-    /// Allows rustc to inject a default alloc_error_handler
-    (active, default_alloc_error_handler, "1.48.0", Some(66741), None),
-
-    /// Allows argument and return position `impl Trait` in a `const fn`.
-    (active, const_impl_trait, "1.48.0", Some(77463), None),
-
-    /// Allows `#[instruction_set(_)]` attribute
-    (active, isa_attribute, "1.48.0", Some(74727), None),
-
-    /// Allow anonymous constants from an inline `const` block
-    (incomplete, inline_const, "1.49.0", Some(76001), None),
-
-    /// Allows unsized fn parameters.
-    (active, unsized_fn_params, "1.49.0", Some(48055), None),
-
-    /// Allows the use of destructuring assignments.
-    (active, destructuring_assignment, "1.49.0", Some(71126), None),
-
-    /// Enables `#[cfg(panic = "...")]` config key.
-    (active, cfg_panic, "1.49.0", Some(77443), None),
-
-    /// Allows capturing disjoint fields in a closure/generator (RFC 2229).
-    (incomplete, capture_disjoint_fields, "1.49.0", Some(53488), None),
-
+    /// Allows trait bounds in `const fn`.
+    (active, const_fn_trait_bound, "1.53.0", Some(57563), None),
+    /// Allows `for _ in _` loops in const contexts.
+    (active, const_for, "1.56.0", Some(87575), None),
     /// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
     (active, const_generics_defaults, "1.51.0", Some(44580), None),
-
+    /// Allows argument and return position `impl Trait` in a `const fn`.
+    (active, const_impl_trait, "1.48.0", Some(77463), None),
+    /// Allows using `&mut` in constant functions.
+    (active, const_mut_refs, "1.41.0", Some(57349), None),
+    /// Be more precise when looking for live drops in a const context.
+    (active, const_precise_live_drops, "1.46.0", Some(73255), None),
     /// Allows references to types with interior mutability within constants
     (active, const_refs_to_cell, "1.51.0", Some(80384), None),
-
-    /// Allows using `pointer` and `reference` in intra-doc links
-    (active, intra_doc_pointers, "1.51.0", Some(80896), None),
-
-    /// Allows `extern "C-cmse-nonsecure-call" fn()`.
-    (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
-
-    /// Allows associated types in inherent impls.
-    (incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
-
-    // Allows setting the threshold for the `large_assignments` lint.
-    (active, large_assignments, "1.52.0", Some(83518), None),
-
-    /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
-    (active, c_unwind, "1.52.0", Some(74990), None),
-
+    /// Allows `impl const Trait for T` syntax.
+    (active, const_trait_impl, "1.42.0", Some(67792), None),
+    /// Allows the `?` operator in const contexts.
+    (active, const_try, "1.56.0", Some(74935), None),
+    /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
+    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
+    /// Allows non-builtin attributes in inner attribute position.
+    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
+    /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
+    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
+    /// Allows declarative macros 2.0 (`macro`).
+    (active, decl_macro, "1.17.0", Some(39412), None),
+    /// Allows rustc to inject a default alloc_error_handler
+    (active, default_alloc_error_handler, "1.48.0", Some(66741), None),
+    /// Allows default type parameters to influence type inference.
+    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
+    /// Allows `#[derive(Default)]` and `#[default]` on enums.
+    (active, derive_default_enum, "1.56.0", Some(86985), None),
+    /// Allows the use of destructuring assignments.
+    (active, destructuring_assignment, "1.49.0", Some(71126), None),
+    /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
+    (active, doc_auto_cfg, "1.58.0", Some(43781), None),
+    /// Allows `#[doc(cfg(...))]`.
+    (active, doc_cfg, "1.21.0", Some(43781), None),
+    /// Allows `#[doc(cfg_hide(...))]`.
+    (active, doc_cfg_hide, "1.57.0", Some(43781), None),
+    /// Allows using `#[doc(keyword = "...")]`.
+    (active, doc_keyword, "1.28.0", Some(51315), None),
+    /// Allows `#[doc(masked)]`.
+    (active, doc_masked, "1.21.0", Some(44027), None),
+    /// Allows using doc(primitive) without a future-incompat warning
+    (active, doc_primitive, "1.56.0", Some(88070), None),
+    /// Allows `X..Y` patterns.
+    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
+    /// Allows exhaustive pattern matching on types that contain uninhabited types.
+    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
+    /// Allows explicit generic arguments specification with `impl Trait` present.
+    (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
+    /// Allows defining `extern type`s.
+    (active, extern_types, "1.23.0", Some(43467), None),
+    /// Allows the use of `#[ffi_const]` on foreign functions.
+    (active, ffi_const, "1.45.0", Some(58328), None),
+    /// Allows the use of `#[ffi_pure]` on foreign functions.
+    (active, ffi_pure, "1.45.0", Some(58329), None),
+    /// Allows using `#[ffi_returns_twice]` on foreign functions.
+    (active, ffi_returns_twice, "1.34.0", Some(58314), None),
     /// Allows using `#[repr(align(...))]` on function items
     (active, fn_align, "1.53.0", Some(82232), None),
-
-    /// Allows `extern "wasm" fn`
-    (active, wasm_abi, "1.53.0", Some(83788), None),
-
-    /// Allows function attribute `#[no_coverage]`, to bypass coverage
-    /// instrumentation of that function.
-    (active, no_coverage, "1.53.0", Some(84605), None),
-
-    /// Allows trait bounds in `const fn`.
-    (active, const_fn_trait_bound, "1.53.0", Some(57563), None),
-
-    /// Allows `async {}` expressions in const contexts.
-    (active, const_async_blocks, "1.53.0", Some(85368), None),
-
+    /// Allows defining generators.
+    (active, generators, "1.21.0", Some(43122), None),
+    /// Infer generic args for both consts and types.
+    (active, generic_arg_infer, "1.55.0", Some(85077), None),
+    /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
+    (active, generic_associated_types, "1.23.0", Some(44265), None),
+    /// Allows non-trivial generic constants which have to have wfness manually propagated to callers
+    (incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
+    /// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern.
+    (active, half_open_range_patterns, "1.41.0", Some(67264), None),
+    /// Allows `if let` guard in match arms.
+    (active, if_let_guard, "1.47.0", Some(51114), None),
     /// Allows using imported `main` function
     (active, imported_main, "1.53.0", Some(28937), None),
-
+    /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
+    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
+    /// Allows inferring `'static` outlives requirements (RFC 2093).
+    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
+    /// Allows associated types in inherent impls.
+    (incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
+    /// Allow anonymous constants from an inline `const` block
+    (incomplete, inline_const, "1.49.0", Some(76001), None),
+    /// Allows using `pointer` and `reference` in intra-doc links
+    (active, intra_doc_pointers, "1.51.0", Some(80896), None),
+    /// Allows `#[instruction_set(_)]` attribute
+    (active, isa_attribute, "1.48.0", Some(74727), None),
+    /// Allows `'a: { break 'a; }`.
+    (active, label_break_value, "1.28.0", Some(48594), None),
+    // Allows setting the threshold for the `large_assignments` lint.
+    (active, large_assignments, "1.52.0", Some(83518), None),
+    /// Allows `if/while p && let q = r && ...` chains.
+    (incomplete, let_chains, "1.37.0", Some(53667), None),
+    /// Allows `let...else` statements.
+    (active, let_else, "1.56.0", Some(87335), None),
+    /// Allows `#[link(..., cfg(..))]`.
+    (active, link_cfg, "1.14.0", Some(37406), None),
+    /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
+    (active, lint_reasons, "1.31.0", Some(54503), None),
+    /// Allows `#[marker]` on certain traits allowing overlapping implementations.
+    (active, marker_trait_attr, "1.30.0", Some(29864), None),
+    /// A minimal, sound subset of specialization intended to be used by the
+    /// standard library until the soundness issues with specialization
+    /// are fixed.
+    (active, min_specialization, "1.7.0", Some(31844), None),
+    /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
+    (active, more_qualified_paths, "1.54.0", Some(86935), None),
+    /// Allows the `#[must_not_suspend]` attribute.
+    (active, must_not_suspend, "1.57.0", Some(83310), None),
+    /// Allows using `#[naked]` on functions.
+    (active, naked_functions, "1.9.0", Some(32408), None),
     /// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
     (active, native_link_modifiers, "1.53.0", Some(81490), None),
-
+    /// Allows specifying the as-needed link modifier
+    (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
     /// Allows specifying the bundle link modifier
     (active, native_link_modifiers_bundle, "1.53.0", Some(81490), None),
-
     /// Allows specifying the verbatim link modifier
     (active, native_link_modifiers_verbatim, "1.53.0", Some(81490), None),
-
     /// Allows specifying the whole-archive link modifier
     (active, native_link_modifiers_whole_archive, "1.53.0", Some(81490), None),
-
-    /// Allows specifying the as-needed link modifier
-    (active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
-
-    /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
-    (active, more_qualified_paths, "1.54.0", Some(86935), None),
-
-    /// Allows `cfg(target_abi = "...")`.
-    (active, cfg_target_abi, "1.55.0", Some(80970), None),
-
-    /// Infer generic args for both consts and types.
-    (active, generic_arg_infer, "1.55.0", Some(85077), None),
-
-    /// Allows `#[derive(Default)]` and `#[default]` on enums.
-    (active, derive_default_enum, "1.56.0", Some(86985), None),
-
-    /// Allows `for _ in _` loops in const contexts.
-    (active, const_for, "1.56.0", Some(87575), None),
-
-    /// Allows the `?` operator in const contexts.
-    (active, const_try, "1.56.0", Some(74935), None),
-
+    /// Allow negative trait implementations.
+    (active, negative_impls, "1.44.0", Some(68318), None),
+    /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
+    (active, never_type, "1.13.0", Some(35121), None),
+    /// Allows diverging expressions to fall back to `!` rather than `()`.
+    (active, never_type_fallback, "1.41.0", Some(65992), None),
+    /// Allows using non lexical lifetimes (RFC 2094).
+    (active, nll, "1.0.0", Some(43234), None),
+    /// Allows `#![no_core]`.
+    (active, no_core, "1.3.0", Some(29639), None),
+    /// Allows function attribute `#[no_coverage]`, to bypass coverage
+    /// instrumentation of that function.
+    (active, no_coverage, "1.53.0", Some(84605), None),
+    /// Allows the use of `no_sanitize` attribute.
+    (active, no_sanitize, "1.42.0", Some(39699), None),
+    /// Allows using the `non_exhaustive_omitted_patterns` lint.
+    (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
+    /// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
+    /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
+    /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
+    (active, object_safe_for_dispatch, "1.40.0", Some(43561), None),
+    /// Allows using `#[optimize(X)]`.
+    (active, optimize_attribute, "1.34.0", Some(54882), None),
+    /// Allows `extern "platform-intrinsic" { ... }`.
+    (active, platform_intrinsics, "1.4.0", Some(27731), None),
+    /// Allows using `#![plugin(myplugin)]`.
+    (active, plugin, "1.0.0", Some(29597), None),
+    /// Allows exhaustive integer pattern matching on `usize` and `isize`.
+    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
+    /// Allows macro attributes on expressions, statements and non-inline modules.
+    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
+    /// Allows the use of raw-dylibs (RFC 2627).
+    (incomplete, raw_dylib, "1.40.0", Some(58713), None),
+    /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
+    (active, raw_ref_op, "1.41.0", Some(64490), None),
+    /// Allows using the `#[register_attr]` attribute.
+    (active, register_attr, "1.41.0", Some(66080), None),
+    /// Allows using the `#[register_tool]` attribute.
+    (active, register_tool, "1.41.0", Some(66079), None),
+    /// Allows the `#[repr(i128)]` attribute for enums.
+    (incomplete, repr128, "1.16.0", Some(56071), None),
+    /// Allows `repr(simd)` and importing the various simd intrinsics.
+    (active, repr_simd, "1.4.0", Some(27731), None),
+    /// Allows the use of SIMD types in functions declared in `extern` blocks.
+    (active, simd_ffi, "1.0.0", Some(27731), None),
+    /// Allows specialization of implementations (RFC 1210).
+    (incomplete, specialization, "1.7.0", Some(31844), None),
+    /// Allows `#[link(kind="static-nobundle"...)]`.
+    (active, static_nobundle, "1.16.0", Some(37403), None),
+    /// Allows attributes on expressions and non-item statements.
+    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
+    /// Allows the use of `#[target_feature]` on safe functions.
+    (active, target_feature_11, "1.45.0", Some(69098), None),
+    /// Allows using `#[thread_local]` on `static` items.
+    (active, thread_local, "1.0.0", Some(29594), None),
+    /// Allows defining `trait X = A + B;` alias items.
+    (active, trait_alias, "1.24.0", Some(41517), None),
     /// Allows upcasting trait objects via supertraits.
     /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
     (incomplete, trait_upcasting, "1.56.0", Some(65991), None),
-
-    /// Allows explicit generic arguments specification with `impl Trait` present.
-    (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
-
-    /// Allows using doc(primitive) without a future-incompat warning
-    (active, doc_primitive, "1.56.0", Some(88070), None),
-
-    /// Allows non-trivial generic constants which have to have wfness manually propagated to callers
-    (incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
-
-    /// Allows additional const parameter types, such as `&'static str` or user defined types
-    (incomplete, adt_const_params, "1.56.0", Some(44580), None),
-
-    /// Allows `let...else` statements.
-    (active, let_else, "1.56.0", Some(87335), None),
-
-    /// Allows the `#[must_not_suspend]` attribute.
-    (active, must_not_suspend, "1.57.0", Some(83310), None),
-
-    /// Allows `#[track_caller]` on closures and generators.
-    (active, closure_track_caller, "1.57.0", Some(87417), None),
-
-    /// Allows `#[doc(cfg_hide(...))]`.
-    (active, doc_cfg_hide, "1.57.0", Some(43781), None),
-
-    /// Allows using the `non_exhaustive_omitted_patterns` lint.
-    (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
-
+    /// Allows #[repr(transparent)] on unions (RFC 2645).
+    (active, transparent_unions, "1.37.0", Some(60405), None),
+    /// Allows inconsistent bounds in where clauses.
+    (active, trivial_bounds, "1.28.0", Some(48214), None),
+    /// Allows using `try {...}` expressions.
+    (active, try_blocks, "1.29.0", Some(31436), None),
+    /// Allows `impl Trait` to be used inside type aliases (RFC 2515).
+    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
+    /// Allows the use of type ascription in expressions.
+    (active, type_ascription, "1.6.0", Some(23416), None),
     /// Allows creation of instances of a struct by moving fields that have
     /// not changed from prior instances of the same struct (RFC #2528)
     (incomplete, type_changing_struct_update, "1.58.0", Some(86555), None),
-
-    /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
-    (active, doc_auto_cfg, "1.58.0", Some(43781), None),
-
-    /// Allows using `const` operands in inline assembly.
-    (active, asm_const, "1.58.0", Some(72016), None),
-
-    /// Allows using `sym` operands in inline assembly.
-    (active, asm_sym, "1.58.0", Some(72016), None),
-
-    /// Enables experimental inline assembly support for additional architectures.
-    (active, asm_experimental_arch, "1.58.0", Some(72016), None),
+    /// Allows unsized fn parameters.
+    (active, unsized_fn_params, "1.49.0", Some(48055), None),
+    /// Allows unsized rvalues at arguments and parameters.
+    (incomplete, unsized_locals, "1.30.0", Some(48055), None),
+    /// Allows unsized tuple coercion.
+    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
+    /// Allows `union`s to implement `Drop`. Moreover, `union`s may now include fields
+    /// that don't implement `Copy` as long as they don't have any drop glue.
+    /// This is checked recursively. On encountering type variable where no progress can be made,
+    /// `T: Copy` is used as a substitute for "no drop glue".
+    ///
+    /// NOTE: A limited form of `union U { ... }` was accepted in 1.19.0.
+    (active, untagged_unions, "1.13.0", Some(55149), None),
+    /// Allows `extern "wasm" fn`
+    (active, wasm_abi, "1.53.0", Some(83788), None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 33188d375f5..7212bbf38c7 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -115,16 +115,26 @@ macro_rules! template {
 
 macro_rules! ungated {
     ($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
-        (sym::$attr, $typ, $tpl, Ungated)
+        BuiltinAttribute { name: sym::$attr, type_: $typ, template: $tpl, gate: Ungated }
     };
 }
 
 macro_rules! gated {
     ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => {
-        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)))
+        BuiltinAttribute {
+            name: sym::$attr,
+            type_: $typ,
+            template: $tpl,
+            gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)),
+        }
     };
     ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
-        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)))
+        BuiltinAttribute {
+            name: sym::$attr,
+            type_: $typ,
+            template: $tpl,
+            gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)),
+        }
     };
 }
 
@@ -143,12 +153,12 @@ macro_rules! rustc_attr {
         )
     };
     ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
-        (
-            sym::$attr,
-            $typ,
-            $tpl,
-            Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)),
-        )
+        BuiltinAttribute {
+            name: sym::$attr,
+            type_: $typ,
+            template: $tpl,
+            gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)),
+        }
     };
 }
 
@@ -161,7 +171,12 @@ macro_rules! experimental {
 const IMPL_DETAIL: &str = "internal implementation detail";
 const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
 
-pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
+pub struct BuiltinAttribute {
+    pub name: Symbol,
+    pub type_: AttributeType,
+    pub template: AttributeTemplate,
+    pub gate: AttributeGate,
+}
 
 /// Attributes that have a special meaning to rustc or rustdoc.
 #[rustfmt::skip]
@@ -290,9 +305,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     // Plugins:
-    (
-        sym::plugin, CrateLevel, template!(List: "name"),
-        Gated(
+    BuiltinAttribute {
+        name: sym::plugin,
+        type_: CrateLevel,
+        template: template!(List: "name"),
+        gate: Gated(
             Stability::Deprecated(
                 "https://github.com/rust-lang/rust/pull/64675",
                 Some("may be removed in a future compiler version"),
@@ -300,8 +317,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
             sym::plugin,
             "compiler plugins are deprecated",
             cfg_fn!(plugin)
-        )
-    ),
+        ),
+    },
 
     // Testing:
     gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)),
@@ -497,17 +514,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         lang, Normal, template!(NameValueStr: "name"), lang_items,
         "language items are subject to change",
     ),
-    (
-        sym::rustc_diagnostic_item,
-        Normal,
-        template!(NameValueStr: "name"),
-        Gated(
+    BuiltinAttribute {
+        name: sym::rustc_diagnostic_item,
+        type_: Normal,
+        template: template!(NameValueStr: "name"),
+        gate: Gated(
             Stability::Unstable,
             sym::rustc_attrs,
             "diagnostic items compiler internal support for linting",
             cfg_fn!(rustc_attrs),
         ),
-    ),
+    },
     gated!(
         // Used in resolve:
         prelude_import, Normal, template!(Word),
@@ -601,7 +618,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 ];
 
 pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> {
-    BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect()
+    BUILTIN_ATTRIBUTES.iter().filter(|attr| attr.gate.is_deprecated()).collect()
 }
 
 pub fn is_builtin_attr_name(name: Symbol) -> bool {
@@ -612,8 +629,8 @@ pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &BuiltinAttribute>>
     SyncLazy::new(|| {
         let mut map = FxHashMap::default();
         for attr in BUILTIN_ATTRIBUTES.iter() {
-            if map.insert(attr.0, attr).is_some() {
-                panic!("duplicate builtin attribute `{}`", attr.0);
+            if map.insert(attr.name, attr).is_some() {
+                panic!("duplicate builtin attribute `{}`", attr.name);
             }
         }
         map
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 7b9b68268ea..4b40040a036 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -45,132 +45,130 @@ declare_features! (
     // feature-group-start: removed features
     // -------------------------------------------------------------------------
 
-    (removed, import_shadowing, "1.0.0", None, None, None),
-    (removed, managed_boxes, "1.0.0", None, None, None),
-    /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
-    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
-    (removed, reflect, "1.0.0", Some(27749), None, None),
-    /// A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    (removed, opt_out_copy, "1.0.0", None, None, None),
-    (removed, quad_precision_float, "1.0.0", None, None, None),
-    (removed, struct_inherit, "1.0.0", None, None, None),
-    (removed, test_removed_feature, "1.0.0", None, None, None),
-    (removed, visible_private_types, "1.0.0", None, None, None),
-    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
-    /// Allows using items which are missing stability attributes
-    (removed, unmarked_api, "1.0.0", None, None, None),
-    (removed, allocator, "1.0.0", None, None, None),
-    (removed, simd, "1.0.0", Some(27731), None,
-     Some("removed in favor of `#[repr(simd)]`")),
     (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
      Some("merged into `#![feature(slice_patterns)]`")),
-    (removed, macro_reexport, "1.0.0", Some(29638), None,
-     Some("subsumed by `pub use`")),
+    (removed, allocator, "1.0.0", None, None, None),
+    (removed, await_macro, "1.38.0", Some(50547), None,
+     Some("subsumed by `.await` syntax")),
+    /// Allows comparing raw pointers during const eval.
+    (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,
+     Some("cannot be allowed in const eval in any meaningful way")),
+    /// Allows non-trivial generic constants which have to be manually propagated upwards.
+     (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")),
+    /// Allows the definition of `const` functions with some advanced features.
+    (removed, const_fn, "1.54.0", Some(57563), None,
+     Some("split into finer-grained feature gates")),
+    /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
+    (removed, const_generics, "1.34.0", Some(44580), None,
+     Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")),
+    /// Allows `[x; N]` where `x` is a constant (RFC 2203).
+    (removed, const_in_array_repeat_expressions,  "1.37.0", Some(49147), None,
+     Some("removed due to causing promotable bugs")),
+    /// Allows casting raw pointers to `usize` during const eval.
+    (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
+     Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
+    /// Allows `T: ?const Trait` syntax in bounds.
+    (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), None,
+     Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")),
     /// Allows using custom attributes (RFC 572).
     (removed, custom_attribute, "1.0.0", Some(29642), None,
      Some("removed in favor of `#![register_tool]` and `#![register_attr]`")),
-    /// Allows features specific to OIBIT (now called auto traits).
-    /// Renamed to `auto_traits`.
-    (removed, optin_builtin_traits, "1.0.0", Some(13231), None,
-     Some("renamed to `auto_traits`")),
-    (removed, pushpop_unsafe, "1.2.0", None, None, None),
-    (removed, needs_allocator, "1.4.0", Some(27389), None,
-     Some("subsumed by `#![feature(allocator_internals)]`")),
-    /// Allows identifying crates that contain sanitizer runtimes.
-    (removed, sanitizer_runtime, "1.17.0", None, None, None),
+    /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+    (removed, custom_derive, "1.32.0", Some(29644), None,
+     Some("subsumed by `#[proc_macro_derive]`")),
     /// Allows `#[doc(spotlight)]`.
     /// The attribute was renamed to `#[doc(notable_trait)]`
     /// and the feature to `doc_notable_trait`.
     (removed, doc_spotlight, "1.22.0", Some(45040), None,
      Some("renamed to `doc_notable_trait`")),
-    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, panic_implementation, "1.28.0", Some(44489), None,
-     Some("subsumed by `#[panic_handler]`")),
-    /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
-    (removed, custom_derive, "1.32.0", Some(29644), None,
-     Some("subsumed by `#[proc_macro_derive]`")),
-    /// Paths of the form: `extern::foo::bar`
-    (removed, extern_in_paths, "1.33.0", Some(55600), None,
-     Some("subsumed by `::foo::bar` paths")),
-    (removed, quote, "1.33.0", Some(29601), None, None),
-    /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
-    (removed, const_generics, "1.34.0", Some(44580), None,
-     Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")),
-    /// Allows `[x; N]` where `x` is a constant (RFC 2203).
-    (removed, const_in_array_repeat_expressions,  "1.37.0", Some(49147), None,
-     Some("removed due to causing promotable bugs")),
     /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
     (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
-    (removed, await_macro, "1.38.0", Some(50547), None,
-     Some("subsumed by `.await` syntax")),
     /// Allows defining `existential type`s.
     (removed, existential_type, "1.38.0", Some(63063), None,
      Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
-    /// Allows using the macros:
-    /// + `__diagnostic_used`
-    /// + `__register_diagnostic`
-    /// +`__build_diagnostic_array`
-    (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
-    /// Allows using `#[on_unimplemented(..)]` on traits.
-    /// (Moved to `rustc_attrs`.)
-    (removed, on_unimplemented, "1.40.0", None, None, None),
-    /// Allows overlapping impls of marker traits.
-    (removed, overlapping_marker_traits, "1.42.0", Some(29864), None,
-     Some("removed in favor of `#![feature(marker_trait_attr)]`")),
-    /// Allows `T: ?const Trait` syntax in bounds.
-    (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), None,
-     Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")),
-    /// Allows `#[no_debug]`.
-    (removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),
+    /// Paths of the form: `extern::foo::bar`
+    (removed, extern_in_paths, "1.33.0", Some(55600), None,
+     Some("subsumed by `::foo::bar` paths")),
+    /// Allows `#[doc(include = "some-file")]`.
+    (removed, external_doc, "1.54.0", Some(44732), None,
+     Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
+    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
+    (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
+     Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
+    (removed, import_shadowing, "1.0.0", None, None, None),
     /// Lazily evaluate constants. This allows constants to depend on type parameters.
     (removed, lazy_normalization_consts, "1.46.0", Some(72219), None, Some("superseded by `generic_const_exprs`")),
-    /// Allows comparing raw pointers during const eval.
-    (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,
-     Some("cannot be allowed in const eval in any meaningful way")),
-    /// Allows non-trivial generic constants which have to be manually propagated upwards.
-    (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")),
     /// Allows using the `#[link_args]` attribute.
     (removed, link_args, "1.53.0", Some(29596), None,
      Some("removed in favor of using `-C link-arg=ARG` on command line, \
            which is available from cargo build scripts with `cargo:rustc-link-arg` now")),
+    (removed, macro_reexport, "1.0.0", Some(29638), None,
+     Some("subsumed by `pub use`")),
     /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
     (removed, main, "1.53.0", Some(29634), None, None),
-    (removed, pub_macro_rules, "1.53.0", Some(78855), None,
-     Some("removed due to being incomplete, in particular it does not work across crates")),
-    /// Allows the definition of `const` functions with some advanced features.
-    (removed, const_fn, "1.54.0", Some(57563), None,
-     Some("split into finer-grained feature gates")),
-    /// Allows using `#[plugin_registrar]` on functions.
-    (removed, plugin_registrar, "1.54.0", Some(29597), None,
-     Some("a __rustc_plugin_registrar symbol must now be defined instead")),
-
-    /// Allows `#[doc(include = "some-file")]`.
-    (removed, external_doc, "1.54.0", Some(44732), None,
-     Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
-
-     /// Allows casting raw pointers to `usize` during const eval.
-    (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
-     Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
-
-    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
-     Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
-
+    (removed, managed_boxes, "1.0.0", None, None, None),
     /// Allows the use of type alias impl trait in function return positions
     (removed, min_type_alias_impl_trait, "1.56.0", Some(63063), None,
      Some("removed in favor of full type_alias_impl_trait")),
-
+    (removed, needs_allocator, "1.4.0", Some(27389), None,
+     Some("subsumed by `#![feature(allocator_internals)]`")),
+    /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
+    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
+    /// Allows `#[no_debug]`.
+    (removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),
+    /// Allows using `#[on_unimplemented(..)]` on traits.
+    /// (Moved to `rustc_attrs`.)
+    (removed, on_unimplemented, "1.40.0", None, None, None),
+    /// A way to temporarily opt out of opt in copy. This will *never* be accepted.
+    (removed, opt_out_copy, "1.0.0", None, None, None),
+    /// Allows features specific to OIBIT (now called auto traits).
+    /// Renamed to `auto_traits`.
+    (removed, optin_builtin_traits, "1.0.0", Some(13231), None,
+     Some("renamed to `auto_traits`")),
+    /// Allows overlapping impls of marker traits.
+    (removed, overlapping_marker_traits, "1.42.0", Some(29864), None,
+     Some("removed in favor of `#![feature(marker_trait_attr)]`")),
+    (removed, panic_implementation, "1.28.0", Some(44489), None,
+     Some("subsumed by `#[panic_handler]`")),
+    /// Allows using `#[plugin_registrar]` on functions.
+    (removed, plugin_registrar, "1.54.0", Some(29597), None,
+     Some("a __rustc_plugin_registrar symbol must now be defined instead")),
+    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, pub_macro_rules, "1.53.0", Some(78855), None,
+     Some("removed due to being incomplete, in particular it does not work across crates")),
+    (removed, pushpop_unsafe, "1.2.0", None, None, None),
+    (removed, quad_precision_float, "1.0.0", None, None, None),
+    (removed, quote, "1.33.0", Some(29601), None, None),
+    (removed, reflect, "1.0.0", Some(27749), None, None),
+    /// Allows using the macros:
+    /// + `__diagnostic_used`
+    /// + `__register_diagnostic`
+    /// +`__build_diagnostic_array`
+    (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
+    /// Allows identifying crates that contain sanitizer runtimes.
+    (removed, sanitizer_runtime, "1.17.0", None, None, None),
+    (removed, simd, "1.0.0", Some(27731), None,
+     Some("removed in favor of `#[repr(simd)]`")),
+    (removed, struct_inherit, "1.0.0", None, None, None),
+    (removed, test_removed_feature, "1.0.0", None, None, None),
+    /// Allows using items which are missing stability attributes
+    (removed, unmarked_api, "1.0.0", None, None, None),
+    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
     /// Allows `#[unwind(..)]`.
     ///
     /// Permits specifying whether a function should permit unwinding or abort on unwind.
     (removed, unwind_attributes, "1.56.0", Some(58760), None, Some("use the C-unwind ABI instead")),
+    (removed, visible_private_types, "1.0.0", None, None, None),
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
+    // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
+    // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs
index 1a34dd04428..5091a7bccc5 100644
--- a/compiler/rustc_hir/src/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
@@ -1,10 +1,5 @@
 /// This declares a list of types which can be allocated by `Arena`.
 ///
-/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
-/// This is faster and more memory efficient if there's only a few allocations of the type.
-/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
-/// faster and more memory efficient if there is lots of allocations.
-///
 /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`,
 /// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro.
 #[macro_export]
@@ -12,7 +7,7 @@ macro_rules! arena_types {
     ($macro:path, $tcx:lifetime) => (
         $macro!([
             // HIR types
-            [few] hir_krate: rustc_hir::Crate<$tcx>,
+            [] hir_krate: rustc_hir::Crate<$tcx>,
             [] arm: rustc_hir::Arm<$tcx>,
             [] asm_operand: (rustc_hir::InlineAsmOperand<$tcx>, Span),
             [] asm_template: rustc_ast::InlineAsmTemplatePiece,
@@ -29,14 +24,14 @@ macro_rules! arena_types {
             [] pat_field: rustc_hir::PatField<$tcx>,
             [] fn_decl: rustc_hir::FnDecl<$tcx>,
             [] foreign_item: rustc_hir::ForeignItem<$tcx>,
-            [few] foreign_item_ref: rustc_hir::ForeignItemRef,
+            [] foreign_item_ref: rustc_hir::ForeignItemRef,
             [] impl_item: rustc_hir::ImplItem<$tcx>,
             [] impl_item_ref: rustc_hir::ImplItemRef,
             [] item: rustc_hir::Item<$tcx>,
-            [few] inline_asm: rustc_hir::InlineAsm<$tcx>,
-            [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
+            [] inline_asm: rustc_hir::InlineAsm<$tcx>,
+            [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
             [] local: rustc_hir::Local<$tcx>,
-            [few] mod_: rustc_hir::Mod<$tcx>,
+            [] mod_: rustc_hir::Mod<$tcx>,
             [] owner_info: rustc_hir::OwnerInfo<$tcx>,
             [] param: rustc_hir::Param<$tcx>,
             [] pat: rustc_hir::Pat<$tcx>,
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index cb668eb35e0..60761a05de8 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -104,8 +104,10 @@ pub enum DefKind {
     Use,
     /// An `extern` block.
     ForeignMod,
-    /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`, or `const { 1 + 2}`
+    /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`
     AnonConst,
+    /// An inline constant, e.g. `const { 1 + 2 }`
+    InlineConst,
     /// Opaque type, aka `impl Trait`.
     OpaqueTy,
     Field,
@@ -155,6 +157,7 @@ impl DefKind {
             DefKind::Use => "import",
             DefKind::ForeignMod => "foreign module",
             DefKind::AnonConst => "constant expression",
+            DefKind::InlineConst => "inline constant",
             DefKind::Field => "field",
             DefKind::Impl => "implementation",
             DefKind::Closure => "closure",
@@ -174,6 +177,7 @@ impl DefKind {
             | DefKind::OpaqueTy
             | DefKind::Impl
             | DefKind::Use
+            | DefKind::InlineConst
             | DefKind::ExternCrate => "an",
             DefKind::Macro(macro_kind) => macro_kind.article(),
             _ => "a",
@@ -207,6 +211,7 @@ impl DefKind {
 
             // Not namespaced.
             DefKind::AnonConst
+            | DefKind::InlineConst
             | DefKind::Field
             | DefKind::LifetimeParam
             | DefKind::ExternCrate
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index a441a635c1e..e00c5789fe9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -647,6 +647,22 @@ pub struct WhereBoundPredicate<'hir> {
     pub bounds: GenericBounds<'hir>,
 }
 
+impl WhereBoundPredicate<'hir> {
+    /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
+    pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
+        let path = match self.bounded_ty.kind {
+            TyKind::Path(QPath::Resolved(None, path)) => path,
+            _ => return false,
+        };
+        match path.res {
+            Res::Def(DefKind::TyParam, def_id) | Res::SelfTy(Some(def_id), None) => {
+                def_id == param_def_id
+            }
+            _ => false,
+        }
+    }
+}
+
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
 #[derive(Debug, HashStable_Generic)]
 pub struct WhereRegionPredicate<'hir> {
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 38cbf5314ef..c0137fc7a5a 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -139,9 +139,6 @@ pub fn dep_graph_path(sess: &Session) -> PathBuf {
 pub fn staging_dep_graph_path(sess: &Session) -> PathBuf {
     in_incr_comp_dir_sess(sess, STAGING_DEP_GRAPH_FILENAME)
 }
-pub fn dep_graph_path_from(incr_comp_session_dir: &Path) -> PathBuf {
-    in_incr_comp_dir(incr_comp_session_dir, DEP_GRAPH_FILENAME)
-}
 
 pub fn work_products_path(sess: &Session) -> PathBuf {
     in_incr_comp_dir_sess(sess, WORK_PRODUCTS_FILENAME)
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 4d38556e5d2..9c6e2aeb50a 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -6,6 +6,7 @@ use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
 use rustc_middle::ty::OnDiskCache;
 use rustc_serialize::opaque::Decoder;
 use rustc_serialize::Decodable;
+use rustc_session::config::IncrementalStateAssertion;
 use rustc_session::Session;
 use std::path::Path;
 
@@ -16,6 +17,7 @@ use super::work_product;
 
 type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;
 
+#[derive(Debug)]
 pub enum LoadResult<T> {
     Ok { data: T },
     DataOutOfDate,
@@ -24,6 +26,26 @@ pub enum LoadResult<T> {
 
 impl<T: Default> LoadResult<T> {
     pub fn open(self, sess: &Session) -> T {
+        // Check for errors when using `-Zassert-incremental-state`
+        match (sess.opts.assert_incr_state, &self) {
+            (Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => {
+                sess.fatal(
+                    "We asserted that the incremental cache should not be loaded, \
+                         but it was loaded.",
+                );
+            }
+            (
+                Some(IncrementalStateAssertion::Loaded),
+                LoadResult::Error { .. } | LoadResult::DataOutOfDate,
+            ) => {
+                sess.fatal(
+                    "We asserted that an existing incremental cache directory should \
+                         be successfully loaded, but it was not.",
+                );
+            }
+            _ => {}
+        };
+
         match self {
             LoadResult::Error { message } => {
                 sess.warn(&message);
@@ -33,7 +55,7 @@ impl<T: Default> LoadResult<T> {
                 if let Err(err) = delete_all_session_dir_contents(sess) {
                     sess.err(&format!(
                         "Failed to delete invalidated or incompatible \
-                                      incremental compilation session directory contents `{}`: {}.",
+                         incremental compilation session directory contents `{}`: {}.",
                         dep_graph_path(sess).display(),
                         err
                     ));
@@ -105,7 +127,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
 
     // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
     // Fortunately, we just checked that this isn't the case.
-    let path = dep_graph_path_from(&sess.incr_comp_session_dir());
+    let path = dep_graph_path(&sess);
     let report_incremental_info = sess.opts.debugging_opts.incremental_info;
     let expected_hash = sess.opts.dep_tracking_hash(false);
 
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 45639bad243..55ccfd0ad23 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -118,32 +118,54 @@ macro_rules! newtype_index {
         }
 
         impl $type {
+            /// Maximum value the index can take, as a `u32`.
             $v const MAX_AS_U32: u32 = $max;
 
+            /// Maximum value the index can take.
             $v const MAX: Self = Self::from_u32($max);
 
+            /// Creates a new index from a given `usize`.
+            ///
+            /// # Panics
+            ///
+            /// Will panic if `value` exceeds `MAX`.
             #[inline]
             $v const fn from_usize(value: usize) -> Self {
                 assert!(value <= ($max as usize));
+                // SAFETY: We just checked that `value <= max`.
                 unsafe {
                     Self::from_u32_unchecked(value as u32)
                 }
             }
 
+            /// Creates a new index from a given `u32`.
+            ///
+            /// # Panics
+            ///
+            /// Will panic if `value` exceeds `MAX`.
             #[inline]
             $v const fn from_u32(value: u32) -> Self {
                 assert!(value <= $max);
+                // SAFETY: We just checked that `value <= max`.
                 unsafe {
                     Self::from_u32_unchecked(value)
                 }
             }
 
+            /// Creates a new index from a given `u32`.
+            ///
+            /// # Safety
+            ///
+            /// The provided value must be less than or equal to the maximum value for the newtype.
+            /// Providing a value outside this range is undefined due to layout restrictions.
+            ///
+            /// Prefer using `from_u32`.
             #[inline]
             $v const unsafe fn from_u32_unchecked(value: u32) -> Self {
                 Self { private: value }
             }
 
-            /// Extracts the value of this index as an integer.
+            /// Extracts the value of this index as a `usize`.
             #[inline]
             $v const fn index(self) -> usize {
                 self.as_usize()
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 2296cc6129a..5b4a9d9dfad 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         let tcx = self.tcx;
 
         // Select everything, returning errors.
-        let true_errors = fulfill_cx.select_where_possible(self).err().unwrap_or_else(Vec::new);
+        let true_errors = fulfill_cx.select_where_possible(self);
         debug!("true_errors = {:#?}", true_errors);
 
         if !true_errors.is_empty() {
@@ -118,7 +118,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         }
 
         // Anything left unselected *now* must be an ambiguity.
-        let ambig_errors = fulfill_cx.select_all_or_error(self).err().unwrap_or_else(Vec::new);
+        let ambig_errors = fulfill_cx.select_all_or_error(self);
         debug!("ambig_errors = {:#?}", ambig_errors);
 
         let region_obligations = self.take_registered_region_obligations();
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 8849d623b2d..c25ec1356e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1704,13 +1704,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         if let ty::Opaque(def_id, substs) = ty.kind() {
             let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
             // Future::Output
-            let item_def_id = self
-                .tcx
-                .associated_items(future_trait)
-                .in_definition_order()
-                .next()
-                .unwrap()
-                .def_id;
+            let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
 
             let bounds = self.tcx.explicit_item_bounds(*def_id);
 
@@ -1800,31 +1794,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
             },
             (_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
-                let span = match cause.code {
-                    // scrutinee's span
-                    ObligationCauseCode::Pattern { span: Some(span), .. } => span,
-                    _ => exp_span,
-                };
-                diag.span_suggestion_verbose(
-                    span.shrink_to_hi(),
-                    "consider `await`ing on the `Future`",
-                    ".await".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => {
-                let span = match cause.code {
-                    // scrutinee's span
-                    ObligationCauseCode::Pattern { span: Some(span), .. } => span,
-                    _ => exp_span,
-                };
                 diag.span_suggestion_verbose(
-                    span.shrink_to_hi(),
+                    exp_span.shrink_to_hi(),
                     "consider `await`ing on the `Future`",
                     ".await".to_string(),
                     Applicability::MaybeIncorrect,
                 );
             }
+            (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => match cause.code {
+                ObligationCauseCode::Pattern { span: Some(span), .. }
+                | ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => {
+                    diag.span_suggestion_verbose(
+                        span.shrink_to_hi(),
+                        "consider `await`ing on the `Future`",
+                        ".await".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
+                    ref prior_arms,
+                    ..
+                }) => {
+                    diag.multipart_suggestion_verbose(
+                        "consider `await`ing on the `Future`",
+                        prior_arms
+                            .iter()
+                            .map(|arm| (arm.shrink_to_hi(), ".await".to_string()))
+                            .collect(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                _ => {}
+            },
             _ => {}
         }
     }
@@ -2190,14 +2191,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         if let Some(SubregionOrigin::CompareImplMethodObligation {
             span,
-            item_name,
             impl_item_def_id,
             trait_item_def_id,
         }) = origin
         {
             return self.report_extra_impl_obligation(
                 span,
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
                 &format!("`{}: {}`", bound_kind, sub),
@@ -2530,7 +2529,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             infer::MiscVariable(_) => String::new(),
             infer::PatternRegion(_) => " for pattern".to_string(),
             infer::AddrOfRegion(_) => " for borrow expression".to_string(),
-            infer::Autoref(_, _) => " for autoref".to_string(),
+            infer::Autoref(_) => " for autoref".to_string(),
             infer::Coercion(_) => " for automatic coercion".to_string(),
             infer::LateBoundRegion(_, br, infer::FnCall) => {
                 format!(" for lifetime parameter {}in function call", br_string(br))
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 0878f8550da..eb1c80ecb01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -3,8 +3,6 @@
 use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
-use rustc_hir::intravisit::Visitor;
-use rustc_hir::FnRetTy;
 use rustc_middle::ty;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -48,19 +46,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             return None; // inapplicable
         };
 
+        // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
+        // and can steer users down the wrong path.
+        if *named == ty::ReStatic {
+            return None;
+        }
+
         debug!("try_report_named_anon_conflict: named = {:?}", named);
         debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
         debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
 
-        let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
-            anon_param_info.param,
-            anon_param_info.param_ty,
-            anon_param_info.param_ty_span,
-            anon_param_info.bound_region,
-            anon_param_info.is_first,
-            region_info.def_id,
-            region_info.is_impl_item,
-        );
+        let param = anon_param_info.param;
+        let new_ty = anon_param_info.param_ty;
+        let new_ty_span = anon_param_info.param_ty_span;
+        let br = anon_param_info.bound_region;
+        let is_first = anon_param_info.is_first;
+        let scope_def_id = region_info.def_id;
+        let is_impl_item = region_info.is_impl_item;
+
         match br {
             ty::BrAnon(_) => {}
             _ => {
@@ -75,26 +78,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             return None;
         }
 
-        if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
-            if self.is_self_anon(is_first, scope_def_id) {
-                return None;
-            }
-
-            if let FnRetTy::Return(ty) = &fndecl.output {
-                let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir());
-                v.visit_ty(ty);
-
-                debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
-                if sub == &ty::ReStatic
-                    && v.0.into_iter().any(|t| t.span.desugaring_kind().is_none())
-                {
-                    // If the failure is due to a `'static` requirement coming from a `dyn` or
-                    // `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
-                    // better in `static_impl_trait`.
-                    debug!("try_report_named_anon_conflict: impl Trait + 'static");
-                    return None;
-                }
-            }
+        if find_anon_type(self.tcx(), anon, &br).is_some()
+            && self.is_self_anon(is_first, scope_def_id)
+        {
+            return None;
         }
 
         let (error_var, span_label_var) = match param.pat.simple_ident() {
@@ -114,16 +101,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         );
 
         diag.span_label(span, format!("lifetime `{}` required", named));
-        // Suggesting `'static` is nearly always incorrect, and can steer users
-        // down the wrong path.
-        if *named != ty::ReStatic {
-            diag.span_suggestion(
-                new_ty_span,
-                &format!("add explicit lifetime `{}` to {}", named, span_label_var),
-                new_ty.to_string(),
-                Applicability::Unspecified,
-            );
-        }
+        diag.span_suggestion(
+            new_ty_span,
+            &format!("add explicit lifetime `{}` to {}", named, span_label_var),
+            new_ty.to_string(),
+            Applicability::Unspecified,
+        );
 
         Some(diag)
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index b9e7ee12bc8..cfa79213c80 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -54,12 +54,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         {
             if let SubregionOrigin::CompareImplTypeObligation {
                 span,
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
             } = origin
             {
-                self.emit_associated_type_err(span, item_name, impl_item_def_id, trait_item_def_id);
+                self.emit_associated_type_err(
+                    span,
+                    self.infcx.tcx.item_name(impl_item_def_id),
+                    impl_item_def_id,
+                    trait_item_def_id,
+                );
                 return Some(ErrorReported);
             }
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 167a8893a11..6600c18351f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -330,30 +330,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 err
             }
-            infer::CompareImplMethodObligation {
-                span,
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            } => self.report_extra_impl_obligation(
-                span,
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-                &format!("`{}: {}`", sup, sub),
-            ),
-            infer::CompareImplTypeObligation {
-                span,
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-            } => self.report_extra_impl_obligation(
-                span,
-                item_name,
-                impl_item_def_id,
-                trait_item_def_id,
-                &format!("`{}: {}`", sup, sub),
-            ),
+            infer::CompareImplMethodObligation { span, impl_item_def_id, trait_item_def_id } => {
+                self.report_extra_impl_obligation(
+                    span,
+                    impl_item_def_id,
+                    trait_item_def_id,
+                    &format!("`{}: {}`", sup, sub),
+                )
+            }
+            infer::CompareImplTypeObligation { span, impl_item_def_id, trait_item_def_id } => self
+                .report_extra_impl_obligation(
+                    span,
+                    impl_item_def_id,
+                    trait_item_def_id,
+                    &format!("`{}: {}`", sup, sub),
+                ),
         }
     }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 9dae978dcde..b874947cc69 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -419,21 +419,11 @@ pub enum SubregionOrigin<'tcx> {
 
     /// Comparing the signature and requirements of an impl method against
     /// the containing trait.
-    CompareImplMethodObligation {
-        span: Span,
-        item_name: Symbol,
-        impl_item_def_id: DefId,
-        trait_item_def_id: DefId,
-    },
+    CompareImplMethodObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
 
     /// Comparing the signature and requirements of an impl associated type
     /// against the containing trait
-    CompareImplTypeObligation {
-        span: Span,
-        item_name: Symbol,
-        impl_item_def_id: DefId,
-        trait_item_def_id: DefId,
-    },
+    CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId },
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -469,7 +459,7 @@ pub enum RegionVariableOrigin {
     AddrOfRegion(Span),
 
     /// Regions created as part of an autoref of a method receiver
-    Autoref(Span, ty::AssocItem),
+    Autoref(Span),
 
     /// Regions created as part of an automatic coercion
     Coercion(Span),
@@ -1830,23 +1820,19 @@ impl<'tcx> SubregionOrigin<'tcx> {
             }
 
             traits::ObligationCauseCode::CompareImplMethodObligation {
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
             } => SubregionOrigin::CompareImplMethodObligation {
                 span: cause.span,
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
             },
 
             traits::ObligationCauseCode::CompareImplTypeObligation {
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
             } => SubregionOrigin::CompareImplTypeObligation {
                 span: cause.span,
-                item_name,
                 impl_item_def_id,
                 trait_item_def_id,
             },
@@ -1862,7 +1848,7 @@ impl RegionVariableOrigin {
             MiscVariable(a)
             | PatternRegion(a)
             | AddrOfRegion(a)
-            | Autoref(a, _)
+            | Autoref(a)
             | Coercion(a)
             | EarlyBoundRegion(a, ..)
             | LateBoundRegion(a, ..)
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index 9e04773c5fa..3947282aa62 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -99,7 +99,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
     /// function. We can then add implied bounds and the like from the
     /// closure arguments into the environment -- these should only
     /// apply in the closure body, so once we exit, we invoke
-    /// `pop_snapshot_post_closure` to remove them.
+    /// `pop_snapshot_post_typeck_child` to remove them.
     ///
     /// Example:
     ///
@@ -129,12 +129,12 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
     /// seems like it'd be readily fixed if we wanted. There are
     /// similar leaks around givens that seem equally suspicious, to
     /// be honest. --nmatsakis
-    pub fn push_snapshot_pre_closure(&self) -> usize {
+    pub fn push_snapshot_pre_typeck_child(&self) -> usize {
         self.region_bound_pairs_accum.len()
     }
 
-    /// See `push_snapshot_pre_closure`.
-    pub fn pop_snapshot_post_closure(&mut self, len: usize) {
+    /// See `push_snapshot_pre_typeck_child`.
+    pub fn pop_snapshot_post_typeck_child(&mut self, len: usize) {
         self.region_bound_pairs_accum.truncate(len);
     }
 
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index dce4a87b041..152a395c871 100644
--- a/compiler/rustc_infer/src/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
@@ -46,30 +46,25 @@ pub trait TraitEngine<'tcx>: 'tcx {
         obligation: PredicateObligation<'tcx>,
     );
 
-    fn select_all_or_error(
-        &mut self,
-        infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
+    fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>>;
 
     fn select_all_with_constness_or_error(
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
         _constness: hir::Constness,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    ) -> Vec<FulfillmentError<'tcx>> {
         self.select_all_or_error(infcx)
     }
 
-    fn select_where_possible(
-        &mut self,
-        infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
+    fn select_where_possible(&mut self, infcx: &InferCtxt<'_, 'tcx>)
+    -> Vec<FulfillmentError<'tcx>>;
 
     // FIXME(fee1-dead) this should not provide a default body for chalk as chalk should be updated
     fn select_with_constness_where_possible(
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
         _constness: hir::Constness,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    ) -> Vec<FulfillmentError<'tcx>> {
         self.select_where_possible(infcx)
     }
 
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 9dbfa3a850b..c1f302e665d 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -6,7 +6,6 @@ use rustc_errors::{struct_span_err, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::symbol::Symbol;
 use rustc_span::{MultiSpan, Span};
 use std::fmt;
 use std::iter;
@@ -15,8 +14,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_extra_impl_obligation(
         &self,
         error_span: Span,
-        item_name: Symbol,
-        _impl_item_def_id: DefId,
+        impl_item_def_id: DefId,
         trait_item_def_id: DefId,
         requirement: &dyn fmt::Display,
     ) -> DiagnosticBuilder<'tcx> {
@@ -27,6 +25,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) {
             let span = self.tcx.sess.source_map().guess_head_span(trait_item_span);
+            let item_name = self.tcx.item_name(impl_item_def_id);
             err.span_label(span, format!("definition of `{}` from trait", item_name));
         }
 
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index c839f824d1c..92f74af4eb3 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -5,6 +5,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
 use rustc_span::symbol::Ident;
+use rustc_span::Span;
 
 pub fn anonymize_predicate<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -97,6 +98,22 @@ pub fn elaborate_predicates<'tcx>(
     elaborate_obligations(tcx, obligations)
 }
 
+pub fn elaborate_predicates_with_span<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    predicates: impl Iterator<Item = (ty::Predicate<'tcx>, Span)>,
+) -> Elaborator<'tcx> {
+    let obligations = predicates
+        .map(|(predicate, span)| {
+            predicate_obligation(
+                predicate,
+                ty::ParamEnv::empty(),
+                ObligationCause::dummy_with_span(span),
+            )
+        })
+        .collect();
+    elaborate_obligations(tcx, obligations)
+}
+
 pub fn elaborate_obligations<'tcx>(
     tcx: TyCtxt<'tcx>,
     mut obligations: Vec<PredicateObligation<'tcx>>,
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 7a6a643e3d0..2904b3f5b70 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -36,6 +36,7 @@ pub struct Compiler {
     pub(crate) input_path: Option<PathBuf>,
     pub(crate) output_dir: Option<PathBuf>,
     pub(crate) output_file: Option<PathBuf>,
+    pub(crate) temps_dir: Option<PathBuf>,
     pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
     pub(crate) override_queries:
         Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>,
@@ -57,6 +58,9 @@ impl Compiler {
     pub fn output_file(&self) -> &Option<PathBuf> {
         &self.output_file
     }
+    pub fn temps_dir(&self) -> &Option<PathBuf> {
+        &self.temps_dir
+    }
     pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
         &self.register_lints
     }
@@ -65,7 +69,14 @@ impl Compiler {
         sess: &Session,
         attrs: &[ast::Attribute],
     ) -> OutputFilenames {
-        util::build_output_filenames(&self.input, &self.output_dir, &self.output_file, attrs, sess)
+        util::build_output_filenames(
+            &self.input,
+            &self.output_dir,
+            &self.output_file,
+            &self.temps_dir,
+            attrs,
+            sess,
+        )
     }
 }
 
@@ -186,6 +197,8 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
         );
     }
 
+    let temps_dir = sess.opts.debugging_opts.temps_dir.as_ref().map(|o| PathBuf::from(&o));
+
     let compiler = Compiler {
         sess,
         codegen_backend,
@@ -193,6 +206,7 @@ pub fn create_compiler_and_run<R>(config: Config, f: impl FnOnce(&Compiler) -> R
         input_path: config.input_path,
         output_dir: config.output_dir,
         output_file: config.output_file,
+        temps_dir,
         register_lints: config.register_lints,
         override_queries: config.override_queries,
     };
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 3f6e879e6e4..b073ee9682f 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -692,6 +692,7 @@ pub fn prepare_outputs(
         &compiler.input,
         &compiler.output_dir,
         &compiler.output_file,
+        &compiler.temps_dir,
         &krate.attrs,
         sess,
     );
@@ -722,6 +723,13 @@ pub fn prepare_outputs(
         }
     }
 
+    if let Some(ref dir) = compiler.temps_dir {
+        if fs::create_dir_all(dir).is_err() {
+            sess.err("failed to find or create the directory specified by `--temps-dir`");
+            return Err(ErrorReported);
+        }
+    }
+
     write_out_deps(sess, boxed_resolver, &outputs, &output_paths);
 
     let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo)
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 2d3cb52f5fd..6b5c79a2d5d 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -551,6 +551,7 @@ fn test_codegen_options_tracking_hash() {
     untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
     untracked!(rpath, true);
     untracked!(save_temps, true);
+    untracked!(strip, Strip::Debuginfo);
 
     macro_rules! tracked {
         ($name: ident, $non_default_value: expr) => {
@@ -635,6 +636,7 @@ fn test_debugging_options_tracking_hash() {
 
     // Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
     // This list is in alphabetical order.
+    untracked!(assert_incr_state, Some(String::from("loaded")));
     untracked!(ast_json, true);
     untracked!(ast_json_noexpand, true);
     untracked!(borrowck, String::from("other"));
@@ -684,7 +686,7 @@ fn test_debugging_options_tracking_hash() {
     untracked!(self_profile_events, Some(vec![String::new()]));
     untracked!(span_debug, true);
     untracked!(span_free_formats, true);
-    untracked!(strip, Strip::Debuginfo);
+    untracked!(temps_dir, Some(String::from("abc")));
     untracked!(terminal_width, Some(80));
     untracked!(threads, 99);
     untracked!(time, true);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 94650237873..04e183a9ba5 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -604,6 +604,7 @@ pub fn build_output_filenames(
     input: &Input,
     odir: &Option<PathBuf>,
     ofile: &Option<PathBuf>,
+    temps_dir: &Option<PathBuf>,
     attrs: &[ast::Attribute],
     sess: &Session,
 ) -> OutputFilenames {
@@ -626,6 +627,7 @@ pub fn build_output_filenames(
                 dirpath,
                 stem,
                 None,
+                temps_dir.clone(),
                 sess.opts.cg.extra_filename.clone(),
                 sess.opts.output_types.clone(),
             )
@@ -654,6 +656,7 @@ pub fn build_output_filenames(
                 out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
                 out_file.file_stem().unwrap_or_default().to_str().unwrap().to_string(),
                 ofile,
+                temps_dir.clone(),
                 sess.opts.cg.extra_filename.clone(),
                 sess.opts.output_types.clone(),
             )
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 6548cdc0fdc..f2e4e70a197 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -32,8 +32,7 @@ use rustc_ast_pretty::pprust::{self, expr_to_string};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
-use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType};
-use rustc_feature::{GateIssue, Stability};
+use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
@@ -959,7 +958,7 @@ impl EarlyLintPass for AnonymousParameters {
 pub struct DeprecatedAttr {
     // This is not free to compute, so we want to keep it around, rather than
     // compute it for every attribute.
-    depr_attrs: Vec<&'static (Symbol, AttributeType, AttributeTemplate, AttributeGate)>,
+    depr_attrs: Vec<&'static BuiltinAttribute>,
 }
 
 impl_lint_pass!(DeprecatedAttr => []);
@@ -990,14 +989,14 @@ fn lint_deprecated_attr(
 
 impl EarlyLintPass for DeprecatedAttr {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
-        for &&(n, _, _, ref g) in &self.depr_attrs {
-            if attr.ident().map(|ident| ident.name) == Some(n) {
+        for BuiltinAttribute { name, gate, .. } in &self.depr_attrs {
+            if attr.ident().map(|ident| ident.name) == Some(*name) {
                 if let &AttributeGate::Gated(
                     Stability::Deprecated(link, suggestion),
                     name,
                     reason,
                     _,
-                ) = g
+                ) = gate
                 {
                     let msg =
                         format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link);
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index f6514ddca9f..507b4421fa1 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -30,7 +30,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_order_by)]
 #![feature(iter_zip)]
 #![feature(never_type)]
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index ddbc3c59128..4f77db8a24d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -889,15 +889,17 @@ LLVMRustOptimizeWithNewPassManager(
       OptimizerLastEPCallbacks.push_back(
         [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
           MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
-          MPM.addPass(ModuleAddressSanitizerPass(
-              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
 #if LLVM_VERSION_GE(14, 0)
-          AddressSanitizerOptions opts(/*CompileKernel=*/false,
-                                       SanitizerOptions->SanitizeAddressRecover,
-                                       /*UseAfterScope=*/true,
-                                       AsanDetectStackUseAfterReturnMode::Runtime);
-          MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(opts)));
+          AddressSanitizerOptions opts = AddressSanitizerOptions{
+            /*CompileKernel=*/false,
+            SanitizerOptions->SanitizeAddressRecover,
+            /*UseAfterScope=*/true,
+            AsanDetectStackUseAfterReturnMode::Runtime,
+          };
+          MPM.addPass(ModuleAddressSanitizerPass(opts));
 #else
+          MPM.addPass(ModuleAddressSanitizerPass(
+              /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
           MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
               /*UseAfterScope=*/true)));
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 5e90aec003e..b2c7818a542 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1179,7 +1179,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                             let ctor_res =
                                 Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
                             let mut vis = self.get_visibility(ctor_def_id.index);
-                            if ctor_def_id == def_id && vis == ty::Visibility::Public {
+                            if ctor_def_id == def_id && vis.is_public() {
                                 // For non-exhaustive variants lower the constructor visibility to
                                 // within the crate. We only need this for fictive constructors,
                                 // for other constructors correct visibilities
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7ea004b16f2..eeb0a77adc0 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -318,7 +318,7 @@ pub fn provide(providers: &mut Providers) {
             }
 
             let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
-                if child.vis != ty::Visibility::Public {
+                if !child.vis.is_public() {
                     return;
                 }
 
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 0dbef66ac37..d46829c2cee 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -797,6 +797,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
         | DefKind::ConstParam
         | DefKind::LifetimeParam
         | DefKind::AnonConst
+        | DefKind::InlineConst
         | DefKind::GlobalAsm
         | DefKind::Closure
         | DefKind::Generator
@@ -832,6 +833,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
         DefKind::Use
         | DefKind::LifetimeParam
         | DefKind::AnonConst
+        | DefKind::InlineConst
         | DefKind::GlobalAsm
         | DefKind::Closure
         | DefKind::Generator
@@ -856,9 +858,11 @@ fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
             (true, mir_opt_base)
         }
         // Constants
-        DefKind::AnonConst | DefKind::AssocConst | DefKind::Static | DefKind::Const => {
-            (true, false)
-        }
+        DefKind::AnonConst
+        | DefKind::InlineConst
+        | DefKind::AssocConst
+        | DefKind::Static
+        | DefKind::Const => (true, false),
         // Full-fledged functions
         DefKind::AssocFn | DefKind::Fn => {
             let generics = tcx.generics_of(def_id);
@@ -914,6 +918,7 @@ fn should_encode_variances(def_kind: DefKind) -> bool {
         | DefKind::Use
         | DefKind::LifetimeParam
         | DefKind::AnonConst
+        | DefKind::InlineConst
         | DefKind::GlobalAsm
         | DefKind::Closure
         | DefKind::Generator
@@ -939,6 +944,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
         | DefKind::AssocFn
         | DefKind::AssocConst
         | DefKind::AnonConst
+        | DefKind::InlineConst
         | DefKind::OpaqueTy
         | DefKind::Impl
         | DefKind::Field
@@ -2187,5 +2193,8 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
     result[header + 2] = (pos >> 8) as u8;
     result[header + 3] = (pos >> 0) as u8;
 
+    // Record metadata size for self-profiling
+    tcx.prof.artifact_size("crate_metadata", "crate_metadata", result.len() as u64);
+
     EncodedMetadata { raw_data: result }
 }
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index 420c500a7de..2bcc2a4f7cf 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -1,10 +1,5 @@
 /// This declares a list of types which can be allocated by `Arena`.
 ///
-/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
-/// This is faster and more memory efficient if there's only a few allocations of the type.
-/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
-/// faster and more memory efficient if there is lots of allocations.
-///
 /// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]` where `T` is the type
 /// listed. These impls will appear in the implement_ty_decoder! macro.
 #[macro_export]
@@ -37,7 +32,7 @@ macro_rules! arena_types {
             [decode] code_region: rustc_middle::mir::coverage::CodeRegion,
             [] const_allocs: rustc_middle::mir::interpret::Allocation,
             // Required for the incremental on-disk cache
-            [few] mir_keys: rustc_hir::def_id::DefIdSet,
+            [] mir_keys: rustc_hir::def_id::DefIdSet,
             [] region_scope_tree: rustc_middle::middle::region::ScopeTree,
             [] dropck_outlives:
                 rustc_middle::infer::canonical::Canonical<'tcx,
@@ -77,10 +72,10 @@ macro_rules! arena_types {
                 rustc_middle::infer::canonical::Canonical<'tcx,
                     rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
                 >,
-            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
-            [few] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels,
-            [few] foreign_module: rustc_session::cstore::ForeignModule,
-            [few] foreign_modules: Vec<rustc_session::cstore::ForeignModule>,
+            [] all_traits: Vec<rustc_hir::def_id::DefId>,
+            [] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels,
+            [] foreign_module: rustc_session::cstore::ForeignModule,
+            [] foreign_modules: Vec<rustc_session::cstore::ForeignModule>,
             [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
             [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation,
             [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 8f52e16c2eb..d9d0781b37a 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -266,7 +266,15 @@ impl<'hir> Map<'hir> {
                 };
                 DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data))
             }
-            Node::AnonConst(_) => DefKind::AnonConst,
+            Node::AnonConst(_) => {
+                let inline = match self.find(self.get_parent_node(hir_id)) {
+                    Some(Node::Expr(&Expr {
+                        kind: ExprKind::ConstBlock(ref anon_const), ..
+                    })) if anon_const.hir_id == hir_id => true,
+                    _ => false,
+                };
+                if inline { DefKind::InlineConst } else { DefKind::AnonConst }
+            }
             Node::Field(_) => DefKind::Field,
             Node::Expr(expr) => match expr.kind {
                 ExprKind::Closure(.., None) => DefKind::Closure,
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 1eba2994ed3..0e70d49ef49 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -248,8 +248,12 @@ pub fn struct_lint_level<'s, 'd>(
             (Level::Warn, None) => sess.struct_warn(""),
             (Level::ForceWarn, Some(span)) => sess.struct_span_force_warn(span, ""),
             (Level::ForceWarn, None) => sess.struct_force_warn(""),
-            (Level::Deny | Level::Forbid, Some(span)) => sess.struct_span_err(span, ""),
-            (Level::Deny | Level::Forbid, None) => sess.struct_err(""),
+            (Level::Deny | Level::Forbid, Some(span)) => {
+                let mut builder = sess.diagnostic().struct_err_lint("");
+                builder.set_span(span);
+                builder
+            }
+            (Level::Deny | Level::Forbid, None) => sess.diagnostic().struct_err_lint(""),
         };
 
         // If this code originates in a foreign macro, aka something that this crate
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 8e363cfbff5..8e1b887f87d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -958,7 +958,7 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn Write) -> io::Res
             write!(w, "static {}", if tcx.is_mutable_static(def_id) { "mut " } else { "" })?
         }
         (_, _) if is_function => write!(w, "fn ")?,
-        (DefKind::AnonConst, _) => {} // things like anon const, not an item
+        (DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item
         _ => bug!("Unexpected def kind {:?}", kind),
     }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 06041bbb02d..9a58009a173 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -797,7 +797,7 @@ rustc_queries! {
     /// additional requirements that the closure's creator must verify.
     query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> {
         desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
-        cache_on_disk_if(tcx) { tcx.is_closure(key.to_def_id()) }
+        cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
     }
     query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> {
         desc {
@@ -822,6 +822,14 @@ rustc_queries! {
         desc { "check for overlap between inherent impls defined in this crate" }
     }
 
+    /// Checks whether all impls in the crate pass the overlap check, returning
+    /// which impls fail it. If all impls are correct, the returned slice is empty.
+    query orphan_check_crate(_: ()) -> &'tcx [LocalDefId] {
+        desc {
+            "checking whether the immpl in the this crate follow the orphan rules",
+        }
+    }
+
     /// Check whether the function has any recursion that could cause the inliner to trigger
     /// a cycle. Returns the call stack causing the cycle. The call stack does not contain the
     /// current function, just all intermediate functions.
@@ -1056,11 +1064,6 @@ rustc_queries! {
     }
 
     /// Return all `impl` blocks in the current crate.
-    ///
-    /// To allow caching this between crates, you must pass in [`LOCAL_CRATE`] as the crate number.
-    /// Passing in any other crate will cause an ICE.
-    ///
-    /// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE
     query all_local_trait_impls(_: ()) -> &'tcx BTreeMap<DefId, Vec<LocalDefId>> {
         desc { "local trait impls" }
     }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 6570d8e1567..245df636107 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -267,14 +267,12 @@ pub enum ObligationCauseCode<'tcx> {
 
     /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplMethodObligation {
-        item_name: Symbol,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
 
     /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplTypeObligation {
-        item_name: Symbol,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
     },
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 869b2ab9dbc..27e22ccac02 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -1,7 +1,9 @@
 use crate::mir::interpret::ConstValue;
 use crate::mir::interpret::{LitToConstInput, Scalar};
-use crate::ty::{self, Ty, TyCtxt};
-use crate::ty::{ParamEnv, ParamEnvAnd};
+use crate::ty::{
+    self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
+    TyCtxt, TypeFoldable,
+};
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -54,6 +56,24 @@ impl<'tcx> Const<'tcx> {
 
         let ty = tcx.type_of(def.def_id_for_type_of());
 
+        match Self::try_eval_lit_or_param(tcx, ty, expr) {
+            Some(v) => v,
+            None => tcx.mk_const(ty::Const {
+                val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                    def: def.to_global(),
+                    substs_: None,
+                    promoted: None,
+                }),
+                ty,
+            }),
+        }
+    }
+
+    fn try_eval_lit_or_param(
+        tcx: TyCtxt<'tcx>,
+        ty: Ty<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
+    ) -> Option<&'tcx Self> {
         let lit_input = match expr.kind {
             hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
             hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
@@ -69,7 +89,7 @@ impl<'tcx> Const<'tcx> {
             // If an error occurred, ignore that it's a literal and leave reporting the error up to
             // mir.
             if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
-                return c;
+                return Some(c);
             } else {
                 tcx.sess.delay_span_bug(expr.span, "Const::from_anon_const: couldn't lit_to_const");
             }
@@ -85,7 +105,7 @@ impl<'tcx> Const<'tcx> {
         };
 
         use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
-        let val = match expr.kind {
+        match expr.kind {
             ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
                 // Find the name and index of the const parameter by indexing the generics of
                 // the parent item and construct a `ParamConst`.
@@ -95,16 +115,53 @@ impl<'tcx> Const<'tcx> {
                 let generics = tcx.generics_of(item_def_id.to_def_id());
                 let index = generics.param_def_id_to_index[&def_id];
                 let name = tcx.hir().name(hir_id);
-                ty::ConstKind::Param(ty::ParamConst::new(index, name))
+                Some(tcx.mk_const(ty::Const {
+                    val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
+                    ty,
+                }))
             }
-            _ => ty::ConstKind::Unevaluated(ty::Unevaluated {
-                def: def.to_global(),
-                substs_: None,
-                promoted: None,
-            }),
+            _ => None,
+        }
+    }
+
+    pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
+        debug!("Const::from_inline_const(def_id={:?})", def_id);
+
+        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+
+        let body_id = match tcx.hir().get(hir_id) {
+            hir::Node::AnonConst(ac) => ac.body,
+            _ => span_bug!(
+                tcx.def_span(def_id.to_def_id()),
+                "from_inline_const can only process anonymous constants"
+            ),
         };
 
-        tcx.mk_const(ty::Const { val, ty })
+        let expr = &tcx.hir().body(body_id).value;
+
+        let ty = tcx.typeck(def_id).node_type(hir_id);
+
+        let ret = match Self::try_eval_lit_or_param(tcx, ty, expr) {
+            Some(v) => v,
+            None => {
+                let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
+                let parent_substs =
+                    tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
+                let substs =
+                    InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
+                        .substs;
+                tcx.mk_const(ty::Const {
+                    val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                        def: ty::WithOptConstParam::unknown(def_id).to_global(),
+                        substs_: Some(substs),
+                        promoted: None,
+                    }),
+                    ty,
+                })
+            }
+        };
+        debug_assert!(!ret.has_free_regions(tcx));
+        ret
     }
 
     /// Interns the given value as a constant.
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 2bd9415171d..b14a6989265 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -42,6 +42,7 @@ pub enum TypeError<'tcx> {
     TupleSize(ExpectedFound<usize>),
     FixedArraySize(ExpectedFound<u64>),
     ArgCount,
+    FieldMisMatch(Symbol, Symbol),
 
     RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
     RegionsInsufficientlyPolymorphic(BoundRegionKind, Region<'tcx>),
@@ -134,6 +135,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                 pluralize!(values.found)
             ),
             ArgCount => write!(f, "incorrect number of function parameters"),
+            FieldMisMatch(adt, field) => write!(f, "field type mismatch: {}.{}", adt, field),
             RegionsDoesNotOutlive(..) => write!(f, "lifetime mismatch"),
             RegionsInsufficientlyPolymorphic(br, _) => write!(
                 f,
@@ -224,6 +226,7 @@ impl<'tcx> TypeError<'tcx> {
             | ArgumentMutability(_)
             | TupleSize(_)
             | ArgCount
+            | FieldMisMatch(..)
             | RegionsDoesNotOutlive(..)
             | RegionsInsufficientlyPolymorphic(..)
             | RegionsOverlyPolymorphic(..)
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index cf47da157d1..673733faa76 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -74,9 +74,10 @@ pub use self::sty::{
     Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind,
     CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion,
     ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig,
-    GeneratorSubsts, GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection,
-    PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind,
-    RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo, VarianceDiagMutKind,
+    GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, InlineConstSubstsParts, ParamConst,
+    ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig,
+    PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut,
+    UpvarSubsts, VarianceDiagInfo, VarianceDiagMutKind,
 };
 pub use self::trait_def::TraitDef;
 
@@ -332,6 +333,10 @@ impl Visibility {
             Visibility::Invisible => false,
         }
     }
+
+    pub fn is_public(self) -> bool {
+        matches!(self, Visibility::Public)
+    }
 }
 
 /// The crate variances map is computed during typeck and contains the
@@ -1927,7 +1932,8 @@ impl<'tcx> TyCtxt<'tcx> {
                 | DefKind::Static
                 | DefKind::AssocConst
                 | DefKind::Ctor(..)
-                | DefKind::AnonConst => self.mir_for_ctfe_opt_const_arg(def),
+                | DefKind::AnonConst
+                | DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def),
                 // If the caller wants `mir_for_ctfe` of a function they should not be using
                 // `instance_mir`, so we'll assume const fn also wants the optimized version.
                 _ => {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 742005e245f..5d9e7aaf72f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2404,7 +2404,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
     // Iterate external crate defs but be mindful about visibility
     while let Some(def) = queue.pop() {
         for child in tcx.item_children(def).iter() {
-            if child.vis != ty::Visibility::Public {
+            if !child.vis.is_public() {
                 continue;
             }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index d6069395474..0f8e80806e3 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -602,6 +602,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             TupleSize(x) => TupleSize(x),
             FixedArraySize(x) => FixedArraySize(x),
             ArgCount => ArgCount,
+            FieldMisMatch(x, y) => FieldMisMatch(x, y),
             RegionsDoesNotOutlive(a, b) => {
                 return tcx.lift((a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b));
             }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 874de3366d7..610f9bd8f82 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -704,6 +704,66 @@ impl<'tcx> UpvarSubsts<'tcx> {
     }
 }
 
+/// An inline const is modeled like
+///
+///     const InlineConst<'l0...'li, T0...Tj, R>: R;
+///
+/// where:
+///
+/// - 'l0...'li and T0...Tj are the generic parameters
+///   inherited from the item that defined the inline const,
+/// - R represents the type of the constant.
+///
+/// When the inline const is instantiated, `R` is substituted as the actual inferred
+/// type of the constant. The reason that `R` is represented as an extra type parameter
+/// is the same reason that [`ClosureSubsts`] have `CS` and `U` as type parameters:
+/// inline const can reference lifetimes that are internal to the creating function.
+#[derive(Copy, Clone, Debug, TypeFoldable)]
+pub struct InlineConstSubsts<'tcx> {
+    /// Generic parameters from the enclosing item,
+    /// concatenated with the inferred type of the constant.
+    pub substs: SubstsRef<'tcx>,
+}
+
+/// Struct returned by `split()`.
+pub struct InlineConstSubstsParts<'tcx, T> {
+    pub parent_substs: &'tcx [GenericArg<'tcx>],
+    pub ty: T,
+}
+
+impl<'tcx> InlineConstSubsts<'tcx> {
+    /// Construct `InlineConstSubsts` from `InlineConstSubstsParts`.
+    pub fn new(
+        tcx: TyCtxt<'tcx>,
+        parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
+    ) -> InlineConstSubsts<'tcx> {
+        InlineConstSubsts {
+            substs: tcx.mk_substs(
+                parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
+            ),
+        }
+    }
+
+    /// Divides the inline const substs into their respective components.
+    /// The ordering assumed here must match that used by `InlineConstSubsts::new` above.
+    fn split(self) -> InlineConstSubstsParts<'tcx, GenericArg<'tcx>> {
+        match self.substs[..] {
+            [ref parent_substs @ .., ty] => InlineConstSubstsParts { parent_substs, ty },
+            _ => bug!("inline const substs missing synthetics"),
+        }
+    }
+
+    /// Returns the substitutions of the inline const's parent.
+    pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
+        self.split().parent_substs
+    }
+
+    /// Returns the type of this inline const.
+    pub fn ty(self) -> Ty<'tcx> {
+        self.split().ty.expect_ty()
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable, TypeFoldable)]
 pub enum ExistentialPredicate<'tcx> {
@@ -2007,7 +2067,9 @@ impl<'tcx> TyS<'tcx> {
     ) -> Option<Discr<'tcx>> {
         match self.kind() {
             TyKind::Adt(adt, _) if adt.variants.is_empty() => {
-                bug!("discriminant_for_variant called on zero variant enum");
+                // This can actually happen during CTFE, see
+                // https://github.com/rust-lang/rust/issues/89765.
+                None
             }
             TyKind::Adt(adt, _) if adt.is_enum() => {
                 Some(adt.discriminant_for_variant(tcx, variant_index))
@@ -2026,10 +2088,10 @@ impl<'tcx> TyS<'tcx> {
             ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
 
             ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => {
-                let assoc_items =
-                    tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
-                let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
-                tcx.mk_projection(discriminant_def_id, tcx.mk_substs([self.into()].iter()))
+                let assoc_items = tcx.associated_item_def_ids(
+                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
+                );
+                tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()]))
             }
 
             ty::Bool
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 2438d1a1602..73a8e18949d 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -3,7 +3,7 @@
 use crate::mir;
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
+use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
 use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
 
 use rustc_hir::def_id::DefId;
@@ -204,6 +204,14 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
         GeneratorSubsts { substs: self }
     }
 
+    /// Interpret these substitutions as the substitutions of an inline const.
+    /// Inline const substitutions have a particular structure controlled by the
+    /// compiler that encodes information like the inferred type;
+    /// see `ty::InlineConstSubsts` struct for more comments.
+    pub fn as_inline_const(&'tcx self) -> InlineConstSubsts<'tcx> {
+        InlineConstSubsts { substs: self }
+    }
+
     /// Creates an `InternalSubsts` that maps each generic parameter to itself.
     pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
         Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param))
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 2c884813d23..6e7acb244d1 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -325,9 +325,9 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let ty = self.type_of(adt_did);
         let (did, constness) = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
-            if let Some(item) = self.associated_items(impl_did).in_definition_order().next() {
+            if let Some(item_id) = self.associated_item_def_ids(impl_did).first() {
                 if validate(self, impl_did).is_ok() {
-                    return Some((item.def_id, self.impl_constness(impl_did)));
+                    return Some((*item_id, self.impl_constness(impl_did)));
                 }
             }
             None
@@ -423,6 +423,15 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(self.def_kind(def_id), DefKind::Closure | DefKind::Generator)
     }
 
+    /// Returns `true` if `def_id` refers to a definition that does not have its own
+    /// type-checking context, i.e. closure, generator or inline const.
+    pub fn is_typeck_child(self, def_id: DefId) -> bool {
+        matches!(
+            self.def_kind(def_id),
+            DefKind::Closure | DefKind::Generator | DefKind::InlineConst
+        )
+    }
+
     /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
     pub fn is_trait(self, def_id: DefId) -> bool {
         self.def_kind(def_id) == DefKind::Trait
@@ -440,16 +449,19 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(self.def_kind(def_id), DefKind::Ctor(..))
     }
 
-    /// Given the def-ID of a fn or closure, returns the def-ID of
-    /// the innermost fn item that the closure is contained within.
-    /// This is a significant `DefId` because, when we do
-    /// type-checking, we type-check this fn item and all of its
-    /// (transitive) closures together. Therefore, when we fetch the
+    /// Given the `DefId`, returns the `DefId` of the innermost item that
+    /// has its own type-checking context or "inference enviornment".
+    ///
+    /// For example, a closure has its own `DefId`, but it is type-checked
+    /// with the containing item. Similarly, an inline const block has its
+    /// own `DefId` but it is type-checked together with the containing item.
+    ///
+    /// Therefore, when we fetch the
     /// `typeck` the closure, for example, we really wind up
     /// fetching the `typeck` the enclosing fn item.
-    pub fn closure_base_def_id(self, def_id: DefId) -> DefId {
+    pub fn typeck_root_def_id(self, def_id: DefId) -> DefId {
         let mut def_id = def_id;
-        while self.is_closure(def_id) {
+        while self.is_typeck_child(def_id) {
             def_id = self.parent(def_id).unwrap_or_else(|| {
                 bug!("closure {:?} has no parent", def_id);
             });
diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs
index da857b0a403..08977049db0 100644
--- a/compiler/rustc_middle/src/util/common.rs
+++ b/compiler/rustc_middle/src/util/common.rs
@@ -34,7 +34,7 @@ where
     let rv = f();
     let duration = start.elapsed();
     let mut accu = accu.lock();
-    *accu = *accu + duration;
+    *accu += duration;
     rv
 }
 
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 4df073c40e2..6320d5d4749 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1762,8 +1762,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ) -> BlockAnd<()> {
         let expr_span = expr.span;
         let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span));
-        let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false);
         let wildcard = Pat::wildcard_from_ty(pat.ty);
+        let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false);
         let mut otherwise_candidate = Candidate::new(expr_place_builder.clone(), &wildcard, false);
         let fake_borrow_temps = self.lower_match_tree(
             block,
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 17296a95bc1..b4005ccd1cc 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -578,7 +578,7 @@ impl<'tcx> Cx<'tcx> {
 
             hir::ExprKind::ConstBlock(ref anon_const) => {
                 let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
-                let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
+                let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);
 
                 ExprKind::ConstBlock { value }
             }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index cb74ae4df2e..ce80214c875 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -544,7 +544,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             let (lit, neg) = match expr.kind {
                 hir::ExprKind::ConstBlock(ref anon_const) => {
                     let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
-                    let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
+                    let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);
                     if matches!(value.val, ConstKind::Param(_)) {
                         let span = self.tcx.hir().span(anon_const.hir_id);
                         self.errors.push(PatternError::ConstParamInPattern(span));
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index d959d2f7f6f..3ed434131b2 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -443,9 +443,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
     /// expands it.
     fn push(&mut self, row: PatStack<'p, 'tcx>) {
         if !row.is_empty() && row.head().is_or_pat() {
-            for row in row.expand_or_pat() {
-                self.patterns.push(row);
-            }
+            self.patterns.extend(row.expand_or_pat());
         } else {
             self.patterns.push(row);
         }
@@ -797,7 +795,7 @@ fn is_useful<'p, 'tcx>(
         return ret;
     }
 
-    assert!(rows.iter().all(|r| r.len() == v.len()));
+    debug_assert!(rows.iter().all(|r| r.len() == v.len()));
 
     let ty = v.head().ty();
     let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty);
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 7607ccc3aba..11856f6e047 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -604,7 +604,7 @@ where
         debug!("destructor_call_block({:?}, {:?})", self, succ);
         let tcx = self.tcx();
         let drop_trait = tcx.require_lang_item(LangItem::Drop, None);
-        let drop_fn = tcx.associated_items(drop_trait).in_definition_order().next().unwrap();
+        let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
         let ty = self.place_ty(self.place);
         let substs = tcx.mk_substs_trait(ty, &[]);
 
@@ -624,12 +624,7 @@ where
             )],
             terminator: Some(Terminator {
                 kind: TerminatorKind::Call {
-                    func: Operand::function_handle(
-                        tcx,
-                        drop_fn.def_id,
-                        substs,
-                        self.source_info.span,
-                    ),
+                    func: Operand::function_handle(tcx, drop_fn, substs, self.source_info.span),
                     args: vec![Operand::Move(Place::from(ref_place))],
                     destination: Some((unit_temp, succ)),
                     cleanup: unwind.into_option(),
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index f2ea5fedc62..f59aaa664f3 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -310,7 +310,6 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
 
     match self_ty.kind() {
         _ if is_copy => builder.copy_shim(),
-        ty::Array(ty, len) => builder.array_shim(dest, src, ty, len),
         ty::Closure(_, substs) => {
             builder.tuple_like_shim(dest, src, substs.as_closure().upvar_tys())
         }
@@ -459,154 +458,6 @@ impl CloneShimBuilder<'tcx> {
         );
     }
 
-    fn loop_header(
-        &mut self,
-        beg: Place<'tcx>,
-        end: Place<'tcx>,
-        loop_body: BasicBlock,
-        loop_end: BasicBlock,
-        is_cleanup: bool,
-    ) {
-        let tcx = self.tcx;
-
-        let cond = self.make_place(Mutability::Mut, tcx.types.bool);
-        let compute_cond = self.make_statement(StatementKind::Assign(Box::new((
-            cond,
-            Rvalue::BinaryOp(BinOp::Ne, Box::new((Operand::Copy(end), Operand::Copy(beg)))),
-        ))));
-
-        // `if end != beg { goto loop_body; } else { goto loop_end; }`
-        self.block(
-            vec![compute_cond],
-            TerminatorKind::if_(tcx, Operand::Move(cond), loop_body, loop_end),
-            is_cleanup,
-        );
-    }
-
-    fn make_usize(&self, value: u64) -> Box<Constant<'tcx>> {
-        Box::new(Constant {
-            span: self.span,
-            user_ty: None,
-            literal: ty::Const::from_usize(self.tcx, value).into(),
-        })
-    }
-
-    fn array_shim(
-        &mut self,
-        dest: Place<'tcx>,
-        src: Place<'tcx>,
-        ty: Ty<'tcx>,
-        len: &'tcx ty::Const<'tcx>,
-    ) {
-        let tcx = self.tcx;
-        let span = self.span;
-
-        let beg = self.local_decls.push(LocalDecl::new(tcx.types.usize, span));
-        let end = self.make_place(Mutability::Not, tcx.types.usize);
-
-        // BB #0
-        // `let mut beg = 0;`
-        // `let end = len;`
-        // `goto #1;`
-        let inits = vec![
-            self.make_statement(StatementKind::Assign(Box::new((
-                Place::from(beg),
-                Rvalue::Use(Operand::Constant(self.make_usize(0))),
-            )))),
-            self.make_statement(StatementKind::Assign(Box::new((
-                end,
-                Rvalue::Use(Operand::Constant(Box::new(Constant {
-                    span: self.span,
-                    user_ty: None,
-                    literal: len.into(),
-                }))),
-            )))),
-        ];
-        self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
-
-        // BB #1: loop {
-        //     BB #2;
-        //     BB #3;
-        // }
-        // BB #4;
-        self.loop_header(Place::from(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);
-
-        // BB #2
-        // `dest[i] = Clone::clone(src[beg])`;
-        // Goto #3 if ok, #5 if unwinding happens.
-        let dest_field = self.tcx.mk_place_index(dest, beg);
-        let src_field = self.tcx.mk_place_index(src, beg);
-        self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5));
-
-        // BB #3
-        // `beg = beg + 1;`
-        // `goto #1`;
-        let statements = vec![self.make_statement(StatementKind::Assign(Box::new((
-            Place::from(beg),
-            Rvalue::BinaryOp(
-                BinOp::Add,
-                Box::new((Operand::Copy(Place::from(beg)), Operand::Constant(self.make_usize(1)))),
-            ),
-        ))))];
-        self.block(statements, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
-
-        // BB #4
-        // `return dest;`
-        self.block(vec![], TerminatorKind::Return, false);
-
-        // BB #5 (cleanup)
-        // `let end = beg;`
-        // `let mut beg = 0;`
-        // goto #6;
-        let end = beg;
-        let beg = self.local_decls.push(LocalDecl::new(tcx.types.usize, span));
-        let init = self.make_statement(StatementKind::Assign(Box::new((
-            Place::from(beg),
-            Rvalue::Use(Operand::Constant(self.make_usize(0))),
-        ))));
-        self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
-
-        // BB #6 (cleanup): loop {
-        //     BB #7;
-        //     BB #8;
-        // }
-        // BB #9;
-        self.loop_header(
-            Place::from(beg),
-            Place::from(end),
-            BasicBlock::new(7),
-            BasicBlock::new(9),
-            true,
-        );
-
-        // BB #7 (cleanup)
-        // `drop(dest[beg])`;
-        self.block(
-            vec![],
-            TerminatorKind::Drop {
-                place: self.tcx.mk_place_index(dest, beg),
-                target: BasicBlock::new(8),
-                unwind: None,
-            },
-            true,
-        );
-
-        // BB #8 (cleanup)
-        // `beg = beg + 1;`
-        // `goto #6;`
-        let statement = self.make_statement(StatementKind::Assign(Box::new((
-            Place::from(beg),
-            Rvalue::BinaryOp(
-                BinOp::Add,
-                Box::new((Operand::Copy(Place::from(beg)), Operand::Constant(self.make_usize(1)))),
-            ),
-        ))));
-        self.block(vec![statement], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
-
-        // BB #9 (resume)
-        self.block(vec![], TerminatorKind::Resume, true);
-    }
-
     fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I)
     where
         I: Iterator<Item = Ty<'tcx>>,
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 7a7a56a034e..658c9028ca1 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -361,6 +361,17 @@ fn collect_and_partition_mono_items<'tcx>(
         )
     });
 
+    if tcx.prof.enabled() {
+        // Record CGU size estimates for self-profiling.
+        for cgu in codegen_units {
+            tcx.prof.artifact_size(
+                "codegen_unit_size_estimate",
+                &cgu.name().as_str()[..],
+                cgu.size_estimate() as u64,
+            );
+        }
+    }
+
     let mono_items: DefIdSet = items
         .iter()
         .filter_map(|mono_item| match *mono_item {
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index e6e4438b6d4..595080619da 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -167,6 +167,7 @@ fn mark_used_by_default_parameters<'tcx>(
         | DefKind::Use
         | DefKind::ForeignMod
         | DefKind::AnonConst
+        | DefKind::InlineConst
         | DefKind::OpaqueTy
         | DefKind::Field
         | DefKind::LifetimeParam
@@ -195,7 +196,7 @@ fn emit_unused_generic_params_error<'tcx>(
     generics: &'tcx ty::Generics,
     unused_parameters: &FiniteBitSet<u32>,
 ) {
-    let base_def_id = tcx.closure_base_def_id(def_id);
+    let base_def_id = tcx.typeck_root_def_id(def_id);
     if !tcx.get_attrs(base_def_id).iter().any(|a| a.has_name(sym::rustc_polymorphize_error)) {
         return;
     }
@@ -303,7 +304,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
                 ControlFlow::CONTINUE
             }
             ty::ConstKind::Unevaluated(uv)
-                if self.tcx.def_kind(uv.def.did) == DefKind::AnonConst =>
+                if matches!(self.tcx.def_kind(uv.def.did), DefKind::AnonConst | DefKind::InlineConst) =>
             {
                 self.visit_child_body(uv.def.did, uv.substs(self.tcx));
                 ControlFlow::CONTINUE
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 569f186a727..7f68112a427 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -82,6 +82,33 @@ pub(crate) fn emit_unescape_error(
                         Applicability::MachineApplicable,
                     );
                 }
+            } else {
+                let printable: Vec<char> = lit
+                    .chars()
+                    .filter(|&x| {
+                        unicode_width::UnicodeWidthChar::width(x).unwrap_or(0) != 0
+                            && !x.is_whitespace()
+                    })
+                    .collect();
+
+                if let [ch] = printable.as_slice() {
+                    has_help = true;
+
+                    handler.span_note(
+                        span,
+                        &format!(
+                            "there are non-printing characters, the full sequence is `{}`",
+                            lit.escape_default(),
+                        ),
+                    );
+
+                    handler.span_suggestion(
+                        span,
+                        "consider removing the non-printing characters",
+                        ch.to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
             }
 
             if !has_help {
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 2aa20d02c88..4781813ee8e 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -5,7 +5,7 @@ use crate::parse_in;
 use rustc_ast::tokenstream::{DelimSpan, TokenTree};
 use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
 use rustc_errors::{Applicability, FatalError, PResult};
-use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
+use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
 use rustc_session::parse::ParseSess;
 use rustc_span::{sym, Symbol};
@@ -15,14 +15,13 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
         return;
     }
 
-    let attr_info =
-        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
+    let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
 
     // Check input tokens for built-in and key-value attributes.
     match attr_info {
         // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-        Some((name, _, template, _)) if name != sym::rustc_dummy => {
-            check_builtin_attribute(sess, attr, name, template)
+        Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
+            check_builtin_attribute(sess, attr, *name, *template)
         }
         _ if let MacArgs::Eq(..) = attr.get_normal_item().args => {
             // All key-value attributes are restricted to meta-item syntax.
@@ -168,7 +167,7 @@ pub fn emit_fatal_malformed_builtin_attribute(
     attr: &Attribute,
     name: Symbol,
 ) -> ! {
-    let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").2;
+    let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template;
     emit_malformed_attribute(sess, attr, name, template);
     // This is fatal, otherwise it will likely cause a cascade of other errors
     // (and an error here is expected to be very rare).
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 596d13d2d9a..6ff2259dc5b 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, struct_span_err, Applicability};
-use rustc_feature::{AttributeType, BUILTIN_ATTRIBUTE_MAP};
+use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -112,6 +112,7 @@ impl CheckAttrVisitor<'tcx> {
                     self.check_default_method_body_is_const(attr, span, target)
                 }
                 sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
+                sym::must_use => self.check_must_use(hir_id, &attr, span, target),
                 sym::rustc_const_unstable
                 | sym::rustc_const_stable
                 | sym::unstable
@@ -148,7 +149,7 @@ impl CheckAttrVisitor<'tcx> {
             }
 
             if hir_id != CRATE_HIR_ID {
-                if let Some((_, AttributeType::CrateLevel, ..)) =
+                if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) =
                     attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
                 {
                     self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
@@ -1046,6 +1047,37 @@ impl CheckAttrVisitor<'tcx> {
         is_valid
     }
 
+    /// Warns against some misuses of `#[must_use]`
+    fn check_must_use(
+        &self,
+        hir_id: HirId,
+        attr: &Attribute,
+        span: &Span,
+        _target: Target,
+    ) -> bool {
+        let node = self.tcx.hir().get(hir_id);
+        if let Some(fn_node) = node.fn_kind() {
+            if let rustc_hir::IsAsync::Async = fn_node.asyncness() {
+                self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+                    lint.build(
+                        "`must_use` attribute on `async` functions \
+                              applies to the anonymous `Future` returned by the \
+                              function, not the value within",
+                    )
+                    .span_label(
+                        *span,
+                        "this attribute does nothing, the `Future`s \
+                                returned by async functions are already `must_use`",
+                    )
+                    .emit();
+                });
+            }
+        }
+
+        // For now, its always valid
+        true
+    }
+
     /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid.
     fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
         match target {
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 4adec3c4f60..af1c7244100 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -7,7 +7,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(crate_visibility_modifier)]
 #![feature(in_band_lifetimes)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs
index 5fc8e230d72..6a8feb041da 100644
--- a/compiler/rustc_passes/src/region.rs
+++ b/compiler/rustc_passes/src/region.rs
@@ -334,9 +334,10 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
     // properly, we can't miss any types.
 
     match expr.kind {
-        // Manually recurse over closures, because they are the only
+        // Manually recurse over closures and inline consts, because they are the only
         // case of nested bodies that share the parent environment.
-        hir::ExprKind::Closure(.., body, _, _) => {
+        hir::ExprKind::Closure(.., body, _, _)
+        | hir::ExprKind::ConstBlock(hir::AnonConst { body, .. }) => {
             let body = visitor.tcx.hir().body(body);
             visitor.visit_body(body);
         }
@@ -817,9 +818,9 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
 }
 
 fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
-    let closure_base_def_id = tcx.closure_base_def_id(def_id);
-    if closure_base_def_id != def_id {
-        return tcx.region_scope_tree(closure_base_def_id);
+    let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
+    if typeck_root_def_id != def_id {
+        return tcx.region_scope_tree(typeck_root_def_id);
     }
 
     let id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index fa34b9abc1e..11668146f7b 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -543,7 +543,7 @@ impl EmbargoVisitor<'tcx> {
         module: LocalDefId,
     ) {
         let level = Some(AccessLevel::Reachable);
-        if let ty::Visibility::Public = vis {
+        if vis.is_public() {
             self.update(def_id, level);
         }
         match def_kind {
@@ -580,7 +580,7 @@ impl EmbargoVisitor<'tcx> {
 
             DefKind::Struct | DefKind::Union => {
                 // While structs and unions have type privacy, their fields do not.
-                if let ty::Visibility::Public = vis {
+                if vis.is_public() {
                     let item =
                         self.tcx.hir().expect_item(self.tcx.hir().local_def_id_to_hir_id(def_id));
                     if let hir::ItemKind::Struct(ref struct_def, _)
@@ -618,6 +618,7 @@ impl EmbargoVisitor<'tcx> {
             | DefKind::Use
             | DefKind::ForeignMod
             | DefKind::AnonConst
+            | DefKind::InlineConst
             | DefKind::Field
             | DefKind::GlobalAsm
             | DefKind::Impl
@@ -932,7 +933,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             let def_id = self.tcx.hir().local_def_id(id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
-                    if export.vis == ty::Visibility::Public {
+                    if export.vis.is_public() {
                         if let Some(def_id) = export.res.opt_def_id() {
                             if let Some(def_id) = def_id.as_local() {
                                 self.update(def_id, Some(AccessLevel::Exported));
@@ -1917,8 +1918,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
     /// 1. It's contained within a public type
     /// 2. It comes from a private crate
     fn leaks_private_dep(&self, item_id: DefId) -> bool {
-        let ret = self.required_visibility == ty::Visibility::Public
-            && self.tcx.is_private_dep(item_id.krate);
+        let ret = self.required_visibility.is_public() && self.tcx.is_private_dep(item_id.krate);
 
         tracing::debug!("leaks_private_dep(item_id={:?})={}", item_id, ret);
         ret
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index d77a70e5327..3cf9d324a38 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -967,6 +967,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 | DefKind::Use
                 | DefKind::ForeignMod
                 | DefKind::AnonConst
+                | DefKind::InlineConst
                 | DefKind::Field
                 | DefKind::LifetimeParam
                 | DefKind::GlobalAsm
@@ -1193,15 +1194,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     // Mark the given macro as unused unless its name starts with `_`.
     // Macro uses will remove items from this set, and the remaining
     // items will be reported as `unused_macros`.
-    fn insert_unused_macro(
-        &mut self,
-        ident: Ident,
-        def_id: LocalDefId,
-        node_id: NodeId,
-        span: Span,
-    ) {
+    fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) {
         if !ident.as_str().starts_with('_') {
-            self.r.unused_macros.insert(def_id, (node_id, span));
+            self.r.unused_macros.insert(def_id, (node_id, ident));
         }
     }
 
@@ -1245,7 +1240,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport));
             } else {
                 self.r.check_reserved_macro_name(ident, res);
-                self.insert_unused_macro(ident, def_id, item.id, span);
+                self.insert_unused_macro(ident, def_id, item.id);
             }
             self.r.visibilities.insert(def_id, vis);
             self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
@@ -1266,7 +1261,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 _ => self.resolve_visibility(&item.vis),
             };
             if vis != ty::Visibility::Public {
-                self.insert_unused_macro(ident, def_id, item.id, span);
+                self.insert_unused_macro(ident, def_id, item.id);
             }
             self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
             self.r.visibilities.insert(def_id, vis);
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 760b7469961..63699128e9e 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -32,7 +32,6 @@ use rustc_ast::visit::{self, Visitor};
 use rustc_ast_lowering::ResolverAstLowering;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::pluralize;
-use rustc_middle::ty;
 use rustc_session::lint::builtin::{MACRO_USE_EXTERN_CRATE, UNUSED_IMPORTS};
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::{MultiSpan, Span, DUMMY_SP};
@@ -228,7 +227,7 @@ impl Resolver<'_> {
         for import in self.potentially_unused_imports.iter() {
             match import.kind {
                 _ if import.used.get()
-                    || import.vis.get() == ty::Visibility::Public
+                    || import.vis.get().is_public()
                     || import.span.is_dummy() =>
                 {
                     if let ImportKind::MacroUse = import.kind {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index ff0d76e94fd..c46a18e5103 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -11,7 +11,7 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::PrimTy;
 use rustc_middle::bug;
-use rustc_middle::ty::{self, DefIdTree};
+use rustc_middle::ty::DefIdTree;
 use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::lev_distance::find_best_match_for_name;
@@ -731,7 +731,7 @@ impl<'a> Resolver<'a> {
                         suggestions.extend(
                             BUILTIN_ATTRIBUTES
                                 .iter()
-                                .map(|(name, ..)| TypoSuggestion::typo_from_res(*name, res)),
+                                .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)),
                         );
                     }
                 }
@@ -1308,7 +1308,7 @@ impl<'a> Resolver<'a> {
             );
             let def_span = self.session.source_map().guess_head_span(binding.span);
             let mut note_span = MultiSpan::from_span(def_span);
-            if !first && binding.vis == ty::Visibility::Public {
+            if !first && binding.vis.is_public() {
                 note_span.push_span_label(def_span, "consider importing it directly".into());
             }
             err.span_note(note_span, &msg);
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 936ab81914a..4262c1e9051 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -164,7 +164,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBindi
                 import: Import { kind: ImportKind::ExternCrate { .. }, .. },
                 ..
             },
-        ) => import.vis.get() == ty::Visibility::Public,
+        ) => import.vis.get().is_public(),
         _ => false,
     }
 }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 5def43c2423..39e710cb77f 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -540,7 +540,7 @@ fn is_late_bound_map<'tcx>(
     def_id: LocalDefId,
 ) -> Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
     match tcx.def_kind(def_id) {
-        DefKind::AnonConst => {
+        DefKind::AnonConst | DefKind::InlineConst => {
             let mut def_id = tcx
                 .parent(def_id.to_def_id())
                 .unwrap_or_else(|| bug!("anon const or closure without a parent"));
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 5f3620b247e..d17e8875a1e 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -13,7 +13,7 @@
 #![feature(drain_filter)]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(let_else)]
 #![feature(never_type)]
@@ -988,7 +988,7 @@ pub struct Resolver<'a> {
     non_macro_attr: Lrc<SyntaxExtension>,
     local_macro_def_scopes: FxHashMap<LocalDefId, Module<'a>>,
     ast_transform_scopes: FxHashMap<LocalExpnId, Module<'a>>,
-    unused_macros: FxHashMap<LocalDefId, (NodeId, Span)>,
+    unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
     proc_macro_stubs: FxHashSet<LocalDefId>,
     /// Traces collected during macro resolution and validated when it's complete.
     single_segment_macro_resolutions:
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 4f6e23d8f84..31fd9b989e1 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -315,8 +315,13 @@ impl<'a> ResolverExpand for Resolver<'a> {
     }
 
     fn check_unused_macros(&mut self) {
-        for (_, &(node_id, span)) in self.unused_macros.iter() {
-            self.lint_buffer.buffer_lint(UNUSED_MACROS, node_id, span, "unused macro definition");
+        for (_, &(node_id, ident)) in self.unused_macros.iter() {
+            self.lint_buffer.buffer_lint(
+                UNUSED_MACROS,
+                node_id,
+                ident.span,
+                &format!("unused macro definition: `{}`", ident.as_str()),
+            );
         }
     }
 
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 543cd0247a5..c7f8fe3a88a 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -739,6 +739,7 @@ impl<'tcx> SaveContext<'tcx> {
                 | HirDefKind::ForeignMod
                 | HirDefKind::LifetimeParam
                 | HirDefKind::AnonConst
+                | HirDefKind::InlineConst
                 | HirDefKind::Use
                 | HirDefKind::Field
                 | HirDefKind::GlobalAsm
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 8a9e8739d03..3f0a6b0e2f6 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -37,7 +37,7 @@ use std::iter::{self, FromIterator};
 use std::path::{Path, PathBuf};
 use std::str::{self, FromStr};
 
-/// The different settings that the `-Z strip` flag can have.
+/// The different settings that the `-C strip` flag can have.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum Strip {
     /// Do not strip at all.
@@ -165,6 +165,18 @@ pub enum LinkerPluginLto {
     Disabled,
 }
 
+/// Used with `-Z assert-incr-state`.
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum IncrementalStateAssertion {
+    /// Found and loaded an existing session directory.
+    ///
+    /// Note that this says nothing about whether any particular query
+    /// will be found to be red or green.
+    Loaded,
+    /// Did not load an existing session directory.
+    NotLoaded,
+}
+
 impl LinkerPluginLto {
     pub fn enabled(&self) -> bool {
         match *self {
@@ -578,6 +590,7 @@ pub struct OutputFilenames {
     pub out_directory: PathBuf,
     filestem: String,
     pub single_output_file: Option<PathBuf>,
+    pub temps_directory: Option<PathBuf>,
     pub outputs: OutputTypes,
 }
 
@@ -592,12 +605,14 @@ impl OutputFilenames {
         out_directory: PathBuf,
         out_filestem: String,
         single_output_file: Option<PathBuf>,
+        temps_directory: Option<PathBuf>,
         extra: String,
         outputs: OutputTypes,
     ) -> Self {
         OutputFilenames {
             out_directory,
             single_output_file,
+            temps_directory,
             outputs,
             filestem: format!("{}{}", out_filestem, extra),
         }
@@ -608,7 +623,14 @@ impl OutputFilenames {
             .get(&flavor)
             .and_then(|p| p.to_owned())
             .or_else(|| self.single_output_file.clone())
-            .unwrap_or_else(|| self.temp_path(flavor, None))
+            .unwrap_or_else(|| self.output_path(flavor))
+    }
+
+    /// Gets the output path where a compilation artifact of the given type
+    /// should be placed on disk.
+    pub fn output_path(&self, flavor: OutputType) -> PathBuf {
+        let extension = flavor.extension();
+        self.with_directory_and_extension(&self.out_directory, &extension)
     }
 
     /// Gets the path where a compilation artifact of the given type for the
@@ -643,11 +665,17 @@ impl OutputFilenames {
             extension.push_str(ext);
         }
 
-        self.with_extension(&extension)
+        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
+
+        self.with_directory_and_extension(&temps_directory, &extension)
     }
 
     pub fn with_extension(&self, extension: &str) -> PathBuf {
-        let mut path = self.out_directory.join(&self.filestem);
+        self.with_directory_and_extension(&self.out_directory, extension)
+    }
+
+    fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
+        let mut path = directory.join(&self.filestem);
         path.set_extension(extension);
         path
     }
@@ -688,6 +716,7 @@ pub fn host_triple() -> &'static str {
 impl Default for Options {
     fn default() -> Options {
         Options {
+            assert_incr_state: None,
             crate_types: Vec::new(),
             optimize: OptLevel::No,
             debuginfo: DebugInfo::None,
@@ -1610,6 +1639,21 @@ fn select_debuginfo(
     }
 }
 
+crate fn parse_assert_incr_state(
+    opt_assertion: &Option<String>,
+    error_format: ErrorOutputType,
+) -> Option<IncrementalStateAssertion> {
+    match opt_assertion {
+        Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
+        Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
+        Some(s) => early_error(
+            error_format,
+            &format!("unexpected incremental state assertion value: {}", s),
+        ),
+        None => None,
+    }
+}
+
 fn parse_native_lib_kind(
     matches: &getopts::Matches,
     kind: &str,
@@ -1999,6 +2043,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let incremental = cg.incremental.as_ref().map(PathBuf::from);
 
+    let assert_incr_state =
+        parse_assert_incr_state(&debugging_opts.assert_incr_state, error_format);
+
     if debugging_opts.profile && incremental.is_some() {
         early_error(
             error_format,
@@ -2163,6 +2210,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     };
 
     Options {
+        assert_incr_state,
         crate_types,
         optimize: opt_level,
         debuginfo,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 71464ad9714..2c217e40aba 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -4,7 +4,6 @@ use crate::early_error;
 use crate::lint;
 use crate::search_paths::SearchPath;
 use crate::utils::NativeLib;
-
 use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet};
 use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TargetTriple, TlsModel};
 
@@ -150,6 +149,7 @@ top_level_options!(
         /// If `Some`, enable incremental compilation, using the given
         /// directory to store intermediate results.
         incremental: Option<PathBuf> [UNTRACKED],
+        assert_incr_state: Option<IncrementalStateAssertion> [UNTRACKED],
 
         debugging_opts: DebuggingOptions [SUBSTRUCT],
         prints: Vec<PrintRequest> [UNTRACKED],
@@ -219,7 +219,7 @@ top_level_options!(
 /// generated code to parse an option into its respective field in the struct. There are a few
 /// hand-written parsers for parsing specific types of values in this module.
 macro_rules! options {
-    ($struct_name:ident, $stat:ident, $prefix:expr, $outputname:expr,
+    ($struct_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr,
      $($( #[$attr:meta] )* $opt:ident : $t:ty = (
         $init:expr,
         $parse:ident,
@@ -264,13 +264,15 @@ macro_rules! options {
     }
 
     pub const $stat: OptionDescrs<$struct_name> =
-        &[ $( (stringify!($opt), $opt, desc::$parse, $desc) ),* ];
+        &[ $( (stringify!($opt), $optmod::$opt, desc::$parse, $desc) ),* ];
 
+    mod $optmod {
     $(
-        fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
-            parse::$parse(&mut redirect_field!(cg.$opt), v)
+        pub(super) fn $opt(cg: &mut super::$struct_name, v: Option<&str>) -> bool {
+            super::parse::$parse(&mut redirect_field!(cg.$opt), v)
         }
     )*
+    }
 
 ) }
 
@@ -918,7 +920,7 @@ mod parse {
 }
 
 options! {
-    CodegenOptions, CG_OPTIONS, "C", "codegen",
+    CodegenOptions, CG_OPTIONS, cgopts, "C", "codegen",
 
     // This list is in alphabetical order.
     //
@@ -1013,6 +1015,8 @@ options! {
         "use soft float ABI (*eabihf targets only) (default: no)"),
     split_debuginfo: Option<SplitDebuginfo> = (None, parse_split_debuginfo, [TRACKED],
         "how to handle split-debuginfo, a platform-specific option"),
+    strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
+        "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
     target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
         "select target processor (`rustc --print target-cpus` for details)"),
     target_feature: String = (String::new(), parse_target_feature, [TRACKED],
@@ -1027,7 +1031,7 @@ options! {
 }
 
 options! {
-    DebuggingOptions, DB_OPTIONS, "Z", "debugging",
+    DebuggingOptions, DB_OPTIONS, dbopts, "Z", "debugging",
 
     // This list is in alphabetical order.
     //
@@ -1042,6 +1046,9 @@ options! {
         "make cfg(version) treat the current version as incomplete (default: no)"),
     asm_comments: bool = (false, parse_bool, [TRACKED],
         "generate comments into the assembly (may change behavior) (default: no)"),
+    assert_incr_state: Option<String> = (None, parse_opt_string, [UNTRACKED],
+        "assert that the incremental cache is in given state: \
+         either `loaded` or `not-loaded`."),
     ast_json: bool = (false, parse_bool, [UNTRACKED],
         "print the AST as JSON and halt (default: no)"),
     ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED],
@@ -1331,6 +1338,8 @@ options! {
         "which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
     teach: bool = (false, parse_bool, [TRACKED],
         "show extended diagnostic help (default: no)"),
+    temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
+        "the directory the intermediate files are written to"),
     terminal_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
         "set the current terminal width"),
     tune_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 0f6a3ddccba..74b3cfa44c3 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -411,7 +411,7 @@ impl Session {
         self.diagnostic().abort_if_errors();
     }
     pub fn compile_status(&self) -> Result<(), ErrorReported> {
-        if self.has_errors() {
+        if self.diagnostic().has_errors_or_lint_errors() {
             self.diagnostic().emit_stashed_diagnostics();
             Err(ErrorReported)
         } else {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index b9730a1e420..99fa9f00094 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -271,6 +271,7 @@ symbols! {
         __S,
         __next,
         __try_var,
+        _args,
         _d,
         _e,
         _task_context,
diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs
index aaf81648c51..0f01a78c8c5 100644
--- a/compiler/rustc_target/src/spec/android_base.rs
+++ b/compiler/rustc_target/src/spec/android_base.rs
@@ -1,7 +1,7 @@
 use crate::spec::{LinkerFlavor, TargetOptions};
 
 pub fn opts() -> TargetOptions {
-    let mut base = super::linux_gnu_base::opts();
+    let mut base = super::linux_base::opts();
     base.os = "android".to_string();
     // Many of the symbols defined in compiler-rt are also defined in libgcc.
     // Android's linker doesn't like that by default.
diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs
index 53afe4ca068..4c80483fc1f 100644
--- a/compiler/rustc_trait_selection/src/autoderef.rs
+++ b/compiler/rustc_trait_selection/src/autoderef.rs
@@ -152,11 +152,12 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             },
             cause,
         );
-        if let Err(e) = fulfillcx.select_where_possible(&self.infcx) {
+        let errors = fulfillcx.select_where_possible(&self.infcx);
+        if !errors.is_empty() {
             // This shouldn't happen, except for evaluate/fulfill mismatches,
             // but that's not a reason for an ICE (`predicate_may_hold` is conservative
             // by design).
-            debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", e);
+            debug!("overloaded_deref_ty: encountered errors {:?} while fulfilling", errors);
             return None;
         }
         let obligations = fulfillcx.pending_obligations();
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6452b520452..54f7b91080d 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -187,9 +187,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
             // an additional sanity check.
             let mut fulfill = FulfillmentContext::new();
             fulfill.register_bound(&infcx, full_env, ty, trait_did, ObligationCause::dummy());
-            fulfill.select_all_or_error(&infcx).unwrap_or_else(|e| {
-                panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, e)
-            });
+            let errors = fulfill.select_all_or_error(&infcx);
+
+            if !errors.is_empty() {
+                panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors);
+            }
 
             let body_id_map: FxHashMap<_, _> = infcx
                 .inner
diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
index ec62ee40068..2ccb2534917 100644
--- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs
@@ -49,34 +49,32 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         self.obligations.insert(obligation);
     }
 
-    fn select_all_or_error(
-        &mut self,
-        infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
-        self.select_where_possible(infcx)?;
-
-        if self.obligations.is_empty() {
-            Ok(())
-        } else {
-            let errors = self
-                .obligations
-                .iter()
-                .map(|obligation| FulfillmentError {
-                    obligation: obligation.clone(),
-                    code: FulfillmentErrorCode::CodeAmbiguity,
-                    // FIXME - does Chalk have a notation of 'root obligation'?
-                    // This is just for diagnostics, so it's okay if this is wrong
-                    root_obligation: obligation.clone(),
-                })
-                .collect();
-            Err(errors)
+    fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
+        {
+            let errors = self.select_where_possible(infcx);
+
+            if !errors.is_empty() {
+                return errors;
+            }
         }
+
+        // any remaining obligations are errors
+        self.obligations
+            .iter()
+            .map(|obligation| FulfillmentError {
+                obligation: obligation.clone(),
+                code: FulfillmentErrorCode::CodeAmbiguity,
+                // FIXME - does Chalk have a notation of 'root obligation'?
+                // This is just for diagnostics, so it's okay if this is wrong
+                root_obligation: obligation.clone(),
+            })
+            .collect()
     }
 
     fn select_where_possible(
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    ) -> Vec<FulfillmentError<'tcx>> {
         assert!(!infcx.is_in_snapshot());
 
         let mut errors = Vec::new();
@@ -147,7 +145,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
             }
         }
 
-        if errors.is_empty() { Ok(()) } else { Err(errors) }
+        errors
     }
 
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs
index f06f0e32f41..bdd4fdd4043 100644
--- a/compiler/rustc_trait_selection/src/traits/codegen.rs
+++ b/compiler/rustc_trait_selection/src/traits/codegen.rs
@@ -120,7 +120,8 @@ where
     // In principle, we only need to do this so long as `result`
     // contains unbound type parameters. It could be a slight
     // optimization to stop iterating early.
-    if let Err(errors) = fulfill_cx.select_all_or_error(infcx) {
+    let errors = fulfill_cx.select_all_or_error(infcx);
+    if !errors.is_empty() {
         infcx.tcx.sess.delay_span_bug(
             rustc_span::DUMMY_SP,
             &format!("Encountered errors `{:?}` resolving bounds after type-checking", errors),
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 8edb7069fc4..6b5d37c0f43 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -151,7 +151,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
     if concrete.is_ok() && uv.substs(infcx.tcx).definitely_has_param_types_or_consts(infcx.tcx) {
         match infcx.tcx.def_kind(uv.def.did) {
-            DefKind::AnonConst => {
+            DefKind::AnonConst | DefKind::InlineConst => {
                 let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
 
                 if mir_body.is_polymorphic {
@@ -495,7 +495,7 @@ pub(super) fn thir_abstract_const<'tcx>(
             // we want to look into them or treat them as opaque projections.
             //
             // Right now we do neither of that and simply always fail to unify them.
-            DefKind::AnonConst => (),
+            DefKind::AnonConst | DefKind::InlineConst => (),
             _ => return Ok(None),
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 0b88eb7572a..f8df0e25959 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -266,19 +266,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     }
                 }
                 if let ObligationCauseCode::CompareImplMethodObligation {
-                    item_name,
                     impl_item_def_id,
                     trait_item_def_id,
                 }
                 | ObligationCauseCode::CompareImplTypeObligation {
-                    item_name,
                     impl_item_def_id,
                     trait_item_def_id,
                 } = obligation.cause.code
                 {
                     self.report_extra_impl_obligation(
                         span,
-                        item_name,
                         impl_item_def_id,
                         trait_item_def_id,
                         &format!("`{}`", obligation.predicate),
@@ -2012,6 +2009,19 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
             Some(param) => param,
             _ => return,
         };
+        let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id();
+        let preds = generics.where_clause.predicates.iter();
+        let explicitly_sized = preds
+            .filter_map(|pred| match pred {
+                hir::WherePredicate::BoundPredicate(bp) => Some(bp),
+                _ => None,
+            })
+            .filter(|bp| bp.is_param_bound(param_def_id))
+            .flat_map(|bp| bp.bounds)
+            .any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait);
+        if explicitly_sized {
+            return;
+        }
         debug!("maybe_suggest_unsized_generics: param={:?}", param);
         match node {
             hir::Node::Item(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 2689e2134fc..0bf01afb575 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -706,36 +706,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
 
         let param_env = obligation.param_env;
-        let trait_ref = poly_trait_ref.skip_binder();
-
-        let found_ty = trait_ref.self_ty();
-        let found_ty_str = found_ty.to_string();
-        let imm_borrowed_found_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, found_ty);
-        let imm_substs = self.tcx.mk_substs_trait(imm_borrowed_found_ty, &[]);
-        let mut_borrowed_found_ty = self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, found_ty);
-        let mut_substs = self.tcx.mk_substs_trait(mut_borrowed_found_ty, &[]);
 
         // Try to apply the original trait binding obligation by borrowing.
-        let mut try_borrowing = |new_imm_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-                                 new_mut_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
-                                 expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
+        let mut try_borrowing = |old_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
                                  blacklist: &[DefId]|
          -> bool {
-            if blacklist.contains(&expected_trait_ref.def_id()) {
+            if blacklist.contains(&old_ref.def_id()) {
                 return false;
             }
 
-            let imm_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
-                ObligationCause::dummy(),
-                param_env,
-                new_imm_trait_ref.without_const().to_predicate(self.tcx),
-            ));
-
-            let mut_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
-                ObligationCause::dummy(),
-                param_env,
-                new_mut_trait_ref.without_const().to_predicate(self.tcx),
-            ));
+            let orig_ty = old_ref.self_ty().skip_binder();
+            let mk_result = |new_ty| {
+                let new_ref = old_ref.rebind(ty::TraitRef::new(
+                    old_ref.def_id(),
+                    self.tcx.mk_substs_trait(new_ty, &old_ref.skip_binder().substs[1..]),
+                ));
+                self.predicate_must_hold_modulo_regions(&Obligation::new(
+                    ObligationCause::dummy(),
+                    param_env,
+                    new_ref.without_const().to_predicate(self.tcx),
+                ))
+            };
+            let imm_result = mk_result(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, orig_ty));
+            let mut_result = mk_result(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, orig_ty));
 
             if imm_result || mut_result {
                 if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
@@ -747,8 +740,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
 
                     let msg = format!(
                         "the trait bound `{}: {}` is not satisfied",
-                        found_ty_str,
-                        expected_trait_ref.print_only_trait_path(),
+                        orig_ty.to_string(),
+                        old_ref.print_only_trait_path(),
                     );
                     if has_custom_message {
                         err.note(&msg);
@@ -764,7 +757,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         span,
                         &format!(
                             "expected an implementor of trait `{}`",
-                            expected_trait_ref.print_only_trait_path(),
+                            old_ref.print_only_trait_path(),
                         ),
                     );
 
@@ -807,21 +800,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         };
 
         if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code {
-            let expected_trait_ref = obligation.parent_trait_ref;
-            let new_imm_trait_ref = poly_trait_ref
-                .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs));
-            let new_mut_trait_ref = poly_trait_ref
-                .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs));
-            return try_borrowing(new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, &[]);
+            try_borrowing(obligation.parent_trait_ref, &[])
         } else if let ObligationCauseCode::BindingObligation(_, _)
         | ObligationCauseCode::ItemObligation(_) = &*code
         {
-            return try_borrowing(
-                poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, imm_substs)),
-                poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, mut_substs)),
-                *poly_trait_ref,
-                &never_suggest_borrow[..],
-            );
+            try_borrowing(*poly_trait_ref, &never_suggest_borrow[..])
         } else {
             false
         }
@@ -1474,7 +1457,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let span = self.tcx.def_span(generator_did);
 
         let in_progress_typeck_results = self.in_progress_typeck_results.map(|t| t.borrow());
-        let generator_did_root = self.tcx.closure_base_def_id(generator_did);
+        let generator_did_root = self.tcx.typeck_root_def_id(generator_did);
         debug!(
             "maybe_note_obligation_cause_for_async_await: generator_did={:?} \
              generator_did_root={:?} in_progress_typeck_results.hir_owner={:?} span={:?}",
@@ -2354,11 +2337,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     )
                 });
             }
-            ObligationCauseCode::CompareImplMethodObligation {
-                item_name,
-                trait_item_def_id,
-                ..
-            } => {
+            ObligationCauseCode::CompareImplMethodObligation { trait_item_def_id, .. } => {
+                let item_name = self.tcx.item_name(trait_item_def_id);
                 let msg = format!(
                     "the requirement `{}` appears on the impl method `{}` but not on the \
                      corresponding trait method",
@@ -2383,9 +2363,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 }
                 err.span_note(assoc_span, &msg);
             }
-            ObligationCauseCode::CompareImplTypeObligation {
-                item_name, trait_item_def_id, ..
-            } => {
+            ObligationCauseCode::CompareImplTypeObligation { trait_item_def_id, .. } => {
+                let item_name = self.tcx.item_name(trait_item_def_id);
                 let msg = format!(
                     "the requirement `{}` appears on the associated impl type `{}` but not on the \
                      corresponding associated trait type",
@@ -2475,13 +2454,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     obligation.param_env,
                 );
 
-                let item_def_id = self
-                    .tcx
-                    .associated_items(future_trait)
-                    .in_definition_order()
-                    .next()
-                    .unwrap()
-                    .def_id;
+                let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
                 // `<T as Future>::Output`
                 let projection_ty = ty::ProjectionTy {
                     // `T`
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 465d1465d5d..e121837c987 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -126,10 +126,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
     }
 
     /// Attempts to select obligations using `selcx`.
-    fn select(
-        &mut self,
-        selcx: &mut SelectionContext<'a, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
         let span = debug_span!("select", obligation_forest_size = ?self.predicates.len());
         let _enter = span.enter();
 
@@ -163,7 +160,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
             errors.len()
         );
 
-        if errors.is_empty() { Ok(()) } else { Err(errors) }
+        errors
     }
 }
 
@@ -223,41 +220,36 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
             .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
     }
 
-    fn select_all_or_error(
-        &mut self,
-        infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
-        self.select_where_possible(infcx)?;
-
-        let errors: Vec<_> = self
-            .predicates
-            .to_errors(CodeAmbiguity)
-            .into_iter()
-            .map(to_fulfillment_error)
-            .collect();
-        if errors.is_empty() { Ok(()) } else { Err(errors) }
+    fn select_all_or_error(&mut self, infcx: &InferCtxt<'_, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
+        {
+            let errors = self.select_where_possible(infcx);
+            if !errors.is_empty() {
+                return errors;
+            }
+        }
+
+        self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
     }
 
     fn select_all_with_constness_or_error(
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
         constness: rustc_hir::Constness,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
-        self.select_with_constness_where_possible(infcx, constness)?;
-
-        let errors: Vec<_> = self
-            .predicates
-            .to_errors(CodeAmbiguity)
-            .into_iter()
-            .map(to_fulfillment_error)
-            .collect();
-        if errors.is_empty() { Ok(()) } else { Err(errors) }
+    ) -> Vec<FulfillmentError<'tcx>> {
+        {
+            let errors = self.select_with_constness_where_possible(infcx, constness);
+            if !errors.is_empty() {
+                return errors;
+            }
+        }
+
+        self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
     }
 
     fn select_where_possible(
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    ) -> Vec<FulfillmentError<'tcx>> {
         let mut selcx = SelectionContext::new(infcx);
         self.select(&mut selcx)
     }
@@ -266,7 +258,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
         constness: hir::Constness,
-    ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
+    ) -> Vec<FulfillmentError<'tcx>> {
         let mut selcx = SelectionContext::with_constness(infcx, constness);
         self.select(&mut selcx)
     }
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index cedd1aa54b8..fa8890fc352 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -33,7 +33,8 @@ pub fn can_type_implement_copy(
             | ty::Char
             | ty::RawPtr(..)
             | ty::Never
-            | ty::Ref(_, _, hir::Mutability::Not) => return Ok(()),
+            | ty::Ref(_, _, hir::Mutability::Not)
+            | ty::Array(..) => return Ok(()),
 
             ty::Adt(adt, substs) => (adt, substs),
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 8f247184e88..91671994c5a 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -65,7 +65,8 @@ pub use self::specialize::{specialization_graph, translate_substs, OverlapError}
 pub use self::structural_match::search_for_structural_match_violation;
 pub use self::structural_match::NonStructuralMatchTy;
 pub use self::util::{
-    elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs,
+    elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span,
+    elaborate_trait_ref, elaborate_trait_refs,
 };
 pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 pub use self::util::{
@@ -180,8 +181,8 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
         // Note: we only assume something is `Copy` if we can
         // *definitively* show that it implements `Copy`. Otherwise,
         // assume it is move; linear is always ok.
-        match fulfill_cx.select_all_or_error(infcx) {
-            Ok(()) => {
+        match fulfill_cx.select_all_or_error(infcx).as_slice() {
+            [] => {
                 debug!(
                     "type_known_to_meet_bound_modulo_regions: ty={:?} bound={} success",
                     ty,
@@ -189,12 +190,12 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
                 );
                 true
             }
-            Err(e) => {
+            errors => {
                 debug!(
-                    "type_known_to_meet_bound_modulo_regions: ty={:?} bound={} errors={:?}",
-                    ty,
-                    infcx.tcx.def_path_str(def_id),
-                    e
+                    ?ty,
+                    bound = %infcx.tcx.def_path_str(def_id),
+                    ?errors,
+                    "type_known_to_meet_bound_modulo_regions"
                 );
                 false
             }
@@ -410,7 +411,10 @@ where
     }
 
     debug!("fully_normalize: select_all_or_error start");
-    fulfill_cx.select_all_or_error(infcx)?;
+    let errors = fulfill_cx.select_all_or_error(infcx);
+    if !errors.is_empty() {
+        return Err(errors);
+    }
     debug!("fully_normalize: select_all_or_error complete");
     let resolved_value = infcx.resolve_vars_if_possible(normalized_value);
     debug!("fully_normalize: resolved_value={:?}", resolved_value);
@@ -441,7 +445,9 @@ pub fn impossible_predicates<'tcx>(
             fulfill_cx.register_predicate_obligation(&infcx, obligation);
         }
 
-        fulfill_cx.select_all_or_error(&infcx).is_err()
+        let errors = fulfill_cx.select_all_or_error(&infcx);
+
+        !errors.is_empty()
     });
     debug!("impossible_predicates = {:?}", result);
     result
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index b5398f8a435..0a85676f431 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
@@ -77,10 +77,11 @@ fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
     let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?;
     debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id));
     fulfill_cx.register_predicate_obligations(infcx, obligations);
-    if let Err(e) = fulfill_cx.select_all_or_error(infcx) {
+    let errors = fulfill_cx.select_all_or_error(infcx);
+    if !errors.is_empty() {
         infcx.tcx.sess.diagnostic().delay_span_bug(
             DUMMY_SP,
-            &format!("errors selecting obligation during MIR typeck: {:?}", e),
+            &format!("errors selecting obligation during MIR typeck: {:?}", errors),
         );
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 481bfa4a26b..2aa214694cb 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1859,7 +1859,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Char
             | ty::RawPtr(..)
             | ty::Never
-            | ty::Ref(_, _, hir::Mutability::Not) => {
+            | ty::Ref(_, _, hir::Mutability::Not)
+            | ty::Array(..) => {
                 // Implementations provided in libcore
                 None
             }
@@ -1872,11 +1873,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Foreign(..)
             | ty::Ref(_, _, hir::Mutability::Mut) => None,
 
-            ty::Array(element_ty, _) => {
-                // (*) binder moved here
-                Where(obligation.predicate.rebind(vec![element_ty]))
-            }
-
             ty::Tuple(tys) => {
                 // (*) binder moved here
                 Where(obligation.predicate.rebind(tys.iter().map(|k| k.expect_ty()).collect()))
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index f9867f0671e..b64c5559227 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -225,8 +225,18 @@ fn fulfill_implication<'a, 'tcx>(
         for oblig in obligations.chain(more_obligations) {
             fulfill_cx.register_predicate_obligation(&infcx, oblig);
         }
-        match fulfill_cx.select_all_or_error(infcx) {
-            Err(errors) => {
+        match fulfill_cx.select_all_or_error(infcx).as_slice() {
+            [] => {
+                debug!(
+                    "fulfill_implication: an impl for {:?} specializes {:?}",
+                    source_trait_ref, target_trait_ref
+                );
+
+                // Now resolve the *substitution* we built for the target earlier, replacing
+                // the inference variables inside with whatever we got from fulfillment.
+                Ok(infcx.resolve_vars_if_possible(target_substs))
+            }
+            errors => {
                 // no dice!
                 debug!(
                     "fulfill_implication: for impls on {:?} and {:?}, \
@@ -238,17 +248,6 @@ fn fulfill_implication<'a, 'tcx>(
                 );
                 Err(())
             }
-
-            Ok(()) => {
-                debug!(
-                    "fulfill_implication: an impl for {:?} specializes {:?}",
-                    source_trait_ref, target_trait_ref
-                );
-
-                // Now resolve the *substitution* we built for the target earlier, replacing
-                // the inference variables inside with whatever we got from fulfillment.
-                Ok(infcx.resolve_vars_if_possible(target_substs))
-            }
         }
     })
 }
@@ -292,6 +291,11 @@ pub(super) fn specialization_graph_provider(
     sg
 }
 
+// This function is only used when
+// encountering errors and inlining
+// it negatively impacts perf.
+#[cold]
+#[inline(never)]
 fn report_overlap_conflict(
     tcx: TyCtxt<'_>,
     overlap: OverlapError,
@@ -444,8 +448,12 @@ fn report_conflicting_impls(
     match used_to_be_allowed {
         None => {
             sg.has_errored = true;
-            let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
-            decorate(LintDiagnosticBuilder::new(err));
+            if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) {
+                let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
+                decorate(LintDiagnosticBuilder::new(err));
+            } else {
+                tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check");
+            }
         }
         Some(kind) => {
             let lint = match kind {
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index a398e847b93..3d713822278 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -103,7 +103,7 @@ fn type_marked_structural(
     //
     // 2. We are sometimes doing future-incompatibility lints for
     //    now, so we do not want unconditional errors here.
-    fulfillment_cx.select_all_or_error(infcx).is_ok()
+    fulfillment_cx.select_all_or_error(infcx).is_empty()
 }
 
 /// This implements the traversal over the structure of a given type to try to
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 37e00733737..92f2760e62c 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -128,9 +128,9 @@ fn compute_implied_outlives_bounds<'tcx>(
 
     // Ensure that those obligations that we had to solve
     // get solved *here*.
-    match fulfill_cx.select_all_or_error(infcx) {
-        Ok(()) => Ok(implied_bounds),
-        Err(_) => Err(NoSolution),
+    match fulfill_cx.select_all_or_error(infcx).as_slice() {
+        [] => Ok(implied_bounds),
+        _ => Err(NoSolution),
     }
 }
 
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 87b729faa54..13ffb2a5adc 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>(
                     let is_copy = self_ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env);
                     match self_ty.kind() {
                         _ if is_copy => (),
-                        ty::Array(..) | ty::Closure(..) | ty::Tuple(..) => {}
+                        ty::Closure(..) | ty::Tuple(..) => {}
                         _ => return Ok(None),
                     };
 
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 3f66e5b4ebf..595b623b020 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -17,7 +17,8 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
     // needs drop.
     let adt_has_dtor =
         |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
-    let res = drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor).next().is_some();
+    let res =
+        drop_tys_helper(tcx, query.value, query.param_env, adt_has_dtor, false).next().is_some();
 
     debug!("needs_drop_raw({:?}) = {:?}", query, res);
     res
@@ -27,10 +28,15 @@ fn has_significant_drop_raw<'tcx>(
     tcx: TyCtxt<'tcx>,
     query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
 ) -> bool {
-    let res =
-        drop_tys_helper(tcx, query.value, query.param_env, adt_consider_insignificant_dtor(tcx))
-            .next()
-            .is_some();
+    let res = drop_tys_helper(
+        tcx,
+        query.value,
+        query.param_env,
+        adt_consider_insignificant_dtor(tcx),
+        true,
+    )
+    .next()
+    .is_some();
     debug!("has_significant_drop_raw({:?}) = {:?}", query, res);
     res
 }
@@ -141,9 +147,9 @@ where
                             Ok(tys) => tys,
                         };
                         for required_ty in tys {
-                            let subst_ty =
+                            let required =
                                 tcx.normalize_erasing_regions(self.param_env, required_ty);
-                            queue_type(self, subst_ty);
+                            queue_type(self, required);
                         }
                     }
                     ty::Array(..) | ty::Opaque(..) | ty::Projection(..) | ty::Param(_) => {
@@ -186,16 +192,39 @@ fn drop_tys_helper<'tcx>(
     ty: Ty<'tcx>,
     param_env: rustc_middle::ty::ParamEnv<'tcx>,
     adt_has_dtor: impl Fn(&ty::AdtDef) -> Option<DtorType>,
+    only_significant: bool,
 ) -> impl Iterator<Item = NeedsDropResult<Ty<'tcx>>> {
+    fn with_query_cache<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        iter: impl IntoIterator<Item = Ty<'tcx>>,
+        only_significant: bool,
+    ) -> NeedsDropResult<Vec<Ty<'tcx>>> {
+        iter.into_iter().try_fold(Vec::new(), |mut vec, subty| {
+            match subty.kind() {
+                ty::Adt(adt_id, subst) => {
+                    for subty in if only_significant {
+                        tcx.adt_significant_drop_tys(adt_id.did)?
+                    } else {
+                        tcx.adt_drop_tys(adt_id.did)?
+                    } {
+                        vec.push(subty.subst(tcx, subst));
+                    }
+                }
+                _ => vec.push(subty),
+            };
+            Ok(vec)
+        })
+    }
+
     let adt_components = move |adt_def: &ty::AdtDef, substs: SubstsRef<'tcx>| {
         if adt_def.is_manually_drop() {
             debug!("drop_tys_helper: `{:?}` is manually drop", adt_def);
-            return Ok(Vec::new().into_iter());
+            Ok(Vec::new())
         } else if let Some(dtor_info) = adt_has_dtor(adt_def) {
             match dtor_info {
                 DtorType::Significant => {
                     debug!("drop_tys_helper: `{:?}` implements `Drop`", adt_def);
-                    return Err(AlwaysRequiresDrop);
+                    Err(AlwaysRequiresDrop)
                 }
                 DtorType::Insignificant => {
                     debug!("drop_tys_helper: `{:?}` drop is insignificant", adt_def);
@@ -203,22 +232,27 @@ fn drop_tys_helper<'tcx>(
                     // Since the destructor is insignificant, we just want to make sure all of
                     // the passed in type parameters are also insignificant.
                     // Eg: Vec<T> dtor is insignificant when T=i32 but significant when T=Mutex.
-                    return Ok(substs.types().collect::<Vec<Ty<'_>>>().into_iter());
+                    with_query_cache(tcx, substs.types(), only_significant)
                 }
             }
         } else if adt_def.is_union() {
             debug!("drop_tys_helper: `{:?}` is a union", adt_def);
-            return Ok(Vec::new().into_iter());
+            Ok(Vec::new())
+        } else {
+            with_query_cache(
+                tcx,
+                adt_def.all_fields().map(|field| {
+                    let r = tcx.type_of(field.did).subst(tcx, substs);
+                    debug!(
+                        "drop_tys_helper: Subst into {:?} with {:?} gettng {:?}",
+                        field, substs, r
+                    );
+                    r
+                }),
+                only_significant,
+            )
         }
-        Ok(adt_def
-            .all_fields()
-            .map(|field| {
-                let r = tcx.type_of(field.did).subst(tcx, substs);
-                debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r);
-                r
-            })
-            .collect::<Vec<_>>()
-            .into_iter())
+        .map(|v| v.into_iter())
     };
 
     NeedsDropTypes::new(tcx, param_env, ty, adt_components)
@@ -252,20 +286,24 @@ fn adt_drop_tys(tcx: TyCtxt<'_>, def_id: DefId) -> Result<&ty::List<Ty<'_>>, Alw
     // significant.
     let adt_has_dtor =
         |adt_def: &ty::AdtDef| adt_def.destructor(tcx).map(|_| DtorType::Significant);
-    drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor)
+    // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_substs)`
+    drop_tys_helper(tcx, tcx.type_of(def_id), tcx.param_env(def_id), adt_has_dtor, false)
         .collect::<Result<Vec<_>, _>>()
         .map(|components| tcx.intern_type_list(&components))
 }
-
+// If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed
+// a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitue the generic parameters
+// of the ADT into the outputted `ty`s.
 fn adt_significant_drop_tys(
     tcx: TyCtxt<'_>,
     def_id: DefId,
 ) -> Result<&ty::List<Ty<'_>>, AlwaysRequiresDrop> {
     drop_tys_helper(
         tcx,
-        tcx.type_of(def_id),
+        tcx.type_of(def_id), // identical to `tcx.make_adt(def, identity_substs)`
         tcx.param_env(def_id),
         adt_consider_insignificant_dtor(tcx),
+        true,
     )
     .collect::<Result<Vec<_>, _>>()
     .map(|components| tcx.intern_type_list(&components))
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 84327a2880e..2f187997b55 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -672,6 +672,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 err.span_label(span, "explicit generic argument not allowed");
             }
 
+            err.note(
+                "see issue #83701 <https://github.com/rust-lang/rust/issues/83701> \
+                 for more information",
+            );
+            if tcx.sess.is_nightly_build() {
+                err.help(
+                    "add `#![feature(explicit_generic_args_with_impl_trait)]` \
+                     to the crate attributes to enable",
+                );
+            }
+
             err.emit();
         }
 
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 5040c4db951..bb1d9744e66 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -371,16 +371,26 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
         let param_env = tcx.param_env(item_def_id);
         for field in fields {
             let field_ty = field.ty(tcx, substs);
-            // We are currently checking the type this field came from, so it must be local.
-            let field_span = tcx.hir().span_if_local(field.did).unwrap();
             if field_ty.needs_drop(tcx, param_env) {
+                let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
+                    // We are currently checking the type this field came from, so it must be local.
+                    Some(Node::Field(field)) => (field.span, field.ty.span),
+                    _ => unreachable!("mir field has to correspond to hir field"),
+                };
                 struct_span_err!(
                     tcx.sess,
                     field_span,
                     E0740,
                     "unions may not contain fields that need dropping"
                 )
-                .span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
+                .multipart_suggestion_verbose(
+                    "wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped",
+                    vec![
+                        (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
+                        (ty_span.shrink_to_hi(), ">".into()),
+                    ],
+                    Applicability::MaybeIncorrect,
+                )
                 .emit();
                 return false;
             }
@@ -663,8 +673,9 @@ fn check_opaque_meets_bounds<'tcx>(
 
         // Check that all obligations are satisfied by the implementation's
         // version.
-        if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors, None, false);
+        let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
         }
 
         // Finally, resolve all regions. This catches wily misuses of
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 410ac24b1f1..4a41552a5fb 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -92,7 +92,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let parent_substs = InternalSubsts::identity_for_item(
             self.tcx,
-            self.tcx.closure_base_def_id(expr_def_id.to_def_id()),
+            self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
         );
 
         let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin {
@@ -257,8 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if is_gen {
             // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
             // associated item and not yield.
-            let return_assoc_item =
-                self.tcx.associated_items(gen_trait).in_definition_order().nth(1).unwrap().def_id;
+            let return_assoc_item = self.tcx.associated_item_def_ids(gen_trait)[1];
             if return_assoc_item != projection.projection_def_id() {
                 debug!("deduce_sig_from_projection: not return assoc item of generator");
                 return None;
@@ -694,8 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // The `Future` trait has only one associted item, `Output`,
         // so check that this is what we see.
-        let output_assoc_item =
-            self.tcx.associated_items(future_trait).in_definition_order().next().unwrap().def_id;
+        let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0];
         if output_assoc_item != predicate.projection_ty.item_def_id {
             span_bug!(
                 cause_span,
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index ad65a0ba62a..28712e06582 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -950,7 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             let mut fcx = traits::FulfillmentContext::new_in_snapshot();
             fcx.register_predicate_obligations(self, ok.obligations);
-            fcx.select_where_possible(&self).is_ok()
+            fcx.select_where_possible(&self).is_empty()
         })
     }
 
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 7c262dcf723..cbfd8747ecf 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -92,7 +92,6 @@ fn compare_predicate_entailment<'tcx>(
         impl_m_span,
         impl_m_hir_id,
         ObligationCauseCode::CompareImplMethodObligation {
-            item_name: impl_m.ident.name,
             impl_item_def_id: impl_m.def_id,
             trait_item_def_id: trait_m.def_id,
         },
@@ -391,8 +390,9 @@ fn compare_predicate_entailment<'tcx>(
 
         // Check that all obligations are satisfied by the implementation's
         // version.
-        if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors, None, false);
+        let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
             return Err(ErrorReported);
         }
 
@@ -1094,8 +1094,9 @@ crate fn compare_const_impl<'tcx>(
 
         // Check that all obligations are satisfied by the implementation's
         // version.
-        if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors, None, false);
+        let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
             return;
         }
 
@@ -1165,7 +1166,6 @@ fn compare_type_predicate_entailment<'tcx>(
         impl_ty_span,
         impl_ty_hir_id,
         ObligationCauseCode::CompareImplTypeObligation {
-            item_name: impl_ty.ident.name,
             impl_item_def_id: impl_ty.def_id,
             trait_item_def_id: trait_ty.def_id,
         },
@@ -1210,8 +1210,9 @@ fn compare_type_predicate_entailment<'tcx>(
 
         // Check that all obligations are satisfied by the implementation's
         // version.
-        if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors, None, false);
+        let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
             return Err(ErrorReported);
         }
 
@@ -1427,10 +1428,10 @@ pub fn check_type_bounds<'tcx>(
 
         // Check that all obligations are satisfied by the implementation's
         // version.
-        if let Err(ref errors) =
-            inh.fulfillment_cx.borrow_mut().select_all_with_constness_or_error(&infcx, constness)
-        {
-            infcx.report_fulfillment_errors(errors, None, false);
+        let errors =
+            inh.fulfillment_cx.borrow_mut().select_all_with_constness_or_error(&infcx, constness);
+        if !errors.is_empty() {
+            infcx.report_fulfillment_errors(&errors, None, false);
             return Err(ErrorReported);
         }
 
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index fd150978f00..4b4d29307ff 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -113,9 +113,10 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
             }
         }
 
-        if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
+        let errors = fulfillment_cx.select_all_or_error(&infcx);
+        if !errors.is_empty() {
             // this could be reached when we get lazy normalization
-            infcx.report_fulfillment_errors(errors, None, false);
+            infcx.report_fulfillment_errors(&errors, None, false);
             return Err(ErrorReported);
         }
 
@@ -239,8 +240,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                     ty::PredicateKind::ConstEvaluatable(a),
                     ty::PredicateKind::ConstEvaluatable(b),
                 ) => tcx.try_unify_abstract_consts((a, b)),
-                (ty::PredicateKind::TypeOutlives(a), ty::PredicateKind::TypeOutlives(b)) => {
-                    relator.relate(predicate.rebind(a.0), p.rebind(b.0)).is_ok()
+                (
+                    ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_a, lt_a)),
+                    ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_b, lt_b)),
+                ) => {
+                    relator.relate(predicate.rebind(ty_a), p.rebind(ty_b)).is_ok()
+                        && relator.relate(predicate.rebind(lt_a), p.rebind(lt_b)).is_ok()
                 }
                 _ => predicate == p,
             }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 3cba7991cca..5c79a067e9f 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -30,15 +30,17 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder,
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ExprKind, QPath};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_middle::ty;
+use rustc_infer::infer::InferOk;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
+use rustc_middle::ty::error::TypeError::{FieldMisMatch, Sorts};
+use rustc_middle::ty::relate::expected_found_bool;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::Ty;
-use rustc_middle::ty::TypeFoldable;
-use rustc_middle::ty::{AdtKind, Visibility};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
+use rustc_session::parse::feature_err;
 use rustc_span::edition::LATEST_STABLE_EDITION;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
@@ -323,7 +325,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
             ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
-            ExprKind::ConstBlock(ref anon_const) => self.to_const(anon_const).ty,
+            ExprKind::ConstBlock(ref anon_const) => {
+                self.check_expr_const_block(anon_const, expected, expr)
+            }
             ExprKind::Repeat(element, ref count) => {
                 self.check_expr_repeat(element, count, expected, expr)
             }
@@ -1166,6 +1170,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.mk_array(element_ty, args.len() as u64)
     }
 
+    fn check_expr_const_block(
+        &self,
+        anon_const: &'tcx hir::AnonConst,
+        expected: Expectation<'tcx>,
+        _expr: &'tcx hir::Expr<'tcx>,
+    ) -> Ty<'tcx> {
+        let body = self.tcx.hir().body(anon_const.body);
+
+        // Create a new function context.
+        let fcx = FnCtxt::new(self, self.param_env, body.value.hir_id);
+        crate::check::GatherLocalsVisitor::new(&fcx).visit_body(body);
+
+        let ty = fcx.check_expr_with_expectation(&body.value, expected);
+        fcx.require_type_is_sized(ty, body.value.span, traits::ConstSized);
+        fcx.write_ty(anon_const.hir_id, ty);
+        ty
+    }
+
     fn check_expr_repeat(
         &self,
         element: &'tcx hir::Expr<'tcx>,
@@ -1262,49 +1284,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() });
         }
 
-        let error_happened = self.check_expr_struct_fields(
+        self.check_expr_struct_fields(
             adt_ty,
             expected,
             expr.hir_id,
             qpath.span(),
             variant,
             fields,
-            base_expr.is_none(),
+            base_expr,
             expr.span,
         );
-        if let Some(base_expr) = base_expr {
-            // If check_expr_struct_fields hit an error, do not attempt to populate
-            // the fields with the base_expr. This could cause us to hit errors later
-            // when certain fields are assumed to exist that in fact do not.
-            if !error_happened {
-                self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {});
-                match adt_ty.kind() {
-                    ty::Adt(adt, substs) if adt.is_struct() => {
-                        let fru_field_types = adt
-                            .non_enum_variant()
-                            .fields
-                            .iter()
-                            .map(|f| {
-                                self.normalize_associated_types_in(
-                                    expr.span,
-                                    f.ty(self.tcx, substs),
-                                )
-                            })
-                            .collect();
-
-                        self.typeck_results
-                            .borrow_mut()
-                            .fru_field_types_mut()
-                            .insert(expr.hir_id, fru_field_types);
-                    }
-                    _ => {
-                        self.tcx
-                            .sess
-                            .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
-                    }
-                }
-            }
-        }
+
         self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
         adt_ty
     }
@@ -1317,9 +1307,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         variant: &'tcx ty::VariantDef,
         ast_fields: &'tcx [hir::ExprField<'tcx>],
-        check_completeness: bool,
+        base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
         expr_span: Span,
-    ) -> bool {
+    ) {
         let tcx = self.tcx;
 
         let adt_ty_hint = self
@@ -1394,7 +1384,116 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 )
                 .emit();
             }
-        } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
+        }
+
+        // If check_expr_struct_fields hit an error, do not attempt to populate
+        // the fields with the base_expr. This could cause us to hit errors later
+        // when certain fields are assumed to exist that in fact do not.
+        if error_happened {
+            return;
+        }
+
+        if let Some(base_expr) = base_expr {
+            // FIXME: We are currently creating two branches here in order to maintain
+            // consistency. But they should be merged as much as possible.
+            let fru_tys = if self.tcx.features().type_changing_struct_update {
+                let base_ty = self.check_expr(base_expr);
+                match adt_ty.kind() {
+                    ty::Adt(adt, substs) if adt.is_struct() => {
+                        match base_ty.kind() {
+                            ty::Adt(base_adt, base_subs) if adt == base_adt => {
+                                variant
+                                    .fields
+                                    .iter()
+                                    .map(|f| {
+                                        let fru_ty = self.normalize_associated_types_in(
+                                            expr_span,
+                                            self.field_ty(base_expr.span, f, base_subs),
+                                        );
+                                        let ident = self.tcx.adjust_ident(f.ident, variant.def_id);
+                                        if let Some(_) = remaining_fields.remove(&ident) {
+                                            let target_ty =
+                                                self.field_ty(base_expr.span, f, substs);
+                                            let cause = self.misc(base_expr.span);
+                                            match self
+                                                .at(&cause, self.param_env)
+                                                .sup(target_ty, fru_ty)
+                                            {
+                                                Ok(InferOk { obligations, value: () }) => {
+                                                    self.register_predicates(obligations)
+                                                }
+                                                // FIXME: Need better diagnostics for `FieldMisMatch` error
+                                                Err(_) => self
+                                                    .report_mismatched_types(
+                                                        &cause,
+                                                        target_ty,
+                                                        fru_ty,
+                                                        FieldMisMatch(
+                                                            variant.ident.name,
+                                                            ident.name,
+                                                        ),
+                                                    )
+                                                    .emit(),
+                                            }
+                                        }
+                                        fru_ty
+                                    })
+                                    .collect()
+                            }
+                            _ => {
+                                return self
+                                    .report_mismatched_types(
+                                        &self.misc(base_expr.span),
+                                        adt_ty,
+                                        base_ty,
+                                        Sorts(expected_found_bool(true, adt_ty, base_ty)),
+                                    )
+                                    .emit();
+                            }
+                        }
+                    }
+                    _ => {
+                        return self
+                            .tcx
+                            .sess
+                            .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
+                    }
+                }
+            } else {
+                self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {
+                    let base_ty = self.check_expr(base_expr);
+                    let same_adt = match (adt_ty.kind(), base_ty.kind()) {
+                        (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt => true,
+                        _ => false,
+                    };
+                    if self.tcx.sess.is_nightly_build() && same_adt {
+                        feature_err(
+                            &self.tcx.sess.parse_sess,
+                            sym::type_changing_struct_update,
+                            base_expr.span,
+                            "type changing struct updating is experimental",
+                        )
+                        .emit();
+                    }
+                });
+                match adt_ty.kind() {
+                    ty::Adt(adt, substs) if adt.is_struct() => variant
+                        .fields
+                        .iter()
+                        .map(|f| {
+                            self.normalize_associated_types_in(expr_span, f.ty(self.tcx, substs))
+                        })
+                        .collect(),
+                    _ => {
+                        return self
+                            .tcx
+                            .sess
+                            .emit_err(FunctionalRecordUpdateOnNonStruct { span: base_expr.span });
+                    }
+                }
+            };
+            self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr_id, fru_tys);
+        } else if kind_name != "union" && !remaining_fields.is_empty() {
             let inaccessible_remaining_fields = remaining_fields.iter().any(|(_, (_, field))| {
                 !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
             });
@@ -1405,8 +1504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.report_missing_fields(adt_ty, span, remaining_fields);
             }
         }
-
-        error_happened
     }
 
     fn check_struct_fields_on_error(
@@ -1632,7 +1729,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .filter_map(|field| {
                 // ignore already set fields and private fields from non-local crates
                 if skip.iter().any(|&x| x == field.ident.name)
-                    || (!variant.def_id.is_local() && field.vis != Visibility::Public)
+                    || (!variant.def_id.is_local() && !field.vis.is_public())
                 {
                     None
                 } else {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 5308126f252..aae59eee991 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -642,11 +642,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     #[instrument(skip(self), level = "debug")]
     pub(in super::super) fn select_all_obligations_or_error(&self) {
-        if let Err(errors) = self
+        let errors = self
             .fulfillment_cx
             .borrow_mut()
-            .select_all_with_constness_or_error(&self, self.inh.constness)
-        {
+            .select_all_with_constness_or_error(&self, self.inh.constness);
+
+        if !errors.is_empty() {
             self.report_fulfillment_errors(&errors, self.inh.body_id, false);
         }
     }
@@ -657,13 +658,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fallback_has_occurred: bool,
         mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
     ) {
-        let result = self
+        let mut result = self
             .fulfillment_cx
             .borrow_mut()
             .select_with_constness_where_possible(self, self.inh.constness);
-        if let Err(mut errors) = result {
-            mutate_fulfillment_errors(&mut errors);
-            self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
+        if !result.is_empty() {
+            mutate_fulfillment_errors(&mut result);
+            self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred);
         }
     }
 
@@ -793,14 +794,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // we can.  We don't care if some things turn
                         // out unconstrained or ambiguous, as we're
                         // just trying to get hints here.
-                        self.save_and_restore_in_snapshot_flag(|_| {
+                        let errors = self.save_and_restore_in_snapshot_flag(|_| {
                             let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
                             for obligation in ok.obligations {
                                 fulfill.register_predicate_obligation(self, obligation);
                             }
                             fulfill.select_where_possible(self)
-                        })
-                        .map_err(|_| ())?;
+                        });
+
+                        if !errors.is_empty() {
+                            return Err(());
+                        }
                     }
                     Err(_) => return Err(()),
                 }
@@ -948,7 +952,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mut err = rustc_errors::struct_span_err!(
                         self.sess(),
                         self_ty.span,
-                        E0783,
+                        E0782,
                         "{}",
                         msg,
                     );
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index dcc635a1f00..6c7d3a0c9c0 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -14,6 +14,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Binder, Ty};
 use rustc_span::symbol::{kw, sym};
 
+use rustc_middle::ty::subst::GenericArgKind;
 use std::iter;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -232,48 +233,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let is_struct_pat_shorthand_field =
                 self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span);
             let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id);
-            if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
-                let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods)
-                    .filter_map(|(receiver, method)| {
-                        let method_call = format!(".{}()", method.ident);
-                        if receiver.ends_with(&method_call) {
-                            None // do not suggest code that is already there (#53348)
-                        } else {
-                            let method_call_list = [".to_vec()", ".to_string()"];
-                            let mut sugg = if receiver.ends_with(".clone()")
-                                && method_call_list.contains(&method_call.as_str())
-                            {
-                                let max_len = receiver.rfind('.').unwrap();
-                                vec![(
-                                    expr.span,
-                                    format!("{}{}", &receiver[..max_len], method_call),
-                                )]
+            if !methods.is_empty() {
+                if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
+                    let mut suggestions = iter::zip(iter::repeat(&expr_text), &methods)
+                        .filter_map(|(receiver, method)| {
+                            let method_call = format!(".{}()", method.ident);
+                            if receiver.ends_with(&method_call) {
+                                None // do not suggest code that is already there (#53348)
                             } else {
-                                if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
-                                    vec![
-                                        (expr.span.shrink_to_lo(), "(".to_string()),
-                                        (expr.span.shrink_to_hi(), format!("){}", method_call)),
-                                    ]
+                                let method_call_list = [".to_vec()", ".to_string()"];
+                                let mut sugg = if receiver.ends_with(".clone()")
+                                    && method_call_list.contains(&method_call.as_str())
+                                {
+                                    let max_len = receiver.rfind('.').unwrap();
+                                    vec![(
+                                        expr.span,
+                                        format!("{}{}", &receiver[..max_len], method_call),
+                                    )]
                                 } else {
-                                    vec![(expr.span.shrink_to_hi(), method_call)]
+                                    if expr.precedence().order()
+                                        < ExprPrecedence::MethodCall.order()
+                                    {
+                                        vec![
+                                            (expr.span.shrink_to_lo(), "(".to_string()),
+                                            (expr.span.shrink_to_hi(), format!("){}", method_call)),
+                                        ]
+                                    } else {
+                                        vec![(expr.span.shrink_to_hi(), method_call)]
+                                    }
+                                };
+                                if is_struct_pat_shorthand_field {
+                                    sugg.insert(
+                                        0,
+                                        (expr.span.shrink_to_lo(), format!("{}: ", receiver)),
+                                    );
                                 }
-                            };
-                            if is_struct_pat_shorthand_field {
-                                sugg.insert(
-                                    0,
-                                    (expr.span.shrink_to_lo(), format!("{}: ", receiver)),
+                                Some(sugg)
+                            }
+                        })
+                        .peekable();
+                    if suggestions.peek().is_some() {
+                        err.multipart_suggestions(
+                            "try using a conversion method",
+                            suggestions,
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
+            } else if found.to_string().starts_with("Option<")
+                && expected.to_string() == "Option<&str>"
+            {
+                if let ty::Adt(_def, subst) = found.kind() {
+                    if subst.len() != 0 {
+                        if let GenericArgKind::Type(ty) = subst[0].unpack() {
+                            let peeled = ty.peel_refs().to_string();
+                            if peeled == "String" {
+                                let ref_cnt = ty.to_string().len() - peeled.len();
+                                let result = format!(".map(|x| &*{}x)", "*".repeat(ref_cnt));
+                                err.span_suggestion_verbose(
+                                    expr.span.shrink_to_hi(),
+                                    "try converting the passed type into a `&str`",
+                                    result,
+                                    Applicability::MaybeIncorrect,
                                 );
                             }
-                            Some(sugg)
                         }
-                    })
-                    .peekable();
-                if suggestions.peek().is_some() {
-                    err.multipart_suggestions(
-                        "try using a conversion method",
-                        suggestions,
-                        Applicability::MaybeIncorrect,
-                    );
+                    }
                 }
             }
         }
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index b0cb8443bfb..6314f2aba4e 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -324,9 +324,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool),
 
             sym::discriminant_value => {
-                let assoc_items =
-                    tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
-                let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
+                let assoc_items = tcx.associated_item_def_ids(
+                    tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
+                );
+                let discriminant_def_id = assoc_items[0];
 
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) };
                 (
diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs
index dc54f63f49c..e7e4e72f6c1 100644
--- a/compiler/rustc_typeck/src/check/method/confirm.rs
+++ b/compiler/rustc_typeck/src/check/method/confirm.rs
@@ -162,7 +162,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
         match &pick.autoref_or_ptr_adjustment {
             Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {
-                let region = self.next_region_var(infer::Autoref(self.span, pick.item));
+                let region = self.next_region_var(infer::Autoref(self.span));
                 target = self.tcx.mk_ref(region, ty::TypeAndMut { mutbl: *mutbl, ty: target });
                 let mutbl = match mutbl {
                     hir::Mutability::Not => AutoBorrowMutability::Not,
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 13f475cd9e0..661ced952c7 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -478,6 +478,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let mut label_span_not_found = || {
                     if unsatisfied_predicates.is_empty() {
                         err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
+                        let is_string_or_ref_str = match actual.kind() {
+                            ty::Ref(_, ty, _) => {
+                                ty.is_str()
+                                    || matches!(
+                                        ty.kind(),
+                                        ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did)
+                                    )
+                            }
+                            ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did),
+                            _ => false,
+                        };
+                        if is_string_or_ref_str && item_name.name == sym::iter {
+                            err.span_suggestion_verbose(
+                                item_name.span,
+                                "because of the in-memory representation of `&str`, to obtain \
+                                 an `Iterator` over each of its codepoint use method `chars`",
+                                String::from("chars"),
+                                Applicability::MachineApplicable,
+                            );
+                        }
                         if let ty::Adt(adt, _) = rcvr_ty.kind() {
                             let mut inherent_impls_candidate = self
                                 .tcx
@@ -1410,7 +1430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 }
                             }
                             // We only want to suggest public or local traits (#45781).
-                            item.vis == ty::Visibility::Public || info.def_id.is_local()
+                            item.vis.is_public() || info.def_id.is_local()
                         })
                         .is_some()
             })
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 7450b4a4ef1..d19e99606bc 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -297,9 +297,9 @@ fn primary_body_of(
 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     // Closures' typeck results come from their outermost function,
     // as they are part of the same "inference environment".
-    let outer_def_id = tcx.closure_base_def_id(def_id);
-    if outer_def_id != def_id {
-        return tcx.has_typeck_results(outer_def_id);
+    let typeck_root_def_id = tcx.typeck_root_def_id(def_id);
+    if typeck_root_def_id != def_id {
+        return tcx.has_typeck_results(typeck_root_def_id);
     }
 
     if let Some(def_id) = def_id.as_local() {
@@ -348,9 +348,9 @@ fn typeck_with_fallback<'tcx>(
 ) -> &'tcx ty::TypeckResults<'tcx> {
     // Closures' typeck results come from their outermost function,
     // as they are part of the same "inference environment".
-    let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
-    if outer_def_id != def_id {
-        return tcx.typeck(outer_def_id);
+    let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()).expect_local();
+    if typeck_root_def_id != def_id {
+        return tcx.typeck(typeck_root_def_id);
     }
 
     let id = tcx.hir().local_def_id_to_hir_id(def_id);
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index dd094745331..9c53a1d4eb6 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -826,10 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.obligation_for_method(span, trait_did, lhs_ty, Some(other_tys));
                 let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
                 fulfill.register_predicate_obligation(self, obligation);
-                Err(match fulfill.select_where_possible(&self.infcx) {
-                    Err(errors) => errors,
-                    _ => vec![],
-                })
+                Err(fulfill.select_where_possible(&self.infcx))
             }
         }
     }
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 5aa11cce25f..cbf33cf1b78 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -292,7 +292,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // String and byte-string literals result in types `&str` and `&[u8]` respectively.
             // All other literals result in non-reference types.
             // As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo {}`.
-            PatKind::Lit(lt) => match self.check_expr(lt).kind() {
+            //
+            // Call `resolve_vars_if_possible` here for inline const blocks.
+            PatKind::Lit(lt) => match self.resolve_vars_if_possible(self.check_expr(lt)).kind() {
                 ty::Ref(..) => AdjustMode::Pass,
                 _ => AdjustMode::Peel,
             },
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 86d4e4d2b11..d2d8b14dd96 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -341,6 +341,29 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.visit_region_obligations(body_id.hir_id);
     }
 
+    fn visit_inline_const(&mut self, id: hir::HirId, body: &'tcx hir::Body<'tcx>) {
+        debug!("visit_inline_const(id={:?})", id);
+
+        // Save state of current function. We will restore afterwards.
+        let old_body_id = self.body_id;
+        let old_body_owner = self.body_owner;
+        let env_snapshot = self.outlives_environment.push_snapshot_pre_typeck_child();
+
+        let body_id = body.id();
+        self.body_id = body_id.hir_id;
+        self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
+
+        self.outlives_environment.save_implied_bounds(body_id.hir_id);
+
+        self.visit_body(body);
+        self.visit_region_obligations(body_id.hir_id);
+
+        // Restore state from previous function.
+        self.outlives_environment.pop_snapshot_post_typeck_child(env_snapshot);
+        self.body_id = old_body_id;
+        self.body_owner = old_body_owner;
+    }
+
     fn visit_region_obligations(&mut self, hir_id: hir::HirId) {
         debug!("visit_region_obligations: hir_id={:?}", hir_id);
 
@@ -406,13 +429,13 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
         // `visit_fn_body`.  We will restore afterwards.
         let old_body_id = self.body_id;
         let old_body_owner = self.body_owner;
-        let env_snapshot = self.outlives_environment.push_snapshot_pre_closure();
+        let env_snapshot = self.outlives_environment.push_snapshot_pre_typeck_child();
 
         let body = self.tcx.hir().body(body_id);
         self.visit_fn_body(hir_id, body, span);
 
         // Restore state from previous function.
-        self.outlives_environment.pop_snapshot_post_closure(env_snapshot);
+        self.outlives_environment.pop_snapshot_post_typeck_child(env_snapshot);
         self.body_id = old_body_id;
         self.body_owner = old_body_owner;
     }
@@ -460,6 +483,11 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
                 intravisit::walk_expr(self, expr);
             }
 
+            hir::ExprKind::ConstBlock(anon_const) => {
+                let body = self.tcx.hir().body(anon_const.body);
+                self.visit_inline_const(anon_const.hir_id, body);
+            }
+
             _ => intravisit::walk_expr(self, expr),
         }
     }
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 774d8078e52..5f5d308a332 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -148,10 +148,17 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Closure(cc, _, body_id, _, _) = expr.kind {
-            let body = self.fcx.tcx.hir().body(body_id);
-            self.visit_body(body);
-            self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, cc);
+        match expr.kind {
+            hir::ExprKind::Closure(cc, _, body_id, _, _) => {
+                let body = self.fcx.tcx.hir().body(body_id);
+                self.visit_body(body);
+                self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, cc);
+            }
+            hir::ExprKind::ConstBlock(anon_const) => {
+                let body = self.fcx.tcx.hir().body(anon_const.body);
+                self.visit_body(body);
+            }
+            _ => {}
         }
 
         intravisit::walk_expr(self, expr);
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index c1adc2894cc..0050ac99cb1 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1641,19 +1641,38 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) {
 
 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
 /// aren't true.
-fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
+fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirId) {
     let empty_env = ty::ParamEnv::empty();
 
     let def_id = fcx.tcx.hir().local_def_id(id);
-    let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p);
+    let predicates_with_span =
+        fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, span)| (*p, *span));
     // Check elaborated bounds.
-    let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
+    let implied_obligations = traits::elaborate_predicates_with_span(fcx.tcx, predicates_with_span);
 
     for obligation in implied_obligations {
         let pred = obligation.predicate;
         // Match the existing behavior.
         if pred.is_global(fcx.tcx) && !pred.has_late_bound_regions() {
             let pred = fcx.normalize_associated_types_in(span, pred);
+            let hir_node = fcx.tcx.hir().find(id);
+
+            // only use the span of the predicate clause (#90869)
+
+            if let Some(hir::Generics { where_clause, .. }) =
+                hir_node.and_then(|node| node.generics())
+            {
+                let obligation_span = obligation.cause.span(fcx.tcx);
+
+                span = where_clause
+                    .predicates
+                    .iter()
+                    // There seems to be no better way to find out which predicate we are in
+                    .find(|pred| pred.span().contains(obligation_span))
+                    .map(|pred| pred.span())
+                    .unwrap_or(obligation_span);
+            }
+
             let obligation = traits::Obligation::new(
                 traits::ObligationCause::new(span, id, traits::TrivialBound),
                 empty_env,
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index d951df94dcf..fdc8b6b5e64 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -282,6 +282,12 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
             hir::ExprKind::Field(..) => {
                 self.visit_field_id(e.hir_id);
             }
+            hir::ExprKind::ConstBlock(anon_const) => {
+                self.visit_node_id(e.span, anon_const.hir_id);
+
+                let body = self.tcx().hir().body(anon_const.body);
+                self.visit_body(body);
+            }
             _ => {}
         }
 
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index d818771f780..372e83592b9 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -263,7 +263,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                     }
 
                     // Check that all transitive obligations are satisfied.
-                    if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
+                    let errors = fulfill_cx.select_all_or_error(&infcx);
+                    if !errors.is_empty() {
                         infcx.report_fulfillment_errors(&errors, None, false);
                     }
 
@@ -522,7 +523,8 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
         fulfill_cx.register_predicate_obligation(&infcx, predicate);
 
         // Check that all transitive obligations are satisfied.
-        if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
+        let errors = fulfill_cx.select_all_or_error(&infcx);
+        if !errors.is_empty() {
             infcx.report_fulfillment_errors(&errors, None, false);
         }
 
diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs
index 079604f128d..377ebf1fe2a 100644
--- a/compiler/rustc_typeck/src/coherence/mod.rs
+++ b/compiler/rustc_typeck/src/coherence/mod.rs
@@ -168,6 +168,7 @@ pub fn provide(providers: &mut Providers) {
     use self::builtin::coerce_unsized_info;
     use self::inherent_impls::{crate_inherent_impls, inherent_impls};
     use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
+    use self::orphan::orphan_check_crate;
 
     *providers = Providers {
         coherent_trait,
@@ -175,6 +176,7 @@ pub fn provide(providers: &mut Providers) {
         inherent_impls,
         crate_inherent_impls_overlap_check,
         coerce_unsized_info,
+        orphan_check_crate,
         ..*providers
     };
 }
@@ -195,13 +197,13 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
 }
 
 pub fn check_coherence(tcx: TyCtxt<'_>) {
+    tcx.sess.time("unsafety_checking", || unsafety::check(tcx));
+    tcx.ensure().orphan_check_crate(());
+
     for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
         tcx.ensure().coherent_trait(trait_def_id);
     }
 
-    tcx.sess.time("unsafety_checking", || unsafety::check(tcx));
-    tcx.sess.time("orphan_checking", || orphan::check(tcx));
-
     // these queries are executed for side-effects (error reporting):
     tcx.ensure().crate_inherent_impls(());
     tcx.ensure().crate_inherent_impls_overlap_check(());
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 0326d1fd74f..b450d3f6c08 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -2,250 +2,266 @@
 //! crate or pertains to a type defined in this crate.
 
 use rustc_errors::struct_span_err;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::def_id::LocalDefId;
+use rustc_span::Span;
 use rustc_trait_selection::traits;
 
-pub fn check(tcx: TyCtxt<'_>) {
-    let mut orphan = OrphanChecker { tcx };
-    tcx.hir().visit_all_item_likes(&mut orphan);
+pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] {
+    let mut errors = Vec::new();
+    for (_trait, impls_of_trait) in tcx.all_local_trait_impls(()) {
+        for &impl_of_trait in impls_of_trait {
+            match orphan_check_impl(tcx, impl_of_trait) {
+                Ok(()) => {}
+                Err(ErrorReported) => errors.push(impl_of_trait),
+            }
+        }
+    }
+    tcx.arena.alloc_slice(&errors)
 }
 
-struct OrphanChecker<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
+#[instrument(skip(tcx), level = "debug")]
+fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorReported> {
+    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+    let trait_def_id = trait_ref.def_id;
 
-impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
-    /// Checks exactly one impl for orphan rules and other such
-    /// restrictions. In this fn, it can happen that multiple errors
-    /// apply to a specific impl, so just return after reporting one
-    /// to prevent inundating the user with a bunch of similar error
-    /// reports.
-    fn visit_item(&mut self, item: &hir::Item<'_>) {
-        // "Trait" impl
-        if let hir::ItemKind::Impl(hir::Impl {
-            generics, of_trait: Some(ref tr), self_ty, ..
-        }) = &item.kind
-        {
-            debug!(
-                "coherence2::orphan check: trait impl {}",
-                self.tcx.hir().node_to_string(item.hir_id())
-            );
-            let trait_ref = self.tcx.impl_trait_ref(item.def_id).unwrap();
-            let trait_def_id = trait_ref.def_id;
-            let sm = self.tcx.sess.source_map();
-            let sp = sm.guess_head_span(item.span);
-            match traits::orphan_check(self.tcx, item.def_id.to_def_id()) {
-                Ok(()) => {}
-                Err(traits::OrphanCheckErr::NonLocalInputType(tys)) => {
-                    let mut err = struct_span_err!(
-                        self.tcx.sess,
-                        sp,
-                        E0117,
-                        "only traits defined in the current crate can be implemented for \
-                         arbitrary types"
-                    );
-                    err.span_label(sp, "impl doesn't use only types from inside the current crate");
-                    for (ty, is_target_ty) in &tys {
-                        let mut ty = *ty;
-                        self.tcx.infer_ctxt().enter(|infcx| {
-                            // Remove the lifetimes unnecessary for this error.
-                            ty = infcx.freshen(ty);
-                        });
-                        ty = match ty.kind() {
-                            // Remove the type arguments from the output, as they are not relevant.
-                            // You can think of this as the reverse of `resolve_vars_if_possible`.
-                            // That way if we had `Vec<MyType>`, we will properly attribute the
-                            // problem to `Vec<T>` and avoid confusing the user if they were to see
-                            // `MyType` in the error.
-                            ty::Adt(def, _) => self.tcx.mk_adt(def, ty::List::empty()),
-                            _ => ty,
-                        };
-                        let this = "this".to_string();
-                        let (ty, postfix) = match &ty.kind() {
-                            ty::Slice(_) => (this, " because slices are always foreign"),
-                            ty::Array(..) => (this, " because arrays are always foreign"),
-                            ty::Tuple(..) => (this, " because tuples are always foreign"),
-                            _ => (format!("`{}`", ty), ""),
-                        };
-                        let msg = format!("{} is not defined in the current crate{}", ty, postfix);
-                        if *is_target_ty {
-                            // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
-                            err.span_label(self_ty.span, &msg);
-                        } else {
-                            // Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
-                            err.span_label(tr.path.span, &msg);
-                        }
-                    }
-                    err.note("define and implement a trait or new type instead");
-                    err.emit();
-                    return;
-                }
-                Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => {
-                    let mut sp = sp;
-                    for param in generics.params {
-                        if param.name.ident().to_string() == param_ty.to_string() {
-                            sp = param.span;
-                        }
-                    }
+    let item = tcx.hir().item(hir::ItemId { def_id });
+    let impl_ = match item.kind {
+        hir::ItemKind::Impl(ref impl_) => impl_,
+        _ => bug!("{:?} is not an impl: {:?}", def_id, item),
+    };
+    let sp = tcx.sess.source_map().guess_head_span(item.span);
+    let tr = impl_.of_trait.as_ref().unwrap();
+    match traits::orphan_check(tcx, item.def_id.to_def_id()) {
+        Ok(()) => {}
+        Err(err) => emit_orphan_check_error(
+            tcx,
+            sp,
+            tr.path.span,
+            impl_.self_ty.span,
+            &impl_.generics,
+            err,
+        )?,
+    }
+
+    // In addition to the above rules, we restrict impls of auto traits
+    // so that they can only be implemented on nominal types, such as structs,
+    // enums or foreign types. To see why this restriction exists, consider the
+    // following example (#22978). Imagine that crate A defines an auto trait
+    // `Foo` and a fn that operates on pairs of types:
+    //
+    // ```
+    // // Crate A
+    // auto trait Foo { }
+    // fn two_foos<A:Foo,B:Foo>(..) {
+    //     one_foo::<(A,B)>(..)
+    // }
+    // fn one_foo<T:Foo>(..) { .. }
+    // ```
+    //
+    // This type-checks fine; in particular the fn
+    // `two_foos` is able to conclude that `(A,B):Foo`
+    // because `A:Foo` and `B:Foo`.
+    //
+    // Now imagine that crate B comes along and does the following:
+    //
+    // ```
+    // struct A { }
+    // struct B { }
+    // impl Foo for A { }
+    // impl Foo for B { }
+    // impl !Send for (A, B) { }
+    // ```
+    //
+    // This final impl is legal according to the orphan
+    // rules, but it invalidates the reasoning from
+    // `two_foos` above.
+    debug!(
+        "trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
+        trait_ref,
+        trait_def_id,
+        tcx.trait_is_auto(trait_def_id)
+    );
+
+    if tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() {
+        let self_ty = trait_ref.self_ty();
+        let opt_self_def_id = match *self_ty.kind() {
+            ty::Adt(self_def, _) => Some(self_def.did),
+            ty::Foreign(did) => Some(did),
+            _ => None,
+        };
 
-                    match local_type {
-                        Some(local_type) => {
-                            struct_span_err!(
-                                self.tcx.sess,
-                                sp,
-                                E0210,
-                                "type parameter `{}` must be covered by another type \
-                                when it appears before the first local type (`{}`)",
-                                param_ty,
-                                local_type
-                            )
-                            .span_label(
-                                sp,
-                                format!(
-                                    "type parameter `{}` must be covered by another type \
-                                when it appears before the first local type (`{}`)",
-                                    param_ty, local_type
-                                ),
-                            )
-                            .note(
-                                "implementing a foreign trait is only possible if at \
-                                    least one of the types for which it is implemented is local, \
-                                    and no uncovered type parameters appear before that first \
-                                    local type",
-                            )
-                            .note(
-                                "in this case, 'before' refers to the following order: \
-                                    `impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
-                                    where `T0` is the first and `Tn` is the last",
-                            )
-                            .emit();
-                        }
-                        None => {
-                            struct_span_err!(
-                                self.tcx.sess,
-                                sp,
-                                E0210,
-                                "type parameter `{}` must be used as the type parameter for some \
-                                local type (e.g., `MyStruct<{}>`)",
-                                param_ty,
-                                param_ty
-                            ).span_label(sp, format!(
-                                "type parameter `{}` must be used as the type parameter for some \
-                                local type",
-                                param_ty,
-                            )).note("implementing a foreign trait is only possible if at \
-                                    least one of the types for which it is implemented is local"
-                            ).note("only traits defined in the current crate can be \
-                                    implemented for a type parameter"
-                            ).emit();
-                        }
-                    };
-                    return;
+        let msg = match opt_self_def_id {
+            // We only want to permit nominal types, but not *all* nominal types.
+            // They must be local to the current crate, so that people
+            // can't do `unsafe impl Send for Rc<SomethingLocal>` or
+            // `impl !Send for Box<SomethingLocalAndSend>`.
+            Some(self_def_id) => {
+                if self_def_id.is_local() {
+                    None
+                } else {
+                    Some((
+                        format!(
+                            "cross-crate traits with a default impl, like `{}`, \
+                                    can only be implemented for a struct/enum type \
+                                    defined in the current crate",
+                            tcx.def_path_str(trait_def_id)
+                        ),
+                        "can't implement cross-crate trait for type in another crate",
+                    ))
                 }
             }
+            _ => Some((
+                format!(
+                    "cross-crate traits with a default impl, like `{}`, can \
+                                only be implemented for a struct/enum type, not `{}`",
+                    tcx.def_path_str(trait_def_id),
+                    self_ty
+                ),
+                "can't implement cross-crate trait with a default impl for \
+                        non-struct/enum type",
+            )),
+        };
 
-            // In addition to the above rules, we restrict impls of auto traits
-            // so that they can only be implemented on nominal types, such as structs,
-            // enums or foreign types. To see why this restriction exists, consider the
-            // following example (#22978). Imagine that crate A defines an auto trait
-            // `Foo` and a fn that operates on pairs of types:
-            //
-            // ```
-            // // Crate A
-            // auto trait Foo { }
-            // fn two_foos<A:Foo,B:Foo>(..) {
-            //     one_foo::<(A,B)>(..)
-            // }
-            // fn one_foo<T:Foo>(..) { .. }
-            // ```
-            //
-            // This type-checks fine; in particular the fn
-            // `two_foos` is able to conclude that `(A,B):Foo`
-            // because `A:Foo` and `B:Foo`.
-            //
-            // Now imagine that crate B comes along and does the following:
-            //
-            // ```
-            // struct A { }
-            // struct B { }
-            // impl Foo for A { }
-            // impl Foo for B { }
-            // impl !Send for (A, B) { }
-            // ```
-            //
-            // This final impl is legal according to the orphan
-            // rules, but it invalidates the reasoning from
-            // `two_foos` above.
-            debug!(
-                "trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
-                trait_ref,
-                trait_def_id,
-                self.tcx.trait_is_auto(trait_def_id)
+        if let Some((msg, label)) = msg {
+            struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit();
+            return Err(ErrorReported);
+        }
+    }
+
+    if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() {
+        tcx.sess
+            .struct_span_err(sp, "cannot implement trait on type alias impl trait")
+            .span_note(tcx.def_span(def_id), "type alias impl trait defined here")
+            .emit();
+        return Err(ErrorReported);
+    }
+
+    Ok(())
+}
+
+fn emit_orphan_check_error(
+    tcx: TyCtxt<'tcx>,
+    sp: Span,
+    trait_span: Span,
+    self_ty_span: Span,
+    generics: &hir::Generics<'tcx>,
+    err: traits::OrphanCheckErr<'tcx>,
+) -> Result<!, ErrorReported> {
+    match err {
+        traits::OrphanCheckErr::NonLocalInputType(tys) => {
+            let mut err = struct_span_err!(
+                tcx.sess,
+                sp,
+                E0117,
+                "only traits defined in the current crate can be implemented for \
+                        arbitrary types"
             );
-            if self.tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() {
-                let self_ty = trait_ref.self_ty();
-                let opt_self_def_id = match *self_ty.kind() {
-                    ty::Adt(self_def, _) => Some(self_def.did),
-                    ty::Foreign(did) => Some(did),
-                    _ => None,
+            err.span_label(sp, "impl doesn't use only types from inside the current crate");
+            for (ty, is_target_ty) in &tys {
+                let mut ty = *ty;
+                tcx.infer_ctxt().enter(|infcx| {
+                    // Remove the lifetimes unnecessary for this error.
+                    ty = infcx.freshen(ty);
+                });
+                ty = match ty.kind() {
+                    // Remove the type arguments from the output, as they are not relevant.
+                    // You can think of this as the reverse of `resolve_vars_if_possible`.
+                    // That way if we had `Vec<MyType>`, we will properly attribute the
+                    // problem to `Vec<T>` and avoid confusing the user if they were to see
+                    // `MyType` in the error.
+                    ty::Adt(def, _) => tcx.mk_adt(def, ty::List::empty()),
+                    _ => ty,
                 };
-
-                let msg = match opt_self_def_id {
-                    // We only want to permit nominal types, but not *all* nominal types.
-                    // They must be local to the current crate, so that people
-                    // can't do `unsafe impl Send for Rc<SomethingLocal>` or
-                    // `impl !Send for Box<SomethingLocalAndSend>`.
-                    Some(self_def_id) => {
-                        if self_def_id.is_local() {
-                            None
-                        } else {
-                            Some((
-                                format!(
-                                    "cross-crate traits with a default impl, like `{}`, \
-                                         can only be implemented for a struct/enum type \
-                                         defined in the current crate",
-                                    self.tcx.def_path_str(trait_def_id)
-                                ),
-                                "can't implement cross-crate trait for type in another crate",
-                            ))
-                        }
-                    }
-                    _ => Some((
-                        format!(
-                            "cross-crate traits with a default impl, like `{}`, can \
-                                       only be implemented for a struct/enum type, not `{}`",
-                            self.tcx.def_path_str(trait_def_id),
-                            self_ty
-                        ),
-                        "can't implement cross-crate trait with a default impl for \
-                               non-struct/enum type",
-                    )),
+                let this = "this".to_string();
+                let (ty, postfix) = match &ty.kind() {
+                    ty::Slice(_) => (this, " because slices are always foreign"),
+                    ty::Array(..) => (this, " because arrays are always foreign"),
+                    ty::Tuple(..) => (this, " because tuples are always foreign"),
+                    _ => (format!("`{}`", ty), ""),
                 };
-
-                if let Some((msg, label)) = msg {
-                    struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
-                        .span_label(sp, label)
-                        .emit();
-                    return;
+                let msg = format!("{} is not defined in the current crate{}", ty, postfix);
+                if *is_target_ty {
+                    // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
+                    err.span_label(self_ty_span, &msg);
+                } else {
+                    // Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
+                    err.span_label(trait_span, &msg);
+                }
+            }
+            err.note("define and implement a trait or new type instead");
+            err.emit()
+        }
+        traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
+            let mut sp = sp;
+            for param in generics.params {
+                if param.name.ident().to_string() == param_ty.to_string() {
+                    sp = param.span;
                 }
             }
 
-            if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() {
-                self.tcx
-                    .sess
-                    .struct_span_err(sp, "cannot implement trait on type alias impl trait")
-                    .span_note(self.tcx.def_span(def_id), "type alias impl trait defined here")
-                    .emit();
+            match local_type {
+                Some(local_type) => struct_span_err!(
+                    tcx.sess,
+                    sp,
+                    E0210,
+                    "type parameter `{}` must be covered by another type \
+                    when it appears before the first local type (`{}`)",
+                    param_ty,
+                    local_type
+                )
+                .span_label(
+                    sp,
+                    format!(
+                        "type parameter `{}` must be covered by another type \
+                    when it appears before the first local type (`{}`)",
+                        param_ty, local_type
+                    ),
+                )
+                .note(
+                    "implementing a foreign trait is only possible if at \
+                        least one of the types for which it is implemented is local, \
+                        and no uncovered type parameters appear before that first \
+                        local type",
+                )
+                .note(
+                    "in this case, 'before' refers to the following order: \
+                        `impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
+                        where `T0` is the first and `Tn` is the last",
+                )
+                .emit(),
+                None => struct_span_err!(
+                    tcx.sess,
+                    sp,
+                    E0210,
+                    "type parameter `{}` must be used as the type parameter for some \
+                    local type (e.g., `MyStruct<{}>`)",
+                    param_ty,
+                    param_ty
+                )
+                .span_label(
+                    sp,
+                    format!(
+                        "type parameter `{}` must be used as the type parameter for some \
+                    local type",
+                        param_ty,
+                    ),
+                )
+                .note(
+                    "implementing a foreign trait is only possible if at \
+                        least one of the types for which it is implemented is local",
+                )
+                .note(
+                    "only traits defined in the current crate can be \
+                        implemented for a type parameter",
+                )
+                .emit(),
             }
         }
     }
 
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
-
-    fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
+    Err(ErrorReported)
 }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 18e8ed394e8..2f427305782 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -28,7 +28,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, DefKind, Res};
+use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::weak_lang_items;
@@ -668,6 +668,7 @@ impl ItemCtxt<'tcx> {
             })
             .flat_map(|b| predicates_from_bound(self, ty, b));
 
+        let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
         let from_where_clauses = ast_generics
             .where_clause
             .predicates
@@ -677,7 +678,7 @@ impl ItemCtxt<'tcx> {
                 _ => None,
             })
             .flat_map(|bp| {
-                let bt = if is_param(self.tcx, bp.bounded_ty, param_id) {
+                let bt = if bp.is_param_bound(param_def_id) {
                     Some(ty)
                 } else if !only_self_bounds.0 {
                     Some(self.to_ty(bp.bounded_ty))
@@ -714,23 +715,6 @@ impl ItemCtxt<'tcx> {
     }
 }
 
-/// Tests whether this is the AST for a reference to the type
-/// parameter with ID `param_id`. We use this so as to avoid running
-/// `ast_ty_to_ty`, because we want to avoid triggering an all-out
-/// conversion of the type to avoid inducing unnecessary cycles.
-fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty<'_>, param_id: hir::HirId) -> bool {
-    if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ast_ty.kind {
-        match path.res {
-            Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => {
-                def_id == tcx.hir().local_def_id(param_id).to_def_id()
-            }
-            _ => false,
-        }
-    } else {
-        false
-    }
-}
-
 fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
     let it = tcx.hir().item(item_id);
     debug!("convert: item {} with id {}", it.ident, it.hir_id());
@@ -1494,13 +1478,15 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                     {
                         Some(parent_def_id.to_def_id())
                     }
-
+                    Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
+                        Some(tcx.typeck_root_def_id(def_id))
+                    }
                     _ => None,
                 }
             }
         }
         Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
-            Some(tcx.closure_base_def_id(def_id))
+            Some(tcx.typeck_root_def_id(def_id))
         }
         Node::Item(item) => match item.kind {
             ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
@@ -1692,6 +1678,24 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
         }));
     }
 
+    // provide junk type parameter defs for const blocks.
+    if let Node::AnonConst(_) = node {
+        let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
+        if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node {
+            params.push(ty::GenericParamDef {
+                index: type_start,
+                name: Symbol::intern("<const_ty>"),
+                def_id,
+                pure_wrt_drop: false,
+                kind: ty::GenericParamDefKind::Type {
+                    has_default: false,
+                    object_lifetime_default: rl::Set1::Empty,
+                    synthetic: None,
+                },
+            });
+        }
+    }
+
     let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect();
 
     ty::Generics {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index a6ea8abdf3f..04a68250ced 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -494,7 +494,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })
                     if anon_const.hir_id == hir_id =>
                 {
-                    tcx.typeck(def_id).node_type(anon_const.hir_id)
+                    let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+                    substs.as_inline_const().ty()
                 }
 
                 Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs
index 39bcf899932..a49eda6572d 100644
--- a/compiler/rustc_typeck/src/hir_wf_check.rs
+++ b/compiler/rustc_typeck/src/hir_wf_check.rs
@@ -88,7 +88,8 @@ fn diagnostic_hir_wf_check<'tcx>(
                     ),
                 );
 
-                if let Err(errors) = fulfill.select_all_or_error(&infcx) {
+                let errors = fulfill.select_all_or_error(&infcx);
+                if !errors.is_empty() {
                     tracing::debug!("Wf-check got errors for {:?}: {:?}", ty, errors);
                     for error in errors {
                         if error.obligation.predicate == self.predicate {
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index f90cfb88491..0881cf07586 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -58,7 +58,7 @@ This API is completely unstable and subject to change.
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(if_let_guard)]
 #![feature(in_band_lifetimes)]
 #![feature(is_sorted)]
@@ -157,10 +157,10 @@ fn require_same_types<'tcx>(
             }
         }
 
-        match fulfill_cx.select_all_or_error(infcx) {
-            Ok(()) => true,
-            Err(errors) => {
-                infcx.report_fulfillment_errors(&errors, None, false);
+        match fulfill_cx.select_all_or_error(infcx).as_slice() {
+            [] => true,
+            errors => {
+                infcx.report_fulfillment_errors(errors, None, false);
                 false
             }
         }
@@ -352,8 +352,9 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
                 term_id,
                 cause,
             );
-            if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-                infcx.report_fulfillment_errors(&err, None, false);
+            let errors = fulfillment_cx.select_all_or_error(&infcx);
+            if !errors.is_empty() {
+                infcx.report_fulfillment_errors(&errors, None, false);
                 error = true;
             }
         });
diff --git a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
index 4ab5fe26abe..91727d57ddf 100644
--- a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
+++ b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs
@@ -83,7 +83,8 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
         // variables. Process these constraints.
         let mut fulfill_cx = FulfillmentContext::new();
         fulfill_cx.register_predicate_obligations(self, result.obligations);
-        if fulfill_cx.select_all_or_error(self).is_err() {
+        let errors = fulfill_cx.select_all_or_error(self);
+        if !errors.is_empty() {
             self.tcx.sess.delay_span_bug(
                 span,
                 "implied_outlives_bounds failed to solve obligations from instantiation",