about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-25 22:33:35 +0000
committerbors <bors@rust-lang.org>2024-06-25 22:33:35 +0000
commitfc94ce216ede9f89a1032b13e2563ddba0ae4194 (patch)
treee520b53ebf7d874cc6dfdc2aa17257bb9ff8dac8 /compiler
parent8a8b357bf11ed4f7ba28916c5975f74dde55f0ea (diff)
parent8f688d2634b10da6c6a91a57bf8f39557c333b31 (diff)
downloadrust-fc94ce216ede9f89a1032b13e2563ddba0ae4194.tar.gz
rust-fc94ce216ede9f89a1032b13e2563ddba0ae4194.zip
Auto merge of #3711 - saethlin:rustup, r=saethlin
Manual Rustup

This bumps us to a rustc commit that doesn't have the chatty `./miri fmt` reported in https://rust-lang.zulipchat.com/#narrow/stream/269128-miri/topic/.22rewriting.20static.22.20printed.20during.20.2E.2Fmiri.20build
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_abi/src/lib.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs42
-rw-r--r--compiler/rustc_ast/src/visit.rs18
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs14
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs77
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs2
-rw-r--r--compiler/rustc_borrowck/src/used_muts.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs140
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs3
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs7
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/sip128.rs2
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs71
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs35
-rw-r--r--compiler/rustc_errors/src/emitter.rs27
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs32
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/hir_id.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs4
-rw-r--r--compiler/rustc_interface/src/interface.rs21
-rw-r--r--compiler/rustc_interface/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs145
-rw-r--r--compiler/rustc_interface/src/queries.rs137
-rw-r--r--compiler/rustc_lint/messages.ftl3
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs7
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs39
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs3
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs8
-rw-r--r--compiler/rustc_middle/src/ty/context.rs10
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs25
-rw-r--r--compiler/rustc_middle/src/ty/list.rs14
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs13
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs7
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs13
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs10
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs61
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs47
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/inspect/build.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs27
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs17
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs13
-rw-r--r--compiler/rustc_passes/messages.ftl15
-rw-r--r--compiler/rustc_passes/src/check_attr.rs42
-rw-r--r--compiler/rustc_passes/src/dead.rs19
-rw-r--r--compiler/rustc_passes/src/errors.rs16
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs5
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs19
-rw-r--r--compiler/rustc_resolve/src/macros.rs87
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs7
-rw-r--r--compiler/rustc_session/src/config.rs6
-rw-r--r--compiler/rustc_session/src/options.rs3
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs2
-rw-r--r--compiler/rustc_span/src/def_id.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs46
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs40
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_type_ir/src/binder.rs35
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs12
-rw-r--r--compiler/rustc_type_ir/src/fold.rs6
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs115
-rw-r--r--compiler/rustc_type_ir/src/interner.rs28
-rw-r--r--compiler/rustc_type_ir/src/opaque_ty.rs10
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs50
-rw-r--r--compiler/rustc_type_ir/src/predicate_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/relate.rs30
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs21
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs18
121 files changed, 1221 insertions, 798 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index a6662d4e0e4..31c66a56bea 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -427,11 +427,13 @@ pub struct Size {
     raw: u64,
 }
 
-// Safety: Ord is implement as just comparing numerical values and numerical values
-// are not changed by (de-)serialization.
 #[cfg(feature = "nightly")]
-unsafe impl StableOrd for Size {
+impl StableOrd for Size {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // `Ord` is implemented as just comparing numerical values and numerical values
+    // are not changed by (de-)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 // This is debug-printed a lot in larger structs, don't waste too much space there
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index c9d2f5c779b..ed8bf58eb23 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -429,10 +429,10 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>(
 ) -> SmallVec<[PatField; 1]> {
     let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp;
     vis.visit_id(id);
+    visit_attrs(attrs, vis);
     vis.visit_ident(ident);
     vis.visit_pat(pat);
     vis.visit_span(span);
-    visit_attrs(attrs, vis);
     smallvec![fp]
 }
 
@@ -443,8 +443,8 @@ fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
         UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
         UseTreeKind::Nested { items, .. } => {
             for (tree, id) in items {
-                vis.visit_use_tree(tree);
                 vis.visit_id(id);
+                vis.visit_use_tree(tree);
             }
         }
         UseTreeKind::Glob => {}
@@ -454,8 +454,8 @@ fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
 
 pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
     let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
-    visit_attrs(attrs, vis);
     vis.visit_id(id);
+    visit_attrs(attrs, vis);
     vis.visit_pat(pat);
     visit_opt(guard, |guard| vis.visit_expr(guard));
     visit_opt(body, |body| vis.visit_expr(body));
@@ -548,10 +548,10 @@ pub fn noop_flat_map_variant<T: MutVisitor>(
     visitor: &mut T,
 ) -> SmallVec<[Variant; 1]> {
     let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
+    visitor.visit_id(id);
+    visit_attrs(attrs, visitor);
     visitor.visit_ident(ident);
     visitor.visit_vis(vis);
-    visit_attrs(attrs, visitor);
-    visitor.visit_id(id);
     visitor.visit_variant_data(data);
     visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
     visitor.visit_span(span);
@@ -565,8 +565,8 @@ fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mu
 fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) {
     vis.visit_span(span);
     for PathSegment { ident, id, args } in segments {
-        vis.visit_ident(ident);
         vis.visit_id(id);
+        vis.visit_ident(ident);
         visit_opt(args, |args| vis.visit_generic_args(args));
     }
     visit_lazy_tts(tokens, vis);
@@ -620,6 +620,7 @@ fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(
 fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
     let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut();
     vis.visit_id(id);
+    visit_attrs(attrs, vis);
     vis.visit_pat(pat);
     visit_opt(ty, |ty| vis.visit_ty(ty));
     match kind {
@@ -634,7 +635,6 @@ fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
     }
     vis.visit_span(span);
     visit_opt(colon_sp, |sp| vis.visit_span(sp));
-    visit_attrs(attrs, vis);
     visit_lazy_tts(tokens, vis);
 }
 
@@ -894,9 +894,9 @@ fn noop_visit_coroutine_kind<T: MutVisitor>(coroutine_kind: &mut CoroutineKind,
         CoroutineKind::Async { span, closure_id, return_impl_trait_id }
         | CoroutineKind::Gen { span, closure_id, return_impl_trait_id }
         | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => {
-            vis.visit_span(span);
             vis.visit_id(closure_id);
             vis.visit_id(return_impl_trait_id);
+            vis.visit_span(span);
         }
     }
 }
@@ -932,8 +932,8 @@ fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturingArg
             vis.visit_lifetime(lt);
         }
         PreciseCapturingArg::Arg(path, id) => {
-            vis.visit_path(path);
             vis.visit_id(id);
+            vis.visit_path(path);
         }
     }
 }
@@ -944,11 +944,11 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
 ) -> SmallVec<[GenericParam; 1]> {
     let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
     vis.visit_id(id);
+    visit_attrs(attrs, vis);
     vis.visit_ident(ident);
     if let Some(colon_span) = colon_span {
         vis.visit_span(colon_span);
     }
-    visit_attrs(attrs, vis);
     visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
     match kind {
         GenericParamKind::Lifetime => {}
@@ -1015,16 +1015,16 @@ fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T)
             fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
         }
         VariantData::Tuple(fields, id) => {
-            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
             vis.visit_id(id);
+            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
         }
         VariantData::Unit(id) => vis.visit_id(id),
     }
 }
 
 fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) {
-    vis.visit_path(path);
     vis.visit_id(ref_id);
+    vis.visit_path(path);
 }
 
 fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) {
@@ -1039,12 +1039,12 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
     visitor: &mut T,
 ) -> SmallVec<[FieldDef; 1]> {
     let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
+    visitor.visit_id(id);
+    visit_attrs(attrs, visitor);
     visitor.visit_span(span);
     visit_opt(ident, |ident| visitor.visit_ident(ident));
     visitor.visit_vis(vis);
-    visitor.visit_id(id);
     visitor.visit_ty(ty);
-    visit_attrs(attrs, visitor);
     smallvec![fd]
 }
 
@@ -1053,11 +1053,11 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>(
     vis: &mut T,
 ) -> SmallVec<[ExprField; 1]> {
     let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f;
+    vis.visit_id(id);
+    visit_attrs(attrs, vis);
     vis.visit_ident(ident);
     vis.visit_expr(expr);
-    vis.visit_id(id);
     vis.visit_span(span);
-    visit_attrs(attrs, vis);
     smallvec![f]
 }
 
@@ -1429,6 +1429,8 @@ pub fn noop_visit_expr<T: MutVisitor>(
     Expr { kind, id, span, attrs, tokens }: &mut Expr,
     vis: &mut T,
 ) {
+    vis.visit_id(id);
+    visit_attrs(attrs, vis);
     match kind {
         ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
         ExprKind::ConstBlock(anon_const) => {
@@ -1449,8 +1451,8 @@ pub fn noop_visit_expr<T: MutVisitor>(
             args: call_args,
             span,
         }) => {
-            vis.visit_ident(ident);
             vis.visit_id(id);
+            vis.visit_ident(ident);
             visit_opt(seg_args, |args| vis.visit_generic_args(args));
             vis.visit_method_receiver_expr(receiver);
             visit_thin_exprs(call_args, vis);
@@ -1601,9 +1603,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
         ExprKind::TryBlock(body) => vis.visit_block(body),
         ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {}
     }
-    vis.visit_id(id);
     vis.visit_span(span);
-    visit_attrs(attrs, vis);
     visit_lazy_tts(tokens, vis);
 }
 
@@ -1645,8 +1645,8 @@ fn noop_flat_map_stmt_kind<T: MutVisitor>(kind: StmtKind, vis: &mut T) -> SmallV
         StmtKind::Empty => smallvec![StmtKind::Empty],
         StmtKind::MacCall(mut mac) => {
             let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
-            vis.visit_mac_call(mac_);
             visit_attrs(attrs, vis);
+            vis.visit_mac_call(mac_);
             visit_lazy_tts(tokens, vis);
             smallvec![StmtKind::MacCall(mac)]
         }
@@ -1657,8 +1657,8 @@ fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) {
     match &mut visibility.kind {
         VisibilityKind::Public | VisibilityKind::Inherited => {}
         VisibilityKind::Restricted { path, id, shorthand: _ } => {
-            vis.visit_path(path);
             vis.visit_id(id);
+            vis.visit_path(path);
         }
     }
     vis.visit_span(&mut visibility.span);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ce38a67ea69..e2ef0542bf9 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -298,8 +298,8 @@ pub trait Visitor<'ast>: Sized {
 }
 
 pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
-    walk_list!(visitor, visit_item, &krate.items);
     walk_list!(visitor, visit_attribute, &krate.attrs);
+    walk_list!(visitor, visit_item, &krate.items);
     V::Result::output()
 }
 
@@ -462,25 +462,25 @@ pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -
 where
     V: Visitor<'a>,
 {
+    walk_list!(visitor, visit_attribute, &variant.attrs);
     try_visit!(visitor.visit_ident(variant.ident));
     try_visit!(visitor.visit_vis(&variant.vis));
     try_visit!(visitor.visit_variant_data(&variant.data));
     visit_opt!(visitor, visit_variant_discr, &variant.disr_expr);
-    walk_list!(visitor, visit_attribute, &variant.attrs);
     V::Result::output()
 }
 
 pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result {
+    walk_list!(visitor, visit_attribute, &f.attrs);
     try_visit!(visitor.visit_expr(&f.expr));
     try_visit!(visitor.visit_ident(f.ident));
-    walk_list!(visitor, visit_attribute, &f.attrs);
     V::Result::output()
 }
 
 pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result {
+    walk_list!(visitor, visit_attribute, &fp.attrs);
     try_visit!(visitor.visit_ident(fp.ident));
     try_visit!(visitor.visit_pat(&fp.pat));
-    walk_list!(visitor, visit_attribute, &fp.attrs);
     V::Result::output()
 }
 
@@ -722,8 +722,8 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(
     visitor: &mut V,
     param: &'a GenericParam,
 ) -> V::Result {
-    try_visit!(visitor.visit_ident(param.ident));
     walk_list!(visitor, visit_attribute, &param.attrs);
+    try_visit!(visitor.visit_ident(param.ident));
     walk_list!(visitor, visit_param_bound, &param.bounds, BoundKind::Bound);
     match &param.kind {
         GenericParamKind::Lifetime => (),
@@ -882,10 +882,10 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
     ctxt: AssocCtxt,
 ) -> V::Result {
     let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
+    walk_list!(visitor, visit_attribute, attrs);
     try_visit!(visitor.visit_vis(vis));
     try_visit!(visitor.visit_ident(ident));
     try_visit!(kind.walk(item, ctxt, visitor));
-    walk_list!(visitor, visit_attribute, attrs);
     V::Result::output()
 }
 
@@ -898,10 +898,10 @@ pub fn walk_struct_def<'a, V: Visitor<'a>>(
 }
 
 pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result {
+    walk_list!(visitor, visit_attribute, &field.attrs);
     try_visit!(visitor.visit_vis(&field.vis));
     visit_opt!(visitor, visit_ident, field.ident);
     try_visit!(visitor.visit_ty(&field.ty));
-    walk_list!(visitor, visit_attribute, &field.attrs);
     V::Result::output()
 }
 
@@ -918,8 +918,8 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V:
         StmtKind::Empty => {}
         StmtKind::MacCall(mac) => {
             let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac;
-            try_visit!(visitor.visit_mac_call(mac));
             walk_list!(visitor, visit_attribute, attrs);
+            try_visit!(visitor.visit_mac_call(mac));
         }
     }
     V::Result::output()
@@ -1141,10 +1141,10 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::R
 }
 
 pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result {
+    walk_list!(visitor, visit_attribute, &arm.attrs);
     try_visit!(visitor.visit_pat(&arm.pat));
     visit_opt!(visitor, visit_expr, &arm.guard);
     visit_opt!(visitor, visit_expr, &arm.body);
-    walk_list!(visitor, visit_attribute, &arm.attrs);
     V::Result::output()
 }
 
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 8a2936c2657..f26f8711dd4 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -6,7 +6,7 @@ use rustc_middle::span_bug;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
-impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
         self.infcx.dcx()
     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 5e10f14f31b..d46febffba8 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -52,7 +52,7 @@ impl<'tcx> UniverseInfo<'tcx> {
 
     pub(crate) fn report_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         placeholder: ty::PlaceholderRegion,
         error_element: RegionElement,
         cause: ObligationCause<'tcx>,
@@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
@@ -160,7 +160,7 @@ trait TypeOpInfo<'tcx> {
     #[instrument(level = "debug", skip(self, mbcx))]
     fn report_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         placeholder: ty::PlaceholderRegion,
         error_element: RegionElement,
         cause: ObligationCause<'tcx>,
@@ -233,7 +233,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
@@ -270,7 +270,7 @@ where
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
@@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
@@ -336,7 +336,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
 
     fn nice_error(
         &self,
-        mbcx: &mut MirBorrowckCtxt<'_, 'tcx>,
+        mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
         _cause: ObligationCause<'tcx>,
         placeholder_region: ty::Region<'tcx>,
         error_region: Option<ty::Region<'tcx>>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 197da3eb641..1cc7fee718e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> {
     Destructor(Ty<'tcx>),
 }
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     pub(crate) fn report_use_of_moved_or_uninitialized(
         &mut self,
         location: Location,
@@ -4243,7 +4243,11 @@ enum AnnotatedBorrowFnSignature<'tcx> {
 impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
     /// Annotate the provided diagnostic with information about borrow from the fn signature that
     /// helps explain.
-    pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, 'tcx>, diag: &mut Diag<'_>) -> String {
+    pub(crate) fn emit(
+        &self,
+        cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>,
+        diag: &mut Diag<'_>,
+    ) -> String {
         match self {
             &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
                 diag.span_label(
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index e3ad92a5b2b..6165a718a30 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -389,7 +389,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
     }
 }
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     fn free_region_constraint_info(
         &self,
         borrow_region: RegionVid,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 5b4269caccb..842ed38f1e2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt {
 
 pub(super) struct IncludingTupleField(pub(super) bool);
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
     /// is moved after being invoked.
     ///
@@ -771,7 +771,7 @@ struct CapturedMessageOpt {
     maybe_reinitialized_locations_is_empty: bool,
 }
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     /// Finds the spans associated to a move or copy of move_place at location.
     pub(super) fn move_spans(
         &self,
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 5a7bca9ab03..12fa4c4f5ee 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> {
     },
 }
 
-impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     pub(crate) fn report_move_errors(&mut self) {
         let grouped_errors = self.group_move_errors();
         for error in grouped_errors {
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index e0b18536dd5..93fac3181ba 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -30,7 +30,7 @@ pub(crate) enum AccessKind {
     Mutate,
 }
 
-impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     pub(crate) fn report_mutability_error(
         &mut self,
         access_place: Place<'tcx>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index 1a42e551597..082111a642c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -75,7 +75,7 @@ impl OutlivesSuggestionBuilder {
     /// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
     fn region_vid_to_name(
         &self,
-        mbcx: &MirBorrowckCtxt<'_, '_>,
+        mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
         region: RegionVid,
     ) -> Option<RegionName> {
         mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable)
@@ -84,7 +84,7 @@ impl OutlivesSuggestionBuilder {
     /// Compiles a list of all suggestions to be printed in the final big suggestion.
     fn compile_all_suggestions(
         &self,
-        mbcx: &MirBorrowckCtxt<'_, '_>,
+        mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
     ) -> SmallVec<[SuggestedConstraint; 2]> {
         let mut suggested = SmallVec::new();
 
@@ -160,7 +160,7 @@ impl OutlivesSuggestionBuilder {
     /// Emit an intermediate note on the given `Diag` if the involved regions are suggestable.
     pub(crate) fn intermediate_suggestion(
         &mut self,
-        mbcx: &MirBorrowckCtxt<'_, '_>,
+        mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
         errci: &ErrorConstraintInfo<'_>,
         diag: &mut Diag<'_>,
     ) {
@@ -179,7 +179,7 @@ impl OutlivesSuggestionBuilder {
 
     /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
     /// suggestion including all collected constraints.
-    pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
+    pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) {
         // No constraints to add? Done.
         if self.constraints_to_add.is_empty() {
             debug!("No constraints to suggest.");
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index c214c52880a..245ce790e49 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> {
     pub(super) span: Span,
 }
 
-impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     /// Converts a region inference variable into a `ty::Region` that
     /// we can use for error reporting. If `r` is universally bound,
     /// then we use the name that we have on record for it. If `r` is
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 25a0d40218b..356416d1a75 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -198,7 +198,7 @@ impl rustc_errors::IntoDiagArg for RegionName {
     }
 }
 
-impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
         self.body.source.def_id().expect_local()
     }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index b3b53e9cb79..69efee2fbdc 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -310,11 +310,11 @@ fn do_mir_borrowck<'tcx>(
         promoted_mbcx.report_move_errors();
         diags = promoted_mbcx.diags;
 
-        struct MoveVisitor<'a, 'cx, 'tcx> {
-            ctxt: &'a mut MirBorrowckCtxt<'cx, 'tcx>,
+        struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> {
+            ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>,
         }
 
-        impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> {
+        impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> {
             fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
                 if let Operand::Move(place) = operand {
                     self.ctxt.check_movable_place(location, *place);
@@ -528,15 +528,15 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
     }
 }
 
-struct MirBorrowckCtxt<'cx, 'tcx> {
+struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
     infcx: &'cx BorrowckInferCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
-    body: &'cx Body<'tcx>,
-    move_data: &'cx MoveData<'tcx>,
+    body: &'mir Body<'tcx>,
+    move_data: &'a MoveData<'tcx>,
 
     /// Map from MIR `Location` to `LocationIndex`; created
     /// when MIR borrowck begins.
-    location_table: &'cx LocationTable,
+    location_table: &'a LocationTable,
 
     movable_coroutine: bool,
     /// This keeps track of whether local variables are free-ed when the function
@@ -605,14 +605,16 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
 // 2. loans made in overlapping scopes do not conflict
 // 3. assignments do not affect things loaned out as immutable
 // 4. moves do not affect things loaned out in any way
-impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorrowckCtxt<'cx, 'tcx> {
-    type FlowState = Flows<'cx, 'tcx>;
+impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
+    for MirBorrowckCtxt<'_, 'mir, '_, 'tcx>
+{
+    type FlowState = Flows<'mir, 'tcx>;
 
     fn visit_statement_before_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'cx, 'tcx>,
-        stmt: &'cx Statement<'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
+        stmt: &'mir Statement<'tcx>,
         location: Location,
     ) {
         debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
@@ -681,8 +683,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
     fn visit_terminator_before_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'cx, 'tcx>,
-        term: &'cx Terminator<'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
+        term: &'mir Terminator<'tcx>,
         loc: Location,
     ) {
         debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
@@ -792,8 +794,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
     fn visit_terminator_after_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'cx, 'tcx>,
-        term: &'cx Terminator<'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
+        term: &'mir Terminator<'tcx>,
         loc: Location,
     ) {
         let span = term.source_info.span;
@@ -969,8 +971,8 @@ impl InitializationRequiringAction {
     }
 }
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
-    fn body(&self) -> &'cx Body<'tcx> {
+impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
+    fn body(&self) -> &'mir Body<'tcx> {
         self.body
     }
 
@@ -986,7 +988,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         place_span: (Place<'tcx>, Span),
         kind: (AccessDepth, ReadOrWrite),
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         let (sd, rw) = kind;
 
@@ -1036,7 +1038,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         place_span: (Place<'tcx>, Span),
         sd: AccessDepth,
         rw: ReadOrWrite,
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) -> bool {
         let mut error_reported = false;
         let borrow_set = Rc::clone(&self.borrow_set);
@@ -1177,7 +1179,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         location: Location,
         place_span: (Place<'tcx>, Span),
         kind: AccessDepth,
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         // Write of P[i] or *P requires P init'd.
         self.check_if_assigned_path_is_moved(location, place_span, flow_state);
@@ -1194,8 +1196,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn consume_rvalue(
         &mut self,
         location: Location,
-        (rvalue, span): (&'cx Rvalue<'tcx>, Span),
-        flow_state: &Flows<'cx, 'tcx>,
+        (rvalue, span): (&'mir Rvalue<'tcx>, Span),
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         match rvalue {
             &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@@ -1452,8 +1454,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn consume_operand(
         &mut self,
         location: Location,
-        (operand, span): (&'cx Operand<'tcx>, Span),
-        flow_state: &Flows<'cx, 'tcx>,
+        (operand, span): (&'mir Operand<'tcx>, Span),
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         match *operand {
             Operand::Copy(place) => {
@@ -1573,7 +1575,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }
     }
 
-    fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'cx, 'tcx>) {
+    fn check_activations(
+        &mut self,
+        location: Location,
+        span: Span,
+        flow_state: &Flows<'mir, 'tcx>,
+    ) {
         // Two-phase borrow support: For each activation that is newly
         // generated at this statement, check if it interferes with
         // another borrow.
@@ -1736,7 +1743,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         let maybe_uninits = &flow_state.uninits;
 
@@ -1841,7 +1848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         let maybe_uninits = &flow_state.uninits;
 
@@ -1940,7 +1947,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         (place, span): (Place<'tcx>, Span),
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
 
@@ -2001,12 +2008,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
         }
 
-        fn check_parent_of_field<'cx, 'tcx>(
-            this: &mut MirBorrowckCtxt<'cx, 'tcx>,
+        fn check_parent_of_field<'mir, 'tcx>(
+            this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>,
             location: Location,
             base: PlaceRef<'tcx>,
             span: Span,
-            flow_state: &Flows<'cx, 'tcx>,
+            flow_state: &Flows<'mir, 'tcx>,
         ) {
             // rust-lang/rust#21232: Until Rust allows reads from the
             // initialized parts of partially initialized structs, we
@@ -2097,7 +2104,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         (place, span): (Place<'tcx>, Span),
         kind: ReadOrWrite,
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
         location: Location,
     ) -> bool {
         debug!(
@@ -2213,7 +2220,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn is_local_ever_initialized(
         &self,
         local: Local,
-        flow_state: &Flows<'cx, 'tcx>,
+        flow_state: &Flows<'mir, 'tcx>,
     ) -> Option<InitIndex> {
         let mpi = self.move_data.rev_lookup.find_local(local)?;
         let ii = &self.move_data.init_path_map[mpi];
@@ -2221,7 +2228,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     /// Adds the place into the used mutable variables set
-    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'cx, 'tcx>) {
+    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) {
         match root_place {
             RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
                 // If the local may have been initialized, and it is now currently being
@@ -2476,7 +2483,7 @@ mod diags {
         }
     }
 
-    impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+    impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
         pub fn buffer_error(&mut self, diag: Diag<'tcx>) {
             self.diags.buffer_error(diag);
         }
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index 8a3a089d0ee..5d3ac1c409a 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -34,7 +34,7 @@ pub(super) enum PrefixSet {
     Shallow,
 }
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     /// Returns an iterator over the prefixes of `place`
     /// (inclusive) from longest to smallest, potentially
     /// terminating the iteration early based on `kind`.
diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs
index dea1c7823a5..25e1f6268e0 100644
--- a/compiler/rustc_borrowck/src/used_muts.rs
+++ b/compiler/rustc_borrowck/src/used_muts.rs
@@ -6,7 +6,7 @@ use rustc_middle::mir::{
 
 use crate::MirBorrowckCtxt;
 
-impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
     /// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
     /// of the `unused_mut` lint.
     ///
@@ -45,13 +45,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
 /// MIR visitor for collecting used mutable variables.
 /// The 'visit lifetime represents the duration of the MIR walk.
-struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
+struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> {
     temporary_used_locals: FxIndexSet<Local>,
     never_initialized_mut_locals: &'visit mut FxIndexSet<Local>,
-    mbcx: &'visit mut MirBorrowckCtxt<'cx, 'tcx>,
+    mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>,
 }
 
-impl GatherUsedMutsVisitor<'_, '_, '_> {
+impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {
     fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
         // Remove any locals that we found were initialized from the
         // `never_initialized_mut_locals` set. At the end, the only remaining locals will
@@ -63,7 +63,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> {
     }
 }
 
-impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
+impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> {
     fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
         debug!("visit_terminator: terminator={:?}", terminator);
         match &terminator.kind {
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index e3a93ae13e4..32936ac183d 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -27,6 +27,7 @@ pub(crate) mod decodable;
 pub(crate) mod default;
 pub(crate) mod encodable;
 pub(crate) mod hash;
+pub(crate) mod smart_ptr;
 
 #[path = "cmp/eq.rs"]
 pub(crate) mod eq;
diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
new file mode 100644
index 00000000000..ea054a7e355
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -0,0 +1,140 @@
+use std::mem::swap;
+
+use ast::HasAttrs;
+use rustc_ast::{
+    self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
+    TraitBoundModifiers,
+};
+use rustc_expand::base::{Annotatable, ExtCtxt};
+use rustc_span::symbol::{sym, Ident};
+use rustc_span::Span;
+use smallvec::{smallvec, SmallVec};
+use thin_vec::{thin_vec, ThinVec};
+
+macro_rules! path {
+    ($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
+}
+
+pub fn expand_deriving_smart_ptr(
+    cx: &ExtCtxt<'_>,
+    span: Span,
+    _mitem: &MetaItem,
+    item: &Annotatable,
+    push: &mut dyn FnMut(Annotatable),
+    _is_const: bool,
+) {
+    let (name_ident, generics) = if let Annotatable::Item(aitem) = item
+        && let ItemKind::Struct(_, g) = &aitem.kind
+    {
+        (aitem.ident, g)
+    } else {
+        cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit();
+        return;
+    };
+
+    // Convert generic parameters (from the struct) into generic args.
+    let mut pointee_param = None;
+    let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
+    let self_params = generics
+        .params
+        .iter()
+        .enumerate()
+        .map(|(idx, p)| match p.kind {
+            GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
+            GenericParamKind::Type { .. } => {
+                if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
+                    if pointee_param.is_some() {
+                        multiple_pointee_diag.push(cx.dcx().struct_span_err(
+                            p.span(),
+                            "`SmartPointer` can only admit one type as pointee",
+                        ));
+                    } else {
+                        pointee_param = Some(idx);
+                    }
+                }
+                GenericArg::Type(cx.ty_ident(p.span(), p.ident))
+            }
+            GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
+        })
+        .collect::<Vec<_>>();
+    let Some(pointee_param_idx) = pointee_param else {
+        cx.dcx().struct_span_err(
+            span,
+            "At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
+        ).emit();
+        return;
+    };
+    if !multiple_pointee_diag.is_empty() {
+        for diag in multiple_pointee_diag {
+            diag.emit();
+        }
+        return;
+    }
+
+    // Create the type of `self`.
+    let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
+    let self_type = cx.ty_path(path);
+
+    // Declare helper function that adds implementation blocks.
+    // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
+    let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
+    let mut add_impl_block = |generics, trait_symbol, trait_args| {
+        let mut parts = path!(span, core::ops);
+        parts.push(Ident::new(trait_symbol, span));
+        let trait_path = cx.path_all(span, true, parts, trait_args);
+        let trait_ref = cx.trait_ref(trait_path);
+        let item = cx.item(
+            span,
+            Ident::empty(),
+            attrs.clone(),
+            ast::ItemKind::Impl(Box::new(ast::Impl {
+                safety: ast::Safety::Default,
+                polarity: ast::ImplPolarity::Positive,
+                defaultness: ast::Defaultness::Final,
+                constness: ast::Const::No,
+                generics,
+                of_trait: Some(trait_ref),
+                self_ty: self_type.clone(),
+                items: ThinVec::new(),
+            })),
+        );
+        push(Annotatable::Item(item));
+    };
+
+    // Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For
+    // example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`.
+    let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span));
+    let mut alt_self_params = self_params;
+    alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone());
+    let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params));
+
+    // Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
+    let mut impl_generics = generics.clone();
+    {
+        let p = &mut impl_generics.params[pointee_param_idx];
+        let arg = GenericArg::Type(s_ty.clone());
+        let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
+        p.bounds.push(cx.trait_bound(unsize, false));
+        let mut attrs = thin_vec![];
+        swap(&mut p.attrs, &mut attrs);
+        p.attrs = attrs.into_iter().filter(|attr| !attr.has_name(sym::pointee)).collect();
+    }
+
+    // Add the `__S: ?Sized` extra parameter to the impl block.
+    let sized = cx.path_global(span, path!(span, core::marker::Sized));
+    let bound = GenericBound::Trait(
+        cx.poly_trait_ref(span, sized),
+        TraitBoundModifiers {
+            polarity: ast::BoundPolarity::Maybe(span),
+            constness: ast::BoundConstness::Never,
+            asyncness: ast::BoundAsyncness::Normal,
+        },
+    );
+    let extra_param = cx.typaram(span, Ident::new(sym::__S, span), vec![bound], None);
+    impl_generics.params.push(extra_param);
+
+    // Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
+    let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
+    add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
+    add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args.clone());
+}
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 35b0f43d8af..8ac59605bc1 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -127,6 +127,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         PartialOrd: partial_ord::expand_deriving_partial_ord,
         RustcDecodable: decodable::expand_deriving_rustc_decodable,
         RustcEncodable: encodable::expand_deriving_rustc_encodable,
+        SmartPointer: smart_ptr::expand_deriving_smart_ptr,
     }
 
     let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bbfc697407b..5e481eb98f5 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -564,9 +564,6 @@ pub(crate) unsafe fn llvm_optimize(
 
     let llvm_plugins = config.llvm_plugins.join(",");
 
-    // FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
-    // We would have to add upstream support for this first, before we can support
-    // config.inline_threshold and our more aggressive default thresholds.
     let result = llvm::LLVMRustOptimize(
         module.module_llvm.llmod(),
         &*module.module_llvm.tm,
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 1a851ad04a1..000fe2e3ce0 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -27,8 +27,6 @@ codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
 
 codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
 
-codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
-
 codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
 
 codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 064be4988bd..0e48eee3dd5 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -120,7 +120,6 @@ pub struct ModuleConfig {
     pub vectorize_loop: bool,
     pub vectorize_slp: bool,
     pub merge_functions: bool,
-    pub inline_threshold: Option<u32>,
     pub emit_lifetime_markers: bool,
     pub llvm_plugins: Vec<String>,
 }
@@ -280,7 +279,6 @@ impl ModuleConfig {
                 }
             },
 
-            inline_threshold: sess.opts.cg.inline_threshold,
             emit_lifetime_markers: sess.emit_lifetime_markers(),
             llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
         }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 15955170e87..fb71cdaa8ff 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -15,11 +15,7 @@ use rustc_span::{sym, Span};
 use rustc_target::spec::{abi, SanitizerSet};
 
 use crate::errors;
-use crate::target_features::from_target_feature;
-use crate::{
-    errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol},
-    target_features::check_target_feature_trait_unsafe,
-};
+use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature};
 
 fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
     use rustc_middle::mir::mono::Linkage::*;
@@ -139,7 +135,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         // coverage on a smaller scope within an excluded larger scope.
                     }
                     Some(_) | None => {
-                        tcx.dcx().emit_err(ExpectedCoverageSymbol { span: attr.span });
+                        tcx.dcx()
+                            .span_delayed_bug(attr.span, "unexpected value of coverage attribute");
                     }
                 }
             }
@@ -174,7 +171,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
                     }
                     Some(_) => {
-                        tcx.dcx().emit_err(ExpectedUsedSymbol { span: attr.span });
+                        tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span });
                     }
                     None => {
                         // Unfortunately, unconditionally using `llvm.used` causes
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index e6ba31c5165..e9d31db9254 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -565,13 +565,6 @@ pub struct UnknownArchiveKind<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_ssa_expected_coverage_symbol)]
-pub struct ExpectedCoverageSymbol {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_ssa_expected_used_symbol)]
 pub struct ExpectedUsedSymbol {
     #[primary_span]
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 9781aae22eb..cddc67d1578 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -27,7 +27,6 @@
 #![feature(lint_reasons)]
 #![feature(macro_metavar_expr)]
 #![feature(map_try_insert)]
-#![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs
index 4c9acfe0f71..fed23df10dc 100644
--- a/compiler/rustc_data_structures/src/sip128.rs
+++ b/compiler/rustc_data_structures/src/sip128.rs
@@ -188,7 +188,7 @@ impl SipHasher128 {
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 {
         let mut hasher = SipHasher128 {
             nbuf: 0,
-            buf: MaybeUninit::uninit_array(),
+            buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY],
             state: State {
                 v0: key0 ^ 0x736f6d6570736575,
                 // The XOR with 0xee is only done on 128-bit algorithm version.
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index b5bdf2e1790..a57f5067dd8 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -238,12 +238,21 @@ pub trait ToStableHashKey<HCX> {
 /// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether
 /// unstable sorting can be used for this type. Set to true if and
 /// only if `a == b` implies `a` and `b` are fully indistinguishable.
-pub unsafe trait StableOrd: Ord {
+pub trait StableOrd: Ord {
     const CAN_USE_UNSTABLE_SORT: bool;
+
+    /// Marker to ensure that implementors have carefully considered
+    /// whether their `Ord` implementation obeys this trait's contract.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: ();
 }
 
-unsafe impl<T: StableOrd> StableOrd for &T {
+impl<T: StableOrd> StableOrd for &T {
     const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
+
+    // Ordering of a reference is exactly that of the referent, and since
+    // the ordering of the referet is stable so must be the ordering of the
+    // reference.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 /// This is a companion trait to `StableOrd`. Some types like `Symbol` can be
@@ -290,8 +299,12 @@ macro_rules! impl_stable_traits_for_trivial_type {
             }
         }
 
-        unsafe impl $crate::stable_hasher::StableOrd for $t {
+        impl $crate::stable_hasher::StableOrd for $t {
             const CAN_USE_UNSTABLE_SORT: bool = true;
+
+            // Encoding and decoding doesn't change the bytes of trivial types
+            // and `Ord::cmp` depends only on those bytes.
+            const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
         }
     };
 }
@@ -327,8 +340,12 @@ impl<CTX> HashStable<CTX> for Hash128 {
     }
 }
 
-unsafe impl StableOrd for Hash128 {
+impl StableOrd for Hash128 {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // Encoding and decoding doesn't change the bytes of `Hash128`
+    // and `Ord::cmp` depends only on those bytes.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<CTX> HashStable<CTX> for ! {
@@ -392,8 +409,12 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2)
     }
 }
 
-unsafe impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
+impl<T1: StableOrd, T2: StableOrd> StableOrd for (T1, T2) {
     const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT;
+
+    // Ordering of tuples is a pure function of their elements' ordering, and since
+    // the ordering of each element is stable so must be the ordering of the tuple.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3)
@@ -410,9 +431,13 @@ where
     }
 }
 
-unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
+impl<T1: StableOrd, T2: StableOrd, T3: StableOrd> StableOrd for (T1, T2, T3) {
     const CAN_USE_UNSTABLE_SORT: bool =
         T1::CAN_USE_UNSTABLE_SORT && T2::CAN_USE_UNSTABLE_SORT && T3::CAN_USE_UNSTABLE_SORT;
+
+    // Ordering of tuples is a pure function of their elements' ordering, and since
+    // the ordering of each element is stable so must be the ordering of the tuple.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<T1, T2, T3, T4, CTX> HashStable<CTX> for (T1, T2, T3, T4)
@@ -431,13 +456,15 @@ where
     }
 }
 
-unsafe impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd
-    for (T1, T2, T3, T4)
-{
+impl<T1: StableOrd, T2: StableOrd, T3: StableOrd, T4: StableOrd> StableOrd for (T1, T2, T3, T4) {
     const CAN_USE_UNSTABLE_SORT: bool = T1::CAN_USE_UNSTABLE_SORT
         && T2::CAN_USE_UNSTABLE_SORT
         && T3::CAN_USE_UNSTABLE_SORT
         && T4::CAN_USE_UNSTABLE_SORT;
+
+    // Ordering of tuples is a pure function of their elements' ordering, and since
+    // the ordering of each element is stable so must be the ordering of the tuple.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
@@ -530,8 +557,12 @@ impl<CTX> HashStable<CTX> for str {
     }
 }
 
-unsafe impl StableOrd for &str {
+impl StableOrd for &str {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // Encoding and decoding doesn't change the bytes of string slices
+    // and `Ord::cmp` depends only on those bytes.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<CTX> HashStable<CTX> for String {
@@ -541,10 +572,12 @@ impl<CTX> HashStable<CTX> for String {
     }
 }
 
-// Safety: String comparison only depends on their contents and the
-// contents are not changed by (de-)serialization.
-unsafe impl StableOrd for String {
+impl StableOrd for String {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // String comparison only depends on their contents and the
+    // contents are not changed by (de-)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<HCX> ToStableHashKey<HCX> for String {
@@ -570,9 +603,11 @@ impl<CTX> HashStable<CTX> for bool {
     }
 }
 
-// Safety: sort order of bools is not changed by (de-)serialization.
-unsafe impl StableOrd for bool {
+impl StableOrd for bool {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // sort order of bools is not changed by (de-)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<T, CTX> HashStable<CTX> for Option<T>
@@ -590,9 +625,11 @@ where
     }
 }
 
-// Safety: the Option wrapper does not add instability to comparison.
-unsafe impl<T: StableOrd> StableOrd for Option<T> {
+impl<T: StableOrd> StableOrd for Option<T> {
     const CAN_USE_UNSTABLE_SORT: bool = T::CAN_USE_UNSTABLE_SORT;
+
+    // the Option wrapper does not add instability to comparison.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2>
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 5ffa3a6099c..bbe9741bf44 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -30,7 +30,7 @@ use rustc_errors::{
 };
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, get_codegen_backend};
-use rustc_interface::{interface, Queries};
+use rustc_interface::{interface, passes, Queries};
 use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
@@ -367,18 +367,17 @@ fn run_compiler(
             return early_exit();
         }
 
-        let early_dcx = EarlyDiagCtxt::new(sess.opts.error_format);
-
-        if print_crate_info(&early_dcx, codegen_backend, sess, has_input) == Compilation::Stop {
+        if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop {
             return early_exit();
         }
 
         if !has_input {
-            early_dcx.early_fatal("no input filename given"); // this is fatal
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            sess.dcx().fatal("no input filename given"); // this is fatal
         }
 
         if !sess.opts.unstable_opts.ls.is_empty() {
-            list_metadata(&early_dcx, sess, &*codegen_backend.metadata_loader());
+            list_metadata(sess, &*codegen_backend.metadata_loader());
             return early_exit();
         }
 
@@ -399,7 +398,9 @@ fn run_compiler(
                         Ok(())
                     })?;
 
-                    queries.write_dep_info()?;
+                    queries.global_ctxt()?.enter(|tcx| {
+                        passes::write_dep_info(tcx);
+                    });
                 } else {
                     let krate = queries.parse()?;
                     pretty::print(
@@ -427,7 +428,9 @@ fn run_compiler(
                 return early_exit();
             }
 
-            queries.write_dep_info()?;
+            queries.global_ctxt()?.enter(|tcx| {
+                passes::write_dep_info(tcx);
+            });
 
             if sess.opts.output_types.contains_key(&OutputType::DepInfo)
                 && sess.opts.output_types.len() == 1
@@ -670,7 +673,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
     }
 }
 
-fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dyn MetadataLoader) {
+fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) {
     match sess.io.input {
         Input::File(ref ifile) => {
             let path = &(*ifile);
@@ -687,13 +690,13 @@ fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dy
             safe_println!("{}", String::from_utf8(v).unwrap());
         }
         Input::Str { .. } => {
-            early_dcx.early_fatal("cannot list metadata for stdin");
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            sess.dcx().fatal("cannot list metadata for stdin");
         }
     }
 }
 
 fn print_crate_info(
-    early_dcx: &EarlyDiagCtxt,
     codegen_backend: &dyn CodegenBackend,
     sess: &Session,
     parse_attrs: bool,
@@ -877,8 +880,8 @@ fn print_crate_info(
                         .expect("unknown Apple target OS");
                     println_info!("deployment_target={}", format!("{major}.{minor}"))
                 } else {
-                    early_dcx
-                        .early_fatal("only Apple targets currently support deployment version info")
+                    #[allow(rustc::diagnostic_outside_of_impl)]
+                    sess.dcx().fatal("only Apple targets currently support deployment version info")
                 }
             }
         }
@@ -1133,7 +1136,11 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
     }
 
     if cg_flags.iter().any(|x| *x == "no-stack-check") {
-        early_dcx.early_warn("the --no-stack-check flag is deprecated and does nothing");
+        early_dcx.early_warn("the `-Cno-stack-check` flag is deprecated and does nothing");
+    }
+
+    if cg_flags.iter().any(|x| x.starts_with("inline-threshold")) {
+        early_dcx.early_warn("the `-Cinline-threshold` flag is deprecated and does nothing (consider using `-Cllvm-args=--inline-threshold=...`)");
     }
 
     if cg_flags.iter().any(|x| *x == "passes=list") {
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 7405705dd33..45118bcc58a 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -902,7 +902,7 @@ impl HumanEmitter {
         //      <EMPTY LINE>
         //
         let mut annotations_position = vec![];
-        let mut line_len = 0;
+        let mut line_len: usize = 0;
         let mut p = 0;
         for (i, annotation) in annotations.iter().enumerate() {
             for (j, next) in annotations.iter().enumerate() {
@@ -973,6 +973,31 @@ impl HumanEmitter {
             return vec![];
         }
 
+        if annotations_position
+            .iter()
+            .all(|(_, ann)| matches!(ann.annotation_type, AnnotationType::MultilineStart(_)))
+            && let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max()
+        {
+            // Special case the following, so that we minimize overlapping multiline spans.
+            //
+            // 3 │       X0 Y0 Z0
+            //   │ ┏━━━━━┛  │  │     < We are writing these lines
+            //   │ ┃┌───────┘  │     < by reverting the "depth" of
+            //   │ ┃│┌─────────┘     < their multilne spans.
+            // 4 │ ┃││   X1 Y1 Z1
+            // 5 │ ┃││   X2 Y2 Z2
+            //   │ ┃│└────╿──│──┘ `Z` label
+            //   │ ┃└─────│──┤
+            //   │ ┗━━━━━━┥  `Y` is a good letter too
+            //   ╰╴       `X` is a good letter
+            for (pos, _) in &mut annotations_position {
+                *pos = max_pos - *pos;
+            }
+            // We know then that we don't need an additional line for the span label, saving us
+            // one line of vertical space.
+            line_len = line_len.saturating_sub(1);
+        }
+
         // Write the column separator.
         //
         // After this we will have:
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 5e83e0d27e1..c53bf965139 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -105,6 +105,9 @@ pub struct AttributeTemplate {
     pub word: bool,
     /// If `Some`, the attribute is allowed to take a list of items like `#[allow(..)]`.
     pub list: Option<&'static str>,
+    /// If non-empty, the attribute is allowed to take a list containing exactly
+    /// one of the listed words, like `#[coverage(off)]`.
+    pub one_of: &'static [Symbol],
     /// If `Some`, the attribute is allowed to be a name/value pair where the
     /// value is a string, like `#[must_use = "reason"]`.
     pub name_value_str: Option<&'static str>,
@@ -165,19 +168,20 @@ pub enum AttributeDuplicates {
 /// E.g., `template!(Word, List: "description")` means that the attribute
 /// supports forms `#[attr]` and `#[attr(description)]`.
 macro_rules! template {
-    (Word) => { template!(@ true, None, None) };
-    (List: $descr: expr) => { template!(@ false, Some($descr), None) };
-    (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
-    (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
-    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
+    (Word) => { template!(@ true, None, &[], None) };
+    (List: $descr: expr) => { template!(@ false, Some($descr), &[], None) };
+    (OneOf: $one_of: expr) => { template!(@ false, None, $one_of, None) };
+    (NameValueStr: $descr: expr) => { template!(@ false, None, &[], Some($descr)) };
+    (Word, List: $descr: expr) => { template!(@ true, Some($descr), &[], None) };
+    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, &[], Some($descr)) };
     (List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ false, Some($descr1), Some($descr2))
+        template!(@ false, Some($descr1), &[], Some($descr2))
     };
     (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ true, Some($descr1), Some($descr2))
+        template!(@ true, Some($descr1), &[], Some($descr2))
     };
-    (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
-        word: $word, list: $list, name_value_str: $name_value_str
+    (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr) => { AttributeTemplate {
+        word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str
     } };
 }
 
@@ -478,8 +482,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, experimental!(no_sanitize)
     ),
     gated!(
-        coverage, Normal, template!(Word, List: "on|off"),
-        WarnFollowing, EncodeCrossCrate::No,
+        coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
+        ErrorPreceding, EncodeCrossCrate::No,
         coverage_attribute, experimental!(coverage)
     ),
 
@@ -575,6 +579,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, coroutines, experimental!(coroutines)
     ),
 
+    // `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
+    gated!(
+        pointee, Normal, template!(Word), ErrorFollowing,
+        EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
+    ),
+
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
     // ==========================================================================
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index f66c9604cbe..2dfaac8f6e7 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -436,6 +436,8 @@ declare_features! (
     (unstable, deprecated_suggestion, "1.61.0", Some(94785)),
     /// Allows deref patterns.
     (incomplete, deref_patterns, "1.79.0", Some(87121)),
+    /// Allows deriving `SmartPointer` traits
+    (unstable, derive_smart_pointer, "1.79.0", Some(123430)),
     /// Controls errors in trait implementations.
     (unstable, do_not_recommend, "1.67.0", Some(51992)),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index ac487469507..c0ca1a8017e 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -165,10 +165,12 @@ impl ItemLocalId {
     pub const INVALID: ItemLocalId = ItemLocalId::MAX;
 }
 
-// Safety: Ord is implement as just comparing the ItemLocalId's numerical
-// values and these are not changed by (de-)serialization.
-unsafe impl StableOrd for ItemLocalId {
+impl StableOrd for ItemLocalId {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // `Ord` is implemented as just comparing the ItemLocalId's numerical
+    // values and these are not changed by (de-)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 3b53c253195..e13ea1a1935 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -719,7 +719,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                             tcx,
                             assoc_item,
                             assoc_item,
-                            ty::TraitRef::new(tcx, def_id.to_def_id(), trait_args),
+                            ty::TraitRef::new_from_args(tcx, def_id.to_def_id(), trait_args),
                         );
                     }
                     _ => {}
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 550f38af8b5..7fa5c96bc9a 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2032,7 +2032,7 @@ pub(super) fn check_type_bounds<'tcx>(
     // to its definition type. This should be the param-env we use to *prove* the
     // predicate too, but we don't do that because of performance issues.
     // See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
-    let trait_projection_ty = Ty::new_projection(tcx, trait_ty.def_id, rebased_args);
+    let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args);
     let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
     let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
     for mut obligation in util::elaborate(tcx, obligations) {
@@ -2230,7 +2230,11 @@ fn param_env_with_gat_bounds<'tcx>(
             _ => predicates.push(
                 ty::Binder::bind_with_vars(
                     ty::ProjectionPredicate {
-                        projection_term: ty::AliasTerm::new(tcx, trait_ty.def_id, rebased_args),
+                        projection_term: ty::AliasTerm::new_from_args(
+                            tcx,
+                            trait_ty.def_id,
+                            rebased_args,
+                        ),
                         term: normalize_impl_ty.into(),
                     },
                     bound_vars,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 683709f43f2..f21aeb4c0b9 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -504,7 +504,11 @@ pub fn check_intrinsic_type(
                         ty::Region::new_bound(tcx, ty::INNERMOST, br),
                         param(0),
                     )],
-                    Ty::new_projection(tcx, discriminant_def_id, tcx.mk_args(&[param(0).into()])),
+                    Ty::new_projection_from_args(
+                        tcx,
+                        discriminant_def_id,
+                        tcx.mk_args(&[param(0).into()]),
+                    ),
                 )
             }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e5bd147352d..e7892f17660 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -423,7 +423,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                 item_segment,
                 trait_ref.args,
             );
-            Ty::new_projection(self.tcx(), item_def_id, item_args)
+            Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
         } else {
             // There are no late-bound regions; we can just ignore the binder.
             let (mut mpart_sugg, mut inferred_sugg) = (None, None);
@@ -1607,7 +1607,7 @@ pub fn suggest_impl_trait<'tcx>(
             let item_ty = ocx.normalize(
                 &ObligationCause::dummy(),
                 param_env,
-                Ty::new_projection(infcx.tcx, assoc_item_def_id, args),
+                Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args),
             );
             // FIXME(compiler-errors): We may benefit from resolving regions here.
             if ocx.select_where_possible().is_empty()
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 9f198933dee..d084d3aefeb 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -23,7 +23,7 @@ fn associated_type_bounds<'tcx>(
     span: Span,
     filter: PredicateFilter,
 ) -> &'tcx [(ty::Clause<'tcx>, Span)] {
-    let item_ty = Ty::new_projection(
+    let item_ty = Ty::new_projection_from_args(
         tcx,
         assoc_item_def_id.to_def_id(),
         GenericArgs::identity_for_item(tcx, assoc_item_def_id),
@@ -108,7 +108,7 @@ pub(super) fn explicit_item_bounds_with_filter(
                 tcx,
                 opaque_def_id.expect_local(),
                 opaque_ty.bounds,
-                Ty::new_projection(
+                Ty::new_projection_from_args(
                     tcx,
                     def_id.to_def_id(),
                     ty::GenericArgs::identity_for_item(tcx, def_id),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index c7699b0b310..802215b2843 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -409,7 +409,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 );
                 debug!(?alias_args);
 
-                ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args)
+                ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args)
             });
 
             // Provide the resolved type of the associated constant to `type_of(AnonConst)`.
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 5911d5bb4e1..24ea328889c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -693,7 +693,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?bound_vars);
 
         let poly_trait_ref = ty::Binder::bind_with_vars(
-            ty::TraitRef::new(tcx, trait_def_id, generic_args),
+            ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
             bound_vars,
         );
 
@@ -759,7 +759,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 Some((trait_def_id, trait_segment, span)),
             );
         }
-        ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
+        ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
     }
 
     fn probe_trait_that_defines_assoc_item(
@@ -789,7 +789,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             // Type aliases defined in crates that have the
             // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
             // then actually instantiate the where bounds of.
-            let alias_ty = ty::AliasTy::new(tcx, did, args);
+            let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
             Ty::new_alias(tcx, ty::Weak, alias_ty)
         } else {
             tcx.at(span).type_of(did).instantiate(tcx, args)
@@ -1267,7 +1267,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .chain(args.into_iter().skip(parent_args.len())),
         );
 
-        let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
+        let ty =
+            Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new_from_args(tcx, assoc_item, args));
 
         Ok(Some((ty, assoc_item)))
     }
@@ -1534,7 +1535,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let item_args =
             self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
 
-        Ty::new_projection(tcx, item_def_id, item_args)
+        Ty::new_projection_from_args(tcx, item_def_id, item_args)
     }
 
     pub fn prohibit_generic_args<'a>(
@@ -2302,7 +2303,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         debug!(?args);
 
         if in_trait {
-            Ty::new_projection(tcx, def_id, args)
+            Ty::new_projection_from_args(tcx, def_id, args)
         } else {
             Ty::new_opaque(tcx, def_id, args)
         }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 31f85e21d71..0551b9bc1f0 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1245,11 +1245,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     expr,
                 );
 
-                return self
+                return Err(self
                     .commit_if_ok(|_| {
-                        self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
+                        self.at(cause, self.param_env).lub(DefineOpaqueTypes::Yes, prev_ty, new_ty)
                     })
-                    .map(|ok| self.register_infer_ok_obligations(ok));
+                    .unwrap_err());
             }
         }
 
@@ -1259,10 +1259,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let Some(e) = first_error {
                     Err(e)
                 } else {
-                    self.commit_if_ok(|_| {
-                        self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
-                    })
-                    .map(|ok| self.register_infer_ok_obligations(ok))
+                    Err(self
+                        .commit_if_ok(|_| {
+                            self.at(cause, self.param_env).lub(
+                                DefineOpaqueTypes::Yes,
+                                prev_ty,
+                                new_ty,
+                            )
+                        })
+                        .unwrap_err())
                 }
             }
             Ok(ok) => {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 233dc2afa9b..f4e1e461953 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3108,7 +3108,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let element_ty = ocx.normalize(
                 &cause,
                 self.param_env,
-                Ty::new_projection(self.tcx, index_trait_output_def_id, impl_trait_ref.args),
+                Ty::new_projection_from_args(
+                    self.tcx,
+                    index_trait_output_def_id,
+                    impl_trait_ref.args,
+                ),
             );
 
             let true_errors = ocx.select_where_possible();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 4edc11d7ab1..f7abba35706 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of
         // that struct type.
         let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_or_alias_def_id) {
-            ty::TraitRef::new(
+            ty::TraitRef::new_from_args(
                 self.tcx,
                 obligation.impl_or_alias_def_id,
                 ty::GenericArgs::identity_for_item(self.tcx, obligation.impl_or_alias_def_id),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 1713d75092e..c0d60477967 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -297,7 +297,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
             trait_ref.args,
         );
 
-        Ty::new_projection(self.tcx(), item_def_id, item_args)
+        Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
     }
 
     fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index fb8863c143f..5eafc60a04e 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -73,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Special-case transmuting from `typeof(function)` and
             // `Option<typeof(function)>` to present a clearer error.
             let from = unpack_option_like(tcx, from);
-            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to)
+            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to)
                 && size_to == Pointer(dl.instruction_address_space).size(&tcx)
             {
                 struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type")
@@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Try to display a sensible error with as much information as possible.
         let skeleton_string = |ty: Ty<'tcx>, sk: Result<_, &_>| match sk {
             Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"),
-            Ok(SizeSkeleton::Known(size)) => {
+            Ok(SizeSkeleton::Known(size, _)) => {
                 if let Some(v) = u128::from(size.bytes()).checked_mul(8) {
                     format!("{v} bits")
                 } else {
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 1f90d5e4c88..e1223307b53 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -333,7 +333,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.var_for_def(cause.span, param)
         });
 
-        let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, args);
+        let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, args);
 
         // Construct an obligation
         let poly_trait_ref = ty::Binder::dummy(trait_ref);
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 47ea221d1a1..9747a91ccbf 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -870,7 +870,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         trait_def_id: DefId,
     ) {
         let trait_args = self.fresh_args_for_item(self.span, trait_def_id);
-        let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_args);
+        let trait_ref = ty::TraitRef::new_from_args(self.tcx, trait_def_id, trait_args);
 
         if self.tcx.is_trait_alias(trait_def_id) {
             // For trait aliases, recursively assume all explicitly named traits are relevant
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index ec0cb7a67ba..a385bc70e35 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1978,7 +1978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             err,
                             self_source,
                             args,
-                            ty::TraitRef::new(
+                            ty::TraitRef::new_from_args(
                                 self.tcx,
                                 trait_did,
                                 self.fresh_args_for_item(sugg_span, trait_did),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index e125f1858dd..80b7e3b4fa5 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -256,12 +256,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 (false, None, None, Some(span), String::new())
             };
 
-        let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new(
+        let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
             self.cx.tcx,
             trait_def_id,
             expected_args,
         ));
-        let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new(
+        let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
             self.cx.tcx,
             trait_def_id,
             actual_args,
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 41c8b941717..dba20e4a335 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -495,9 +495,8 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
             let res = {
                 // If `f` panics, `finish_diagnostics` will run during
                 // unwinding because of the `defer`.
-                let mut guar = None;
                 let sess_abort_guard = defer(|| {
-                    guar = compiler.sess.finish_diagnostics(&config.registry);
+                    compiler.sess.finish_diagnostics(&config.registry);
                 });
 
                 let res = f(&compiler);
@@ -506,16 +505,14 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
                 // normally when `sess_abort_guard` is dropped.
                 drop(sess_abort_guard);
 
-                // If `finish_diagnostics` emits errors (e.g. stashed
-                // errors) we can't return an error directly, because the
-                // return type of this function is `R`, not `Result<R, E>`.
-                // But we need to communicate the errors' existence to the
-                // caller, otherwise the caller might mistakenly think that
-                // no errors occurred and return a zero exit code. So we
-                // abort (panic) instead, similar to if `f` had panicked.
-                if guar.is_some() {
-                    compiler.sess.dcx().abort_if_errors();
-                }
+                // If error diagnostics have been emitted, we can't return an
+                // error directly, because the return type of this function
+                // is `R`, not `Result<R, E>`. But we need to communicate the
+                // errors' existence to the caller, otherwise the caller might
+                // mistakenly think that no errors occurred and return a zero
+                // exit code. So we abort (panic) instead, similar to if `f`
+                // had panicked.
+                compiler.sess.dcx().abort_if_errors();
 
                 res
             };
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 0c3d4e19ef8..38f64ebb04e 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -8,7 +8,7 @@
 mod callbacks;
 mod errors;
 pub mod interface;
-mod passes;
+pub mod passes;
 mod proc_macro_decls;
 mod queries;
 pub mod util;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index f881d53858a..2951f50b1f5 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -7,16 +7,16 @@ use rustc_ast::{self as ast, visit};
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::parallel;
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{Lrc, OnceLock, WorkerLocal};
-use rustc_errors::PResult;
+use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
 use rustc_expand::base::{ExtCtxt, LintStoreExpand};
 use rustc_feature::Features;
 use rustc_fs_util::try_canonicalize;
-use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
+use rustc_hir::def_id::{StableCrateId, StableCrateIdMap, LOCAL_CRATE};
+use rustc_hir::definitions::Definitions;
+use rustc_incremental::setup_dep_graph;
 use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
-use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
 use rustc_parse::{
@@ -28,6 +28,7 @@ use rustc_session::code_stats::VTableSizeInfo;
 use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::output::filename_for_input;
+use rustc_session::output::{collect_crate_types, find_crate_name};
 use rustc_session::search_paths::PathKind;
 use rustc_session::{Limit, Session};
 use rustc_span::symbol::{sym, Symbol};
@@ -39,20 +40,22 @@ use std::any::Any;
 use std::ffi::OsString;
 use std::io::{self, BufWriter, Write};
 use std::path::{Path, PathBuf};
-use std::sync::LazyLock;
+use std::sync::{Arc, LazyLock};
 use std::{env, fs, iter};
 use tracing::{info, instrument};
 
-pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
-    let krate = sess.time("parse_crate", || {
-        let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
-            Input::File(file) => new_parser_from_file(&sess.psess, file, None),
-            Input::Str { input, name } => {
-                new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
-            }
-        });
-        parser.parse_crate_mod()
-    })?;
+pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> {
+    let krate = sess
+        .time("parse_crate", || {
+            let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
+                Input::File(file) => new_parser_from_file(&sess.psess, file, None),
+                Input::Str { input, name } => {
+                    new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
+                }
+            });
+            parser.parse_crate_mod()
+        })
+        .map_err(|parse_error| parse_error.emit())?;
 
     if sess.opts.unstable_opts.input_stats {
         eprintln!("Lines of code:             {}", sess.source_map().count_lines());
@@ -559,7 +562,7 @@ fn resolver_for_lowering_raw<'tcx>(
     (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate)))), resolutions)
 }
 
-pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) {
+pub fn write_dep_info(tcx: TyCtxt<'_>) {
     // Make sure name resolution and macro expansion is run for
     // the side-effect of providing a complete set of all
     // accessed files and env vars.
@@ -640,22 +643,48 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
     *providers
 });
 
-pub fn create_global_ctxt<'tcx>(
+pub(crate) fn create_global_ctxt<'tcx>(
     compiler: &'tcx Compiler,
-    crate_types: Vec<CrateType>,
-    stable_crate_id: StableCrateId,
-    dep_graph: DepGraph,
-    untracked: Untracked,
+    mut krate: rustc_ast::Crate,
     gcx_cell: &'tcx OnceLock<GlobalCtxt<'tcx>>,
     arena: &'tcx WorkerLocal<Arena<'tcx>>,
     hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
-) -> &'tcx GlobalCtxt<'tcx> {
+) -> Result<&'tcx GlobalCtxt<'tcx>> {
+    let sess = &compiler.sess;
+
+    rustc_builtin_macros::cmdline_attrs::inject(
+        &mut krate,
+        &sess.psess,
+        &sess.opts.unstable_opts.crate_attr,
+    );
+
+    let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
+
+    // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
+    let crate_name = find_crate_name(sess, &pre_configured_attrs);
+    let crate_types = collect_crate_types(sess, &pre_configured_attrs);
+    let stable_crate_id = StableCrateId::new(
+        crate_name,
+        crate_types.contains(&CrateType::Executable),
+        sess.opts.cg.metadata.clone(),
+        sess.cfg_version,
+    );
+    let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
+    let dep_graph = setup_dep_graph(sess)?;
+
+    let cstore =
+        FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _);
+    let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
+
+    let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default());
+    let untracked =
+        Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids };
+
     // We're constructing the HIR here; we don't care what we will
     // read, since we haven't even constructed the *input* to
     // incr. comp. yet.
     dep_graph.assert_ignored();
 
-    let sess = &compiler.sess;
     let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
     let codegen_backend = &compiler.codegen_backend;
@@ -669,7 +698,7 @@ pub fn create_global_ctxt<'tcx>(
     let incremental = dep_graph.is_fully_enabled();
 
     sess.time("setup_global_ctxt", || {
-        gcx_cell.get_or_init(move || {
+        let qcx = gcx_cell.get_or_init(move || {
             TyCtxt::create_global_ctxt(
                 sess,
                 crate_types,
@@ -688,7 +717,23 @@ pub fn create_global_ctxt<'tcx>(
                 providers.hooks,
                 compiler.current_gcx.clone(),
             )
-        })
+        });
+
+        qcx.enter(|tcx| {
+            let feed = tcx.create_crate_num(stable_crate_id).unwrap();
+            assert_eq!(feed.key(), LOCAL_CRATE);
+            feed.crate_name(crate_name);
+
+            let feed = tcx.feed_unit_query();
+            feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
+                sess,
+                &pre_configured_attrs,
+                crate_name,
+            )));
+            feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
+            feed.output_filenames(Arc::new(outputs));
+        });
+        Ok(qcx)
     })
 }
 
@@ -924,12 +969,56 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
     Ok(())
 }
 
+/// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
+/// to write UI tests that actually test that compilation succeeds without reporting
+/// an error.
+fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
+    let Some((def_id, _)) = tcx.entry_fn(()) else { return };
+    for attr in tcx.get_attrs(def_id, sym::rustc_error) {
+        match attr.meta_item_list() {
+            // Check if there is a `#[rustc_error(delayed_bug_from_inside_query)]`.
+            Some(list)
+                if list.iter().any(|list_item| {
+                    matches!(
+                        list_item.ident().map(|i| i.name),
+                        Some(sym::delayed_bug_from_inside_query)
+                    )
+                }) =>
+            {
+                tcx.ensure().trigger_delayed_bug(def_id);
+            }
+
+            // Bare `#[rustc_error]`.
+            None => {
+                tcx.dcx().emit_fatal(errors::RustcErrorFatal { span: tcx.def_span(def_id) });
+            }
+
+            // Some other attribute.
+            Some(_) => {
+                tcx.dcx().emit_warn(errors::RustcErrorUnexpectedAnnotation {
+                    span: tcx.def_span(def_id),
+                });
+            }
+        }
+    }
+}
+
 /// Runs the codegen backend, after which the AST and analysis can
 /// be discarded.
-pub fn start_codegen<'tcx>(
+pub(crate) fn start_codegen<'tcx>(
     codegen_backend: &dyn CodegenBackend,
     tcx: TyCtxt<'tcx>,
-) -> Box<dyn Any> {
+) -> Result<Box<dyn Any>> {
+    // Don't do code generation if there were any errors. Likewise if
+    // there were any delayed bugs, because codegen will likely cause
+    // more ICEs, obscuring the original problem.
+    if let Some(guar) = tcx.sess.dcx().has_errors_or_delayed_bugs() {
+        return Err(guar);
+    }
+
+    // Hook for UI tests.
+    check_for_rustc_errors_attr(tcx);
+
     info!("Pre-codegen\n{:?}", tcx.debug_stats());
 
     let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx);
@@ -952,7 +1041,7 @@ pub fn start_codegen<'tcx>(
         }
     }
 
-    codegen
+    Ok(codegen)
 }
 
 fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 1b9165342d4..cfd4304e893 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,26 +1,20 @@
-use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
+use crate::errors::FailedWritingFile;
 use crate::interface::{Compiler, Result};
-use crate::{errors, passes, util};
+use crate::{errors, passes};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal};
-use rustc_hir::def_id::{StableCrateId, StableCrateIdMap, LOCAL_CRATE};
-use rustc_hir::definitions::Definitions;
-use rustc_incremental::setup_dep_graph;
-use rustc_metadata::creader::CStore;
+use rustc_data_structures::sync::{OnceLock, WorkerLocal};
+use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{GlobalCtxt, TyCtxt};
 use rustc_serialize::opaque::FileEncodeResult;
-use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
-use rustc_session::cstore::Untracked;
-use rustc_session::output::{collect_crate_types, find_crate_name};
+use rustc_session::config::{self, OutputFilenames, OutputType};
 use rustc_session::Session;
-use rustc_span::symbol::sym;
 use std::any::Any;
 use std::cell::{RefCell, RefMut};
 use std::sync::Arc;
@@ -106,133 +100,26 @@ impl<'tcx> Queries<'tcx> {
     }
 
     pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
-        self.parse.compute(|| {
-            passes::parse(&self.compiler.sess).map_err(|parse_error| parse_error.emit())
-        })
+        self.parse.compute(|| passes::parse(&self.compiler.sess))
     }
 
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
-            let sess = &self.compiler.sess;
-
-            let mut krate = self.parse()?.steal();
-
-            rustc_builtin_macros::cmdline_attrs::inject(
-                &mut krate,
-                &sess.psess,
-                &sess.opts.unstable_opts.crate_attr,
-            );
-
-            let pre_configured_attrs =
-                rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
-
-            // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
-            let crate_name = find_crate_name(sess, &pre_configured_attrs);
-            let crate_types = collect_crate_types(sess, &pre_configured_attrs);
-            let stable_crate_id = StableCrateId::new(
-                crate_name,
-                crate_types.contains(&CrateType::Executable),
-                sess.opts.cg.metadata.clone(),
-                sess.cfg_version,
-            );
-            let outputs = util::build_output_filenames(&pre_configured_attrs, sess);
-            let dep_graph = setup_dep_graph(sess)?;
-
-            let cstore = FreezeLock::new(Box::new(CStore::new(
-                self.compiler.codegen_backend.metadata_loader(),
-            )) as _);
-            let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
-
-            let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default());
-            let untracked = Untracked {
-                cstore,
-                source_span: AppendOnlyIndexVec::new(),
-                definitions,
-                stable_crate_ids,
-            };
-
-            let qcx = passes::create_global_ctxt(
+            let krate = self.parse()?.steal();
+
+            passes::create_global_ctxt(
                 self.compiler,
-                crate_types,
-                stable_crate_id,
-                dep_graph,
-                untracked,
+                krate,
                 &self.gcx_cell,
                 &self.arena,
                 &self.hir_arena,
-            );
-
-            qcx.enter(|tcx| {
-                let feed = tcx.create_crate_num(stable_crate_id).unwrap();
-                assert_eq!(feed.key(), LOCAL_CRATE);
-                feed.crate_name(crate_name);
-
-                let feed = tcx.feed_unit_query();
-                feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
-                    sess,
-                    &pre_configured_attrs,
-                    crate_name,
-                )));
-                feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
-                feed.output_filenames(Arc::new(outputs));
-            });
-            Ok(qcx)
+            )
         })
     }
 
-    pub fn write_dep_info(&'tcx self) -> Result<()> {
-        self.global_ctxt()?.enter(|tcx| {
-            passes::write_dep_info(tcx);
-        });
-        Ok(())
-    }
-
-    /// Check for the `#[rustc_error]` annotation, which forces an error in codegen. This is used
-    /// to write UI tests that actually test that compilation succeeds without reporting
-    /// an error.
-    fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) {
-        let Some((def_id, _)) = tcx.entry_fn(()) else { return };
-        for attr in tcx.get_attrs(def_id, sym::rustc_error) {
-            match attr.meta_item_list() {
-                // Check if there is a `#[rustc_error(delayed_bug_from_inside_query)]`.
-                Some(list)
-                    if list.iter().any(|list_item| {
-                        matches!(
-                            list_item.ident().map(|i| i.name),
-                            Some(sym::delayed_bug_from_inside_query)
-                        )
-                    }) =>
-                {
-                    tcx.ensure().trigger_delayed_bug(def_id);
-                }
-
-                // Bare `#[rustc_error]`.
-                None => {
-                    tcx.dcx().emit_fatal(RustcErrorFatal { span: tcx.def_span(def_id) });
-                }
-
-                // Some other attribute.
-                Some(_) => {
-                    tcx.dcx()
-                        .emit_warn(RustcErrorUnexpectedAnnotation { span: tcx.def_span(def_id) });
-                }
-            }
-        }
-    }
-
     pub fn codegen_and_build_linker(&'tcx self) -> Result<Linker> {
         self.global_ctxt()?.enter(|tcx| {
-            // Don't do code generation if there were any errors. Likewise if
-            // there were any delayed bugs, because codegen will likely cause
-            // more ICEs, obscuring the original problem.
-            if let Some(guar) = self.compiler.sess.dcx().has_errors_or_delayed_bugs() {
-                return Err(guar);
-            }
-
-            // Hook for UI tests.
-            Self::check_for_rustc_errors_attr(tcx);
-
-            let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx);
+            let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx)?;
 
             Ok(Linker {
                 dep_graph: tcx.dep_graph.clone(),
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index eac5083ffbf..46cf87d1e3c 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -604,6 +604,9 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound
 lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
     .suggestion = use pat_param to preserve semantics
 
+lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope
+    .help = import `macro_rules` with `use` to make it callable above its definition
+
 lint_overflowing_bin_hex = literal out of range for `{$ty}`
     .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
     .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index adb2a3275c0..05e075205c4 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -434,5 +434,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
             lints::InnerAttributeUnstable::CustomInnerAttribute
         }
         .decorate_lint(diag),
+        BuiltinLintDiag::OutOfScopeMacroCalls { path } => {
+            lints::OutOfScopeMacroCalls { path }.decorate_lint(diag)
+        }
     }
 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 6df3a11deb0..14084405d0e 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2911,3 +2911,10 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion {
     #[suggestion_part(code = ")")]
     pub right: Span,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(lint_out_of_scope_macro_calls)]
+#[help]
+pub struct OutOfScopeMacroCalls {
+    pub path: String,
+}
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 7aef6321eeb..8b669bcc13f 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -109,7 +109,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
                     return;
                 }
 
-                let proj_ty = Ty::new_projection(
+                let proj_ty = Ty::new_projection_from_args(
                     cx.tcx,
                     proj.projection_term.def_id,
                     proj.projection_term.args,
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 265779c9374..a023d6161df 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4945,3 +4945,42 @@ declare_lint! {
         reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>",
     };
 }
+
+declare_lint! {
+    /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope,
+    /// above their definition, which may happen in key-value attributes.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![doc = in_root!()]
+    ///
+    /// macro_rules! in_root { () => { "" } }
+    ///
+    /// fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The scope in which a `macro_rules` item is visible starts at that item and continues
+    /// below it. This is more similar to `let` than to other items, which are in scope both above
+    /// and below their definition.
+    /// Due to a bug `macro_rules` were accidentally in scope inside some key-value attributes
+    /// above their definition. The lint catches such cases.
+    /// To address the issue turn the `macro_rules` into a regularly scoped item by importing it
+    /// with `use`.
+    ///
+    /// This is a [future-incompatible] lint to transition this to a
+    /// hard error in the future.
+    ///
+    /// [future-incompatible]: ../index.md#future-incompatible-lints
+    pub OUT_OF_SCOPE_MACRO_CALLS,
+    Warn,
+    "detects out of scope calls to `macro_rules` in key-value attributes",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reference: "issue #124535 <https://github.com/rust-lang/rust/issues/124535>",
+    };
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index f33aadfbbc8..b44eb252167 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -744,6 +744,9 @@ pub enum BuiltinLintDiag {
     InnerAttributeUnstable {
         is_macro: bool,
     },
+    OutOfScopeMacroCalls {
+        path: String,
+    },
 }
 
 /// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 01cefc75194..ef88b253864 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1817,11 +1817,11 @@ mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
-    static_assert_size!(BasicBlockData<'_>, 144);
+    static_assert_size!(BasicBlockData<'_>, 128);
     static_assert_size!(LocalDecl<'_>, 40);
     static_assert_size!(SourceScopeData<'_>, 64);
     static_assert_size!(Statement<'_>, 32);
-    static_assert_size!(Terminator<'_>, 112);
+    static_assert_size!(Terminator<'_>, 96);
     static_assert_size!(VarDebugInfo<'_>, 88);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 0fc84ea5c62..2c2884f1897 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -730,7 +730,7 @@ pub enum TerminatorKind<'tcx> {
         /// reused across function calls without duplicating the contents.
         /// The span for each arg is also included
         /// (e.g. `a` and `b` in `x.foo(a, b)`).
-        args: Vec<Spanned<Operand<'tcx>>>,
+        args: Box<[Spanned<Operand<'tcx>>]>,
         /// Where the returned value will be written
         destination: Place<'tcx>,
         /// Where to go after this call returns. If none, the call necessarily diverges.
@@ -837,7 +837,7 @@ pub enum TerminatorKind<'tcx> {
         template: &'tcx [InlineAsmTemplatePiece],
 
         /// The operands for the inline assembly, as `Operand`s or `Place`s.
-        operands: Vec<InlineAsmOperand<'tcx>>,
+        operands: Box<[InlineAsmOperand<'tcx>]>,
 
         /// Miscellaneous options for the inline assembly.
         options: InlineAsmOptions,
@@ -849,7 +849,7 @@ pub enum TerminatorKind<'tcx> {
         /// Valid targets for the inline assembly.
         /// The first element is the fallthrough destination, unless
         /// InlineAsmOptions::NORETURN is set.
-        targets: Vec<BasicBlock>,
+        targets: Box<[BasicBlock]>,
 
         /// Action to be taken if the inline assembly unwinds. This is present
         /// if and only if InlineAsmOptions::MAY_UNWIND is set.
@@ -1561,6 +1561,6 @@ mod size_asserts {
     static_assert_size!(PlaceElem<'_>, 24);
     static_assert_size!(Rvalue<'_>, 40);
     static_assert_size!(StatementKind<'_>, 16);
-    static_assert_size!(TerminatorKind<'_>, 96);
+    static_assert_size!(TerminatorKind<'_>, 80);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 7848aa21eac..4bac9396e59 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -240,7 +240,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
         let trait_generics = self.generics_of(trait_def_id);
         (
-            ty::TraitRef::new(self, trait_def_id, args.truncate_to(self, trait_generics)),
+            ty::TraitRef::new_from_args(self, trait_def_id, args.truncate_to(self, trait_generics)),
             &args[trait_generics.count()..],
         )
     }
@@ -261,12 +261,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.check_args_compatible(def_id, args)
     }
 
-    fn check_and_mk_args(
-        self,
-        def_id: DefId,
-        args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
-    ) -> ty::GenericArgsRef<'tcx> {
-        self.check_and_mk_args(def_id, args)
+    fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
+        self.debug_assert_args_compatible(def_id, args);
     }
 
     fn intern_canonical_goal_evaluation_step(
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index f608b02f42c..eb25aecd9ce 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -309,7 +309,8 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
 #[derive(Copy, Clone, Debug)]
 pub enum SizeSkeleton<'tcx> {
     /// Any statically computable Layout.
-    Known(Size),
+    /// Alignment can be `None` if unknown.
+    Known(Size, Option<Align>),
 
     /// This is a generic const expression (i.e. N * 2), which may contain some parameters.
     /// It must be of type usize, and represents the size of a type in bytes.
@@ -339,7 +340,12 @@ impl<'tcx> SizeSkeleton<'tcx> {
         // First try computing a static layout.
         let err = match tcx.layout_of(param_env.and(ty)) {
             Ok(layout) => {
-                return Ok(SizeSkeleton::Known(layout.size));
+                if layout.abi.is_sized() {
+                    return Ok(SizeSkeleton::Known(layout.size, Some(layout.align.abi)));
+                } else {
+                    // Just to be safe, don't claim a known layout for unsized types.
+                    return Err(tcx.arena.alloc(LayoutError::Unknown(ty)));
+                }
             }
             Err(err @ LayoutError::Unknown(_)) => err,
             // We can't extract SizeSkeleton info from other layout errors
@@ -389,19 +395,20 @@ impl<'tcx> SizeSkeleton<'tcx> {
             ty::Array(inner, len) if tcx.features().transmute_generic_consts => {
                 let len_eval = len.try_eval_target_usize(tcx, param_env);
                 if len_eval == Some(0) {
-                    return Ok(SizeSkeleton::Known(Size::from_bytes(0)));
+                    return Ok(SizeSkeleton::Known(Size::from_bytes(0), None));
                 }
 
                 match SizeSkeleton::compute(inner, tcx, param_env)? {
                     // This may succeed because the multiplication of two types may overflow
                     // but a single size of a nested array will not.
-                    SizeSkeleton::Known(s) => {
+                    SizeSkeleton::Known(s, a) => {
                         if let Some(c) = len_eval {
                             let size = s
                                 .bytes()
                                 .checked_mul(c)
                                 .ok_or_else(|| &*tcx.arena.alloc(LayoutError::SizeOverflow(ty)))?;
-                            return Ok(SizeSkeleton::Known(Size::from_bytes(size)));
+                            // Alignment is unchanged by arrays.
+                            return Ok(SizeSkeleton::Known(Size::from_bytes(size), a));
                         }
                         Err(tcx.arena.alloc(LayoutError::Unknown(ty)))
                     }
@@ -427,8 +434,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
                     for field in fields {
                         let field = field?;
                         match field {
-                            SizeSkeleton::Known(size) => {
-                                if size.bytes() > 0 {
+                            SizeSkeleton::Known(size, align) => {
+                                let is_1zst = size.bytes() == 0
+                                    && align.is_some_and(|align| align.bytes() == 1);
+                                if !is_1zst {
                                     return Err(err);
                                 }
                             }
@@ -492,7 +501,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
 
     pub fn same_size(self, other: SizeSkeleton<'tcx>) -> bool {
         match (self, other) {
-            (SizeSkeleton::Known(a), SizeSkeleton::Known(b)) => a == b,
+            (SizeSkeleton::Known(a, _), SizeSkeleton::Known(b, _)) => a == b,
             (SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => {
                 a == b
             }
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 71a93cc520d..73eba93194e 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -133,6 +133,20 @@ impl<H, T> RawList<H, T> {
     }
 }
 
+impl<'a, H, T: Copy> rustc_type_ir::inherent::SliceLike for &'a RawList<H, T> {
+    type Item = T;
+
+    type IntoIter = iter::Copied<<&'a [T] as IntoIterator>::IntoIter>;
+
+    fn iter(self) -> Self::IntoIter {
+        (*self).iter()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        (*self).as_slice()
+    }
+}
+
 macro_rules! impl_list_empty {
     ($header_ty:ty, $header_init:expr) => {
         impl<T> RawList<$header_ty, T> {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 709c5fe2305..ff40a726fbc 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -499,7 +499,7 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
-        Ty::new_alias(tcx, ty::Opaque, AliasTy::new(tcx, def_id, args))
+        Ty::new_alias(tcx, ty::Opaque, AliasTy::new_from_args(tcx, def_id, args))
     }
 
     /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed`
@@ -670,6 +670,15 @@ impl<'tcx> Ty<'tcx> {
     }
 
     #[inline]
+    pub fn new_projection_from_args(
+        tcx: TyCtxt<'tcx>,
+        item_def_id: DefId,
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> Ty<'tcx> {
+        Ty::new_alias(tcx, ty::Projection, AliasTy::new_from_args(tcx, item_def_id, args))
+    }
+
+    #[inline]
     pub fn new_projection(
         tcx: TyCtxt<'tcx>,
         item_def_id: DefId,
@@ -1409,7 +1418,7 @@ impl<'tcx> Ty<'tcx> {
                 let assoc_items = tcx.associated_item_def_ids(
                     tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
                 );
-                Ty::new_projection(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
+                Ty::new_projection_from_args(tcx, assoc_items[0], tcx.mk_args(&[self.into()]))
             }
 
             ty::Pat(ty, _) => ty.discriminant_ty(tcx),
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 7549481c1b3..94ab2fb4581 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -170,7 +170,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                     .map(|arg|
                         Ok(Spanned { node: self.parse_operand(*arg)?, span: self.thir.exprs[*arg].span  } )
                     )
-                    .collect::<PResult<Vec<_>>>()?;
+                    .collect::<PResult<Box<[_]>>>()?;
                 Ok(TerminatorKind::Call {
                     func: fun,
                     args,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 9f9b566bb8f..c5ee6db5999 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -152,10 +152,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     source_info,
                     TerminatorKind::Call {
                         func: exchange_malloc,
-                        args: vec![
+                        args: [
                             Spanned { node: Operand::Move(size), span: DUMMY_SP },
                             Spanned { node: Operand::Move(align), span: DUMMY_SP },
-                        ],
+                        ]
+                        .into(),
                         destination: storage,
                         target: Some(success),
                         unwind: UnwindAction::Continue,
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 6b4dd8b64a4..76bdc26a501 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -238,7 +238,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             ExprKind::Call { ty: _, fun, ref args, from_hir_call, fn_span } => {
                 let fun = unpack!(block = this.as_local_operand(block, fun));
-                let args: Vec<_> = args
+                let args: Box<[_]> = args
                     .into_iter()
                     .copied()
                     .map(|arg| Spanned {
@@ -485,7 +485,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         operands,
                         options,
                         line_spans,
-                        targets,
+                        targets: targets.into_boxed_slice(),
                         unwind: if options.contains(InlineAsmOptions::MAY_UNWIND) {
                             UnwindAction::Continue
                         } else {
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 11d3e2a8180..d29874a5ad4 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -324,7 +324,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     user_ty: None,
                     const_: method,
                 })),
-                args: vec![Spanned { node: Operand::Move(ref_src), span }],
+                args: [Spanned { node: Operand::Move(ref_src), span }].into(),
                 destination: temp,
                 target: Some(target_block),
                 unwind: UnwindAction::Continue,
@@ -486,10 +486,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     const_: method,
                 })),
-                args: vec![
+                args: [
                     Spanned { node: Operand::Copy(val), span: DUMMY_SP },
                     Spanned { node: expect, span: DUMMY_SP },
-                ],
+                ]
+                .into(),
                 destination: eq_result,
                 target: Some(eq_block),
                 unwind: UnwindAction::Continue,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index dda6c88008b..8c6c9e10cdf 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -220,7 +220,7 @@ impl<'tcx> ConstToPat<'tcx> {
             tcx,
             ObligationCause::dummy(),
             self.param_env,
-            ty::TraitRef::new(
+            ty::TraitRef::new_from_args(
                 tcx,
                 partial_eq_trait_id,
                 tcx.with_opt_host_effect_param(
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 654020164db..e0da9600ae3 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -650,10 +650,8 @@ where
                         [ty.into()],
                         self.source_info.span,
                     ),
-                    args: vec![Spanned {
-                        node: Operand::Move(Place::from(ref_place)),
-                        span: DUMMY_SP,
-                    }],
+                    args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
+                        .into(),
                     destination: unit_temp,
                     target: Some(succ),
                     unwind: unwind.into_action(),
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 6b338efd569..52db931b68e 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -34,7 +34,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
         2,
         mir::TerminatorKind::Call {
             func: mir::Operand::Copy(dummy_place.clone()),
-            args: vec![],
+            args: [].into(),
             destination: dummy_place.clone(),
             target: Some(mir::START_BLOCK),
             unwind: mir::UnwindAction::Continue,
@@ -48,7 +48,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
         4,
         mir::TerminatorKind::Call {
             func: mir::Operand::Copy(dummy_place.clone()),
-            args: vec![],
+            args: [].into(),
             destination: dummy_place.clone(),
             target: Some(mir::START_BLOCK),
             unwind: mir::UnwindAction::Continue,
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index bf79b4e133a..05674792426 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -677,8 +677,8 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
 fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
     let terminator = bb_data.terminator.take().unwrap();
-    if let TerminatorKind::Call { mut args, destination, target, .. } = terminator.kind {
-        let arg = args.pop().unwrap();
+    if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind {
+        let [arg] = *Box::try_from(args).unwrap();
         let local = arg.node.place().unwrap().local;
 
         let arg = Rvalue::Use(arg.node);
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 048547dc9f5..63a9f303b85 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -134,7 +134,7 @@ impl<'tcx> MockBlocks<'tcx> {
             some_from_block,
             TerminatorKind::Call {
                 func: Operand::Copy(self.dummy_place.clone()),
-                args: vec![],
+                args: [].into(),
                 destination: self.dummy_place.clone(),
                 target: Some(TEMP_BLOCK),
                 unwind: UnwindAction::Continue,
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 32b5d812025..0a5fc697d03 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -624,8 +624,7 @@ impl<'tcx> Inliner<'tcx> {
         };
 
         // Copy the arguments if needed.
-        let args: Vec<_> =
-            self.make_call_args(args, &callsite, caller_body, &callee_body, return_block);
+        let args = self.make_call_args(args, &callsite, caller_body, &callee_body, return_block);
 
         let mut integrator = Integrator {
             args: &args,
@@ -736,12 +735,12 @@ impl<'tcx> Inliner<'tcx> {
 
     fn make_call_args(
         &self,
-        args: Vec<Spanned<Operand<'tcx>>>,
+        args: Box<[Spanned<Operand<'tcx>>]>,
         callsite: &CallSite<'tcx>,
         caller_body: &mut Body<'tcx>,
         callee_body: &Body<'tcx>,
         return_block: Option<BasicBlock>,
-    ) -> Vec<Local> {
+    ) -> Box<[Local]> {
         let tcx = self.tcx;
 
         // There is a bit of a mismatch between the *caller* of a closure and the *callee*.
@@ -768,7 +767,8 @@ impl<'tcx> Inliner<'tcx> {
         //
         // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`.
         if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() {
-            let mut args = args.into_iter();
+            // FIXME(edition_2024): switch back to a normal method call.
+            let mut args = <_>::into_iter(args);
             let self_ = self.create_temp_if_necessary(
                 args.next().unwrap().node,
                 callsite,
@@ -802,7 +802,8 @@ impl<'tcx> Inliner<'tcx> {
 
             closure_ref_arg.chain(tuple_tmp_args).collect()
         } else {
-            args.into_iter()
+            // FIXME(edition_2024): switch back to a normal method call.
+            <_>::into_iter(args)
                 .map(|a| self.create_temp_if_necessary(a.node, callsite, caller_body, return_block))
                 .collect()
         }
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 6806c517c17..8209e5e2711 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -1,6 +1,7 @@
 //! Performs various peephole optimizations.
 
 use crate::simplify::simplify_duplicate_switch_targets;
+use crate::take_array;
 use rustc_ast::attr;
 use rustc_middle::bug;
 use rustc_middle::mir::*;
@@ -285,7 +286,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
             return;
         }
 
-        let Some(arg_place) = args.pop().unwrap().node.place() else { return };
+        let Ok([arg]) = take_array(args) else { return };
+        let Some(arg_place) = arg.node.place() else { return };
 
         statements.push(Statement {
             source_info: terminator.source_info,
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index fe195f0112f..f7056702cb4 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -160,8 +160,9 @@ fn remap_mir_for_const_eval_select<'tcx>(
             } if let ty::FnDef(def_id, _) = *const_.ty().kind()
                 && tcx.is_intrinsic(def_id, sym::const_eval_select) =>
             {
-                let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
-                    std::mem::take(args).try_into().unwrap();
+                let Ok([tupled_args, called_in_const, called_at_rt]) = take_array(args) else {
+                    unreachable!()
+                };
                 let ty = tupled_args.node.ty(&body.local_decls, tcx);
                 let fields = ty.tuple_fields();
                 let num_args = fields.len();
@@ -211,6 +212,11 @@ fn remap_mir_for_const_eval_select<'tcx>(
     body
 }
 
+fn take_array<T, const N: usize>(b: &mut Box<[T]>) -> Result<[T; N], Box<[T]>> {
+    let b: Box<[T; N]> = std::mem::take(b).try_into()?;
+    Ok(*b)
+}
+
 fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     tcx.mir_keys(()).contains(&def_id)
 }
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 3ffc447217d..6aa90394355 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -1,5 +1,6 @@
 //! Lowers intrinsic calls
 
+use crate::take_array;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, span_bug};
@@ -50,42 +51,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::copy_nonoverlapping => {
                         let target = target.unwrap();
-                        let mut args = args.drain(..);
+                        let Ok([src, dst, count]) = take_array(args) else {
+                            bug!("Wrong arguments for copy_non_overlapping intrinsic");
+                        };
                         block.statements.push(Statement {
                             source_info: terminator.source_info,
                             kind: StatementKind::Intrinsic(Box::new(
                                 NonDivergingIntrinsic::CopyNonOverlapping(
                                     rustc_middle::mir::CopyNonOverlapping {
-                                        src: args.next().unwrap().node,
-                                        dst: args.next().unwrap().node,
-                                        count: args.next().unwrap().node,
+                                        src: src.node,
+                                        dst: dst.node,
+                                        count: count.node,
                                     },
                                 ),
                             )),
                         });
-                        assert_eq!(
-                            args.next(),
-                            None,
-                            "Extra argument for copy_non_overlapping intrinsic"
-                        );
-                        drop(args);
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::assume => {
                         let target = target.unwrap();
-                        let mut args = args.drain(..);
+                        let Ok([arg]) = take_array(args) else {
+                            bug!("Wrong arguments for assume intrinsic");
+                        };
                         block.statements.push(Statement {
                             source_info: terminator.source_info,
                             kind: StatementKind::Intrinsic(Box::new(
-                                NonDivergingIntrinsic::Assume(args.next().unwrap().node),
+                                NonDivergingIntrinsic::Assume(arg.node),
                             )),
                         });
-                        assert_eq!(
-                            args.next(),
-                            None,
-                            "Extra argument for copy_non_overlapping intrinsic"
-                        );
-                        drop(args);
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::wrapping_add
@@ -100,13 +93,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     | sym::unchecked_shl
                     | sym::unchecked_shr => {
                         let target = target.unwrap();
-                        let lhs;
-                        let rhs;
-                        {
-                            let mut args = args.drain(..);
-                            lhs = args.next().unwrap();
-                            rhs = args.next().unwrap();
-                        }
+                        let Ok([lhs, rhs]) = take_array(args) else {
+                            bug!("Wrong arguments for {} intrinsic", intrinsic.name);
+                        };
                         let bin_op = match intrinsic.name {
                             sym::wrapping_add => BinOp::Add,
                             sym::wrapping_sub => BinOp::Sub,
@@ -132,13 +121,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
                         if let Some(target) = *target {
-                            let lhs;
-                            let rhs;
-                            {
-                                let mut args = args.drain(..);
-                                lhs = args.next().unwrap();
-                                rhs = args.next().unwrap();
-                            }
+                            let Ok([lhs, rhs]) = take_array(args) else {
+                                bug!("Wrong arguments for {} intrinsic", intrinsic.name);
+                            };
                             let bin_op = match intrinsic.name {
                                 sym::add_with_overflow => BinOp::AddWithOverflow,
                                 sym::sub_with_overflow => BinOp::SubWithOverflow,
@@ -174,7 +159,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                         }
                     }
                     sym::read_via_copy => {
-                        let [arg] = args.as_slice() else {
+                        let Ok([arg]) = take_array(args) else {
                             span_bug!(terminator.source_info.span, "Wrong number of arguments");
                         };
                         let derefed_place = if let Some(place) = arg.node.place()
@@ -207,7 +192,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::write_via_move => {
                         let target = target.unwrap();
-                        let Ok([ptr, val]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+                        let Ok([ptr, val]) = take_array(args) else {
                             span_bug!(
                                 terminator.source_info.span,
                                 "Wrong number of arguments for write_via_move intrinsic",
@@ -247,7 +232,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::offset => {
                         let target = target.unwrap();
-                        let Ok([ptr, delta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+                        let Ok([ptr, delta]) = take_array(args) else {
                             span_bug!(
                                 terminator.source_info.span,
                                 "Wrong number of arguments for offset intrinsic",
@@ -264,7 +249,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     }
                     sym::transmute | sym::transmute_unchecked => {
                         let dst_ty = destination.ty(local_decls, tcx).ty;
-                        let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else {
+                        let Ok([arg]) = take_array(args) else {
                             span_bug!(
                                 terminator.source_info.span,
                                 "Wrong number of arguments for transmute intrinsic",
@@ -289,7 +274,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                         }
                     }
                     sym::aggregate_raw_ptr => {
-                        let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+                        let Ok([data, meta]) = take_array(args) else {
                             span_bug!(
                                 terminator.source_info.span,
                                 "Wrong number of arguments for aggregate_raw_ptr intrinsic",
@@ -317,7 +302,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                         terminator.kind = TerminatorKind::Goto { target };
                     }
                     sym::ptr_metadata => {
-                        let Ok([ptr]) = <[_; 1]>::try_from(std::mem::take(args)) else {
+                        let Ok([ptr]) = take_array(args) else {
                             span_bug!(
                                 terminator.source_info.span,
                                 "Wrong number of arguments for ptr_metadata intrinsic",
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 825f8957187..25577e88e28 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -562,7 +562,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
             vec![statement],
             TerminatorKind::Call {
                 func,
-                args: vec![Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }],
+                args: [Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }].into(),
                 destination: dest,
                 target: Some(next),
                 unwind: UnwindAction::Cleanup(cleanup),
@@ -843,7 +843,7 @@ fn build_call_shim<'tcx>(
     };
 
     // BB #0
-    let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect::<Vec<_>>();
+    let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect();
     block(
         &mut blocks,
         statements,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index cae9c5c8567..ee7279a43b2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -527,7 +527,7 @@ where
         };
 
         for assumption in
-            self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), &alias_ty.args)
+            self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
         {
             candidates.extend(G::probe_and_consider_implied_clause(
                 self,
@@ -603,7 +603,7 @@ where
         // Consider all of the auto-trait and projection bounds, which don't
         // need to be recorded as a `BuiltinImplSource::Object` since they don't
         // really have a vtable base...
-        for bound in bounds {
+        for bound in bounds.iter() {
             match bound.skip_binder() {
                 ty::ExistentialPredicate::Trait(_) => {
                     // Skip principal
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index b10be5a9ba7..2df039c766c 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -58,7 +58,7 @@ where
 
         ty::Tuple(tys) => {
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-            Ok(tys.into_iter().map(ty::Binder::dummy).collect())
+            Ok(tys.iter().map(ty::Binder::dummy).collect())
         }
 
         ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@@ -79,23 +79,21 @@ where
             .cx()
             .bound_coroutine_hidden_types(def_id)
             .into_iter()
-            .map(|bty| bty.instantiate(tcx, &args))
+            .map(|bty| bty.instantiate(tcx, args))
             .collect()),
 
         // For `PhantomData<T>`, we pass `T`.
         ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
 
-        ty::Adt(def, args) => Ok(def
-            .all_field_tys(tcx)
-            .iter_instantiated(tcx, &args)
-            .map(ty::Binder::dummy)
-            .collect()),
+        ty::Adt(def, args) => {
+            Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect())
+        }
 
         ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
             // We can resolve the `impl Trait` to its concrete type,
             // which enforces a DAG between the functions requiring
             // the auto trait bounds in question.
-            Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, &args))])
+            Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))])
         }
     }
 }
@@ -147,7 +145,7 @@ where
 
         // impl Sized for ()
         // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
-        ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |&ty| vec![ty::Binder::dummy(ty)])),
+        ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])),
 
         // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
         //   `sized_constraint(Adt)` is the deepest struct trail that can be determined
@@ -160,7 +158,7 @@ where
         //   if the ADT is sized for all possible args.
         ty::Adt(def, args) => {
             if let Some(sized_crit) = def.sized_constraint(ecx.cx()) {
-                Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), &args))])
+                Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))])
             } else {
                 Ok(vec![])
             }
@@ -213,7 +211,7 @@ where
         }
 
         // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
-        ty::Tuple(tys) => Ok(tys.into_iter().map(ty::Binder::dummy).collect()),
+        ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
 
         // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
         ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@@ -242,7 +240,7 @@ where
             .cx()
             .bound_coroutine_hidden_types(def_id)
             .into_iter()
-            .map(|bty| bty.instantiate(ecx.cx(), &args))
+            .map(|bty| bty.instantiate(ecx.cx(), args))
             .collect()),
     }
 }
@@ -259,8 +257,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
             let sig = tcx.fn_sig(def_id);
             if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) {
                 Ok(Some(
-                    sig.instantiate(tcx, &args)
-                        .map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())),
+                    sig.instantiate(tcx, args)
+                        .map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())),
                 ))
             } else {
                 Err(NoSolution)
@@ -269,7 +267,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
         // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
         ty::FnPtr(sig) => {
             if sig.is_fn_trait_compatible() {
-                Ok(Some(sig.map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output()))))
+                Ok(Some(
+                    sig.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())),
+                ))
             } else {
                 Err(NoSolution)
             }
@@ -292,7 +292,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
                     }
                 }
             }
-            Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output()))))
+            Ok(Some(
+                closure_args.sig().map_bound(|sig| (sig.inputs().get(0).unwrap(), sig.output())),
+            ))
         }
 
         // Coroutine-closures don't implement `Fn` traits the normal way.
@@ -470,7 +472,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
             let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
             Ok((
                 bound_sig.rebind(AsyncCallableRelevantTypes {
-                    tupled_inputs_ty: Ty::new_tup(tcx, &sig.inputs()),
+                    tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs().as_slice()),
                     output_coroutine_ty: sig.output(),
                     coroutine_return_ty: future_output_ty,
                 }),
@@ -521,7 +523,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
             let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
             Ok((
                 bound_sig.rebind(AsyncCallableRelevantTypes {
-                    tupled_inputs_ty: sig.inputs()[0],
+                    tupled_inputs_ty: sig.inputs().get(0).unwrap(),
                     output_coroutine_ty: sig.output(),
                     coroutine_return_ty: future_output_ty,
                 }),
@@ -669,7 +671,7 @@ where
     let tcx = ecx.cx();
     let mut requirements = vec![];
     requirements
-        .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args));
+        .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args));
 
     // FIXME(associated_const_equality): Also add associated consts to
     // the requirements here.
@@ -680,13 +682,12 @@ where
             continue;
         }
 
-        requirements.extend(
-            tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args),
-        );
+        requirements
+            .extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args));
     }
 
     let mut replace_projection_with = HashMap::default();
-    for bound in object_bounds {
+    for bound in object_bounds.iter() {
         if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
             let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
             let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index f1d4864a84b..0a313c6a951 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -267,7 +267,9 @@ where
         // We therefore instantiate the existential variable in the canonical response with the
         // inference variable of the input right away, which is more performant.
         let mut opt_values = IndexVec::from_elem_n(None, response.variables.len());
-        for (original_value, result_value) in iter::zip(original_values, var_values.var_values) {
+        for (original_value, result_value) in
+            iter::zip(original_values, var_values.var_values.iter())
+        {
             match result_value.kind() {
                 ty::GenericArgKind::Type(t) => {
                     if let ty::Bound(debruijn, b) = t.kind() {
@@ -291,7 +293,7 @@ where
         }
 
         let var_values = delegate.cx().mk_args_from_iter(
-            response.variables.into_iter().enumerate().map(|(index, info)| {
+            response.variables.iter().enumerate().map(|(index, info)| {
                 if info.universe() != ty::UniverseIndex::ROOT {
                     // A variable from inside a binder of the query. While ideally these shouldn't
                     // exist at all (see the FIXME at the start of this method), we have to deal with
@@ -344,7 +346,7 @@ where
     ) {
         assert_eq!(original_values.len(), var_values.len());
 
-        for (&orig, response) in iter::zip(original_values, var_values.var_values) {
+        for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
             let goals =
                 delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
             assert!(goals.is_empty());
@@ -413,7 +415,8 @@ where
     // In case any fresh inference variables have been created between `state`
     // and the previous instantiation, extend `orig_values` for it.
     assert!(orig_values.len() <= state.value.var_values.len());
-    for &arg in &state.value.var_values.var_values[orig_values.len()..state.value.var_values.len()]
+    for &arg in &state.value.var_values.var_values.as_slice()
+        [orig_values.len()..state.value.var_values.len()]
     {
         // FIXME: This is so ugly.
         let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span);
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 6644fff2140..04dce2780b0 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -787,7 +787,7 @@ where
             // Alternatively we could modify `Equate` for this case by adding another
             // variant to `StructurallyRelateAliases`.
             let identity_args = self.fresh_args_for_item(alias.def_id);
-            let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args);
+            let rigid_ctor = ty::AliasTerm::new_from_args(tcx, alias.def_id, identity_args);
             let ctor_term = rigid_ctor.to_term(tcx);
             let obligations =
                 self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?;
@@ -875,7 +875,7 @@ where
 
     pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
         let args = self.delegate.fresh_args_for_item(def_id);
-        for arg in args {
+        for arg in args.iter() {
             self.inspect.add_var_value(arg);
         }
         args
@@ -979,7 +979,7 @@ where
                     result: *result,
                 })
                 .enter(|ecx| {
-                    for (a, b) in std::iter::zip(candidate_key.args, key.args) {
+                    for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
                         ecx.eq(param_env, a, b)?;
                     }
                     ecx.eq(param_env, candidate_ty, ty)?;
diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
index ae59f0c5e95..4fc58e06d67 100644
--- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
@@ -7,6 +7,7 @@
 use std::marker::PhantomData;
 use std::mem;
 
+use rustc_type_ir::inherent::*;
 use rustc_type_ir::{self as ty, Interner};
 
 use crate::delegate::SolverDelegate;
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index b76b4c09852..e29ae7ac0a2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -182,7 +182,7 @@ where
                 return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
             }
             ty::ConstKind::Unevaluated(uv) => {
-                self.cx().type_of(uv.def).instantiate(self.cx(), &uv.args)
+                self.cx().type_of(uv.def).instantiate(self.cx(), uv.args)
             }
             ty::ConstKind::Expr(_) => unimplemented!(
                 "`feature(generic_const_exprs)` is not supported in the new trait solver"
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
index 827fe5f2ca4..004ecf2d2c4 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
@@ -29,7 +29,7 @@ where
         self.eq(
             goal.param_env,
             inherent.self_ty(),
-            tcx.type_of(impl_def_id).instantiate(tcx, &impl_args),
+            tcx.type_of(impl_def_id).instantiate(tcx, impl_args),
         )?;
 
         // Equate IAT with the RHS of the project goal
@@ -44,11 +44,11 @@ where
         self.add_goals(
             GoalSource::Misc,
             tcx.predicates_of(inherent.def_id)
-                .iter_instantiated(tcx, &inherent_args)
+                .iter_instantiated(tcx, inherent_args)
                 .map(|pred| goal.with(tcx, pred)),
         );
 
-        let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, &inherent_args);
+        let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args);
         self.instantiate_normalizes_to_term(goal, normalized.into());
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index f58384d86cd..bc5233c4887 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -121,7 +121,7 @@ where
                     ecx.add_goals(
                         GoalSource::Misc,
                         tcx.own_predicates_of(goal.predicate.def_id())
-                            .iter_instantiated(tcx, &goal.predicate.alias.args)
+                            .iter_instantiated(tcx, goal.predicate.alias.args)
                             .map(|pred| goal.with(tcx, pred)),
                     );
 
@@ -163,13 +163,13 @@ where
 
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
-            let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args);
+            let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
 
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
-                .iter_instantiated(tcx, &impl_args)
+                .iter_instantiated(tcx, impl_args)
                 .map(|pred| goal.with(tcx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
@@ -177,7 +177,7 @@ where
             ecx.add_goals(
                 GoalSource::Misc,
                 tcx.own_predicates_of(goal.predicate.def_id())
-                    .iter_instantiated(tcx, &goal.predicate.alias.args)
+                    .iter_instantiated(tcx, goal.predicate.alias.args)
                     .map(|pred| goal.with(tcx, pred)),
             );
 
@@ -254,7 +254,7 @@ where
                 kind => panic!("expected projection, found {kind:?}"),
             };
 
-            ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, &target_args));
+            ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, target_args));
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -467,7 +467,7 @@ where
             tupled_inputs_ty,
             tupled_upvars_ty,
             coroutine_captures_by_ref_ty,
-        ] = **goal.predicate.alias.args
+        ] = *goal.predicate.alias.args.as_slice()
         else {
             panic!();
         };
@@ -567,14 +567,14 @@ where
                 ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) {
                     None => Ty::new_unit(tcx),
                     Some(tail_ty) => {
-                        Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, &args)])
+                        Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, args)])
                     }
                 },
                 ty::Adt(_, _) => Ty::new_unit(tcx),
 
                 ty::Tuple(elements) => match elements.last() {
                     None => Ty::new_unit(tcx),
-                    Some(&tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
+                    Some(tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
                 },
 
                 ty::Infer(
@@ -895,7 +895,7 @@ where
         } else {
             let target_args = self.fresh_args_for_item(target_container_def_id);
             let target_trait_ref =
-                tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, &target_args);
+                tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, target_args);
             // Relate source impl to target impl by equating trait refs.
             self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?;
             // Also add predicates since they may be needed to constrain the
@@ -903,7 +903,7 @@ where
             self.add_goals(
                 GoalSource::Misc,
                 tcx.predicates_of(target_container_def_id)
-                    .iter_instantiated(tcx, &target_args)
+                    .iter_instantiated(tcx, target_args)
                     .map(|pred| goal.with(tcx, pred)),
             );
             goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args)
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
index f3494328d9e..a16f9e64f2f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
@@ -86,7 +86,7 @@ where
             }
             (Reveal::All, _) => {
                 // FIXME: Add an assertion that opaque type storage is empty.
-                let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, &opaque_ty.args);
+                let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args);
                 self.eq(goal.param_env, expected, actual)?;
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
@@ -102,7 +102,7 @@ pub fn uses_unique_placeholders_ignoring_regions<I: Interner>(
     args: I::GenericArgs,
 ) -> Result<(), NotUniqueParam<I>> {
     let mut seen = GrowableBitSet::default();
-    for arg in args {
+    for arg in args.iter() {
         match arg.kind() {
             // Ignore regions, since we can't resolve those in a canonicalized
             // query in the trait solver.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
index 27d5ae07729..ca90bc17cc7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
@@ -25,11 +25,11 @@ where
         self.add_goals(
             GoalSource::Misc,
             tcx.predicates_of(weak_ty.def_id)
-                .iter_instantiated(tcx, &weak_ty.args)
+                .iter_instantiated(tcx, weak_ty.args)
                 .map(|pred| goal.with(tcx, pred)),
         );
 
-        let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, &weak_ty.args);
+        let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
         self.instantiate_normalizes_to_term(goal, actual.into());
 
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 2ddb3c981db..9746c836aff 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -77,12 +77,12 @@ where
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
             ecx.record_impl_args(impl_args);
-            let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args);
+            let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
-                .iter_instantiated(tcx, &impl_args)
+                .iter_instantiated(tcx, impl_args)
                 .map(|pred| goal.with(tcx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
@@ -186,7 +186,7 @@ where
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let nested_obligations = tcx
                 .predicates_of(goal.predicate.def_id())
-                .iter_instantiated(tcx, &goal.predicate.trait_ref.args)
+                .iter_instantiated(tcx, goal.predicate.trait_ref.args)
                 .map(|p| goal.with(tcx, p));
             // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
             ecx.add_goals(GoalSource::Misc, nested_obligations);
@@ -373,7 +373,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution> {
-        let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else {
+        let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
             panic!();
         };
 
@@ -783,7 +783,7 @@ where
             // (i.e. the principal, all of the associated types match, and any auto traits)
             ecx.add_goals(
                 GoalSource::ImplWhereBound,
-                b_data.into_iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
+                b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
             );
 
             // The type must be `Sized` to be unsized.
@@ -851,7 +851,7 @@ where
             };
 
         self.probe_trait_candidate(source).enter(|ecx| {
-            for bound in b_data {
+            for bound in b_data.iter() {
                 match bound.skip_binder() {
                     // Check that a's supertrait (upcast_principal) is compatible
                     // with the target (b_ty).
@@ -953,18 +953,15 @@ where
 
         let tail_field_ty = def.struct_tail_ty(tcx).unwrap();
 
-        let a_tail_ty = tail_field_ty.instantiate(tcx, &a_args);
-        let b_tail_ty = tail_field_ty.instantiate(tcx, &b_args);
+        let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
+        let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
 
         // Instantiate just the unsizing params from B into A. The type after
         // this instantiation must be equal to B. This is so we don't unsize
         // unrelated type parameters.
-        let new_a_args = tcx.mk_args_from_iter(
-            a_args
-                .iter()
-                .enumerate()
-                .map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { *a }),
-        );
+        let new_a_args = tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
+            if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
+        }));
         let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args);
 
         // Finally, we require that `TailA: Unsize<TailB>` for the tail field
@@ -1005,7 +1002,7 @@ where
         let Goal { predicate: (_a_ty, b_ty), .. } = goal;
 
         let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
-        let &b_last_ty = b_tys.last().unwrap();
+        let b_last_ty = b_tys.last().unwrap();
 
         // Instantiate just the tail field of B., and require that they're equal.
         let unsized_a_ty =
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 3a4690670af..42392ad2163 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -322,9 +322,8 @@ error: foo
  --> test.rs:3:3
   |
 3 |      X0 Y0
-  |   ___^__-
-  |  |___|
-  | ||
+  |  ____^  -
+  | | ______|
 4 | ||   X1 Y1
 5 | ||   X2 Y2
   | ||____^__- `Y` is a good letter too
@@ -361,9 +360,8 @@ error: foo
  --> test.rs:3:3
   |
 3 |      X0 Y0
-  |   ___^__-
-  |  |___|
-  | ||
+  |  ____^  -
+  | | ______|
 4 | ||   Y1 X1
   | ||____-__^ `X` is a good letter
   |  |____|
@@ -445,10 +443,9 @@ error: foo
  --> test.rs:3:3
   |
 3 |       X0 Y0 Z0
-  |    ___^__-__-
-  |   |___|__|
-  |  ||___|
-  | |||
+  |  _____^  -  -
+  | | _______|  |
+  | || _________|
 4 | |||   X1 Y1 Z1
 5 | |||   X2 Y2 Z2
   | |||____^__-__- `Z` label
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index bcb1131cc19..3d5e6371f4c 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -4,8 +4,10 @@ use crate::{errors, parse_in};
 
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::DelimSpan;
-use rustc_ast::MetaItemKind;
-use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety};
+use rustc_ast::{
+    self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind,
+    NestedMetaItem, Safety,
+};
 use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::{
     AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
@@ -184,9 +186,13 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim
 
 /// Checks that the given meta-item is compatible with this `AttributeTemplate`.
 fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool {
+    let is_one_allowed_subword = |items: &[NestedMetaItem]| match items {
+        [item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)),
+        _ => false,
+    };
     match meta {
         MetaItemKind::Word => template.word,
-        MetaItemKind::List(..) => template.list.is_some(),
+        MetaItemKind::List(items) => template.list.is_some() || is_one_allowed_subword(items),
         MetaItemKind::NameValue(lit) if lit.kind.is_str() => template.name_value_str.is_some(),
         MetaItemKind::NameValue(..) => false,
     }
@@ -230,6 +236,7 @@ fn emit_malformed_attribute(
     if let Some(descr) = template.list {
         suggestions.push(format!("#{inner}[{name}({descr})]"));
     }
+    suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]")));
     if let Some(descr) = template.name_value_str {
         suggestions.push(format!("#{inner}[{name} = \"{descr}\"]"));
     }
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 9a830b0f49b..5a560325ab9 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -103,18 +103,9 @@ passes_continue_labeled_block =
     .label = labeled blocks cannot be `continue`'d
     .block_label = labeled block the `continue` points to
 
-passes_coverage_fn_defn =
-    `#[coverage]` may only be applied to function definitions
-
-passes_coverage_ignored_function_prototype =
-    `#[coverage]` is ignored on function prototypes
-
-passes_coverage_not_coverable =
-    `#[coverage]` must be applied to coverable code
-    .label = not coverable code
-
-passes_coverage_propagate =
-    `#[coverage]` does not propagate into items and must be applied to the contained functions directly
+passes_coverage_not_fn_or_closure =
+    attribute should be applied to a function definition or closure
+    .label = not a function or closure
 
 passes_dead_codes =
     { $multiple ->
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 2ed5bba85c6..d33f12a973f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -122,7 +122,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     self.check_diagnostic_on_unimplemented(attr.span, hir_id, target)
                 }
                 [sym::inline] => self.check_inline(hir_id, attr, span, target),
-                [sym::coverage] => self.check_coverage(hir_id, attr, span, target),
+                [sym::coverage] => self.check_coverage(attr, span, target),
                 [sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target),
                 [sym::marker] => self.check_marker(hir_id, attr, span, target),
                 [sym::target_feature] => {
@@ -369,47 +369,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Checks if a `#[coverage]` is applied directly to a function
-    fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
+    /// Checks that `#[coverage(..)]` is applied to a function or closure.
+    fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool {
         match target {
-            // #[coverage] on function is fine
+            // #[coverage(..)] on function is fine
             Target::Fn
             | Target::Closure
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
-
-            // function prototypes can't be covered
-            Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span,
-                    errors::IgnoredCoverageFnProto,
-                );
-                true
-            }
-
-            Target::Mod | Target::ForeignMod | Target::Impl | Target::Trait => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span,
-                    errors::IgnoredCoveragePropagate,
-                );
-                true
-            }
-
-            Target::Expression | Target::Statement | Target::Arm => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span,
-                    errors::IgnoredCoverageFnDefn,
-                );
-                true
-            }
-
             _ => {
-                self.dcx().emit_err(errors::IgnoredCoverageNotCoverable {
+                self.dcx().emit_err(errors::CoverageNotFnOrClosure {
                     attr_span: attr.span,
                     defn_span: span,
                 });
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 69386c0fbdb..7c7700dd859 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -1010,6 +1010,22 @@ impl<'tcx> DeadVisitor<'tcx> {
         parent_item: Option<LocalDefId>,
         report_on: ReportOn,
     ) {
+        fn get_parent_if_enum_variant<'tcx>(
+            tcx: TyCtxt<'tcx>,
+            may_variant: LocalDefId,
+        ) -> LocalDefId {
+            if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant)
+                && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
+                && let Some(enum_local_id) = enum_did.as_local()
+                && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
+                && let ItemKind::Enum(_, _) = item.kind
+            {
+                enum_local_id
+            } else {
+                may_variant
+            }
+        }
+
         let Some(&first_item) = dead_codes.first() else {
             return;
         };
@@ -1053,6 +1069,9 @@ impl<'tcx> DeadVisitor<'tcx> {
         };
 
         let encl_def_id = parent_item.unwrap_or(first_item.def_id);
+        // If parent of encl_def_id is an enum, use the parent ID intead.
+        let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id);
+
         let ignored_derived_impls =
             if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
                 let trait_list = ign_traits
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index f0596568092..7734dba3670 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -60,21 +60,9 @@ pub struct InlineNotFnOrClosure {
     pub defn_span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_coverage_ignored_function_prototype)]
-pub struct IgnoredCoverageFnProto;
-
-#[derive(LintDiagnostic)]
-#[diag(passes_coverage_propagate)]
-pub struct IgnoredCoveragePropagate;
-
-#[derive(LintDiagnostic)]
-#[diag(passes_coverage_fn_defn)]
-pub struct IgnoredCoverageFnDefn;
-
 #[derive(Diagnostic)]
-#[diag(passes_coverage_not_coverable, code = E0788)]
-pub struct IgnoredCoverageNotCoverable {
+#[diag(passes_coverage_not_fn_or_closure, code = E0788)]
+pub struct CoverageNotFnOrClosure {
     #[primary_span]
     pub attr_span: Span,
     #[label]
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 5f1a03502a7..f2a68e35671 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -301,9 +301,12 @@ impl<HCX> ToStableHashKey<HCX> for WorkProductId {
         self.hash
     }
 }
-unsafe impl StableOrd for WorkProductId {
+impl StableOrd for WorkProductId {
     // Fingerprint can use unstable (just a tuple of `u64`s), so WorkProductId can as well
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // `WorkProductId` sort order is not affected by (de)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index e035749fc39..4e0f2792d97 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -14,7 +14,7 @@ use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, Modul
 use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError};
 use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError};
 
-use rustc_ast::visit::{self, AssocCtxt, Visitor};
+use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
 use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
 use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
 use rustc_attr as attr;
@@ -1313,7 +1313,17 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             _ => {
                 let orig_macro_rules_scope = self.parent_scope.macro_rules;
                 self.build_reduced_graph_for_item(item);
-                visit::walk_item(self, item);
+                match item.kind {
+                    ItemKind::Mod(..) => {
+                        // Visit attributes after items for backward compatibility.
+                        // This way they can use `macro_rules` defined later.
+                        self.visit_vis(&item.vis);
+                        self.visit_ident(item.ident);
+                        item.kind.walk(item, AssocCtxt::Trait, self);
+                        visit::walk_list!(self, visit_attribute, &item.attrs);
+                    }
+                    _ => visit::walk_item(self, item),
+                }
                 match item.kind {
                     ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
                         self.parent_scope.macro_rules
@@ -1514,7 +1524,10 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         if krate.is_placeholder {
             self.visit_invoc_in_module(krate.id);
         } else {
-            visit::walk_crate(self, krate);
+            // Visit attributes after items for backward compatibility.
+            // This way they can use `macro_rules` defined later.
+            visit::walk_list!(self, visit_item, &krate.items);
+            visit::walk_list!(self, visit_attribute, &krate.attrs);
             self.contains_macro_use(&krate.attrs);
         }
     }
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 87794d11cea..026a2ca1412 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -5,7 +5,7 @@ use crate::errors::CannotDetermineMacroResolution;
 use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope};
 use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive};
 use crate::Namespace::*;
-use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, Used};
+use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, NameBindingKind, Used};
 use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
 use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use rustc_ast::expand::StrippedCfgItem;
@@ -18,15 +18,18 @@ use rustc_errors::{Applicability, StashKey};
 use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::compile_declarative_macro;
-use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
+use rustc_expand::expand::{
+    AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
+};
 use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_middle::middle::stability;
 use rustc_middle::ty::RegisteredTools;
 use rustc_middle::ty::{TyCtxt, Visibility};
-use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
-use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
-use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
+use rustc_session::lint::builtin::{
+    LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, SOFT_UNSTABLE,
+    UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACROS, UNUSED_MACRO_RULES,
+};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::edit_distance;
@@ -140,9 +143,10 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
             }
         }
     }
-    // We implicitly add `rustfmt`, `clippy`, `diagnostic` to known tools,
-    // but it's not an error to register them explicitly.
-    let predefined_tools = [sym::clippy, sym::rustfmt, sym::diagnostic, sym::miri];
+    // We implicitly add `rustfmt`, `clippy`, `diagnostic`, `miri` and `rust_analyzer` to known
+    // tools, but it's not an error to register them explicitly.
+    let predefined_tools =
+        [sym::clippy, sym::rustfmt, sym::diagnostic, sym::miri, sym::rust_analyzer];
     registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
     registered_tools
 }
@@ -288,6 +292,16 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
         let parent_scope = &ParentScope { derives, ..parent_scope };
         let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion();
         let node_id = invoc.expansion_data.lint_node_id;
+        // This is a heuristic, but it's good enough for the lint.
+        let looks_like_invoc_in_mod_inert_attr = self
+            .invocation_parents
+            .get(&invoc_id)
+            .or_else(|| self.invocation_parents.get(&eager_expansion_root))
+            .map(|&(mod_def_id, _)| mod_def_id)
+            .filter(|&mod_def_id| {
+                invoc.fragment_kind == AstFragmentKind::Expr
+                    && self.tcx.def_kind(mod_def_id) == DefKind::Mod
+            });
         let (ext, res) = self.smart_resolve_macro_path(
             path,
             kind,
@@ -298,6 +312,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
             force,
             soft_custom_inner_attributes_gate(path, invoc),
             deleg_impl,
+            looks_like_invoc_in_mod_inert_attr,
         )?;
 
         let span = invoc.span();
@@ -520,6 +535,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         force: bool,
         soft_custom_inner_attributes_gate: bool,
         deleg_impl: Option<LocalDefId>,
+        invoc_in_mod_inert_attr: Option<LocalDefId>,
     ) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
         let (ext, res) = match self.resolve_macro_or_delegation_path(
             path,
@@ -528,6 +544,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             true,
             force,
             deleg_impl,
+            invoc_in_mod_inert_attr.map(|def_id| (def_id, node_id)),
         ) {
             Ok((Some(ext), res)) => (ext, res),
             Ok((None, res)) => (self.dummy_ext(kind), res),
@@ -682,20 +699,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         trace: bool,
         force: bool,
     ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
-        self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None)
+        self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None, None)
     }
 
     fn resolve_macro_or_delegation_path(
         &mut self,
-        path: &ast::Path,
+        ast_path: &ast::Path,
         kind: Option<MacroKind>,
         parent_scope: &ParentScope<'a>,
         trace: bool,
         force: bool,
         deleg_impl: Option<LocalDefId>,
+        invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
     ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
-        let path_span = path.span;
-        let mut path = Segment::from_path(path);
+        let path_span = ast_path.span;
+        let mut path = Segment::from_path(ast_path);
 
         // Possibly apply the macro helper hack
         if deleg_impl.is_none()
@@ -761,6 +779,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             let res = binding.map(|binding| binding.res());
             self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
+            self.report_out_of_scope_macro_calls(
+                ast_path,
+                parent_scope,
+                invoc_in_mod_inert_attr,
+                binding.ok(),
+            );
             res
         };
 
@@ -1013,6 +1037,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
+    fn report_out_of_scope_macro_calls(
+        &mut self,
+        path: &ast::Path,
+        parent_scope: &ParentScope<'a>,
+        invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
+        binding: Option<NameBinding<'a>>,
+    ) {
+        if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
+            && let Some(binding) = binding
+            // This is a `macro_rules` itself, not some import.
+            && let NameBindingKind::Res(res) = binding.kind
+            && let Res::Def(DefKind::Macro(MacroKind::Bang), def_id) = res
+            // And the `macro_rules` is defined inside the attribute's module,
+            // so it cannot be in scope unless imported.
+            && self.tcx.is_descendant_of(def_id, mod_def_id.to_def_id())
+        {
+            // Try to resolve our ident ignoring `macro_rules` scopes.
+            // If such resolution is successful and gives the same result
+            // (e.g. if the macro is re-imported), then silence the lint.
+            let no_macro_rules = self.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty);
+            let fallback_binding = self.early_resolve_ident_in_lexical_scope(
+                path.segments[0].ident,
+                ScopeSet::Macro(MacroKind::Bang),
+                &ParentScope { macro_rules: no_macro_rules, ..*parent_scope },
+                None,
+                false,
+                None,
+            );
+            if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
+                self.tcx.sess.psess.buffer_lint(
+                    OUT_OF_SCOPE_MACRO_CALLS,
+                    path.span,
+                    node_id,
+                    BuiltinLintDiag::OutOfScopeMacroCalls { path: pprust::path_to_string(path) },
+                );
+            }
+        }
+    }
+
     pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
         // Reserve some names that are not quite covered by the general check
         // performed on `Resolver::builtin_attrs`.
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 44b31f2659c..f0f2d1fefd2 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -232,7 +232,8 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
                 .filter(|item| item.kind == ty::AssocKind::Type)
                 .map(move |assoc_ty| {
                     super_poly_trait_ref.map_bound(|super_trait_ref| {
-                        let alias_ty = ty::AliasTy::new(tcx, assoc_ty.def_id, super_trait_ref.args);
+                        let alias_ty =
+                            ty::AliasTy::new_from_args(tcx, assoc_ty.def_id, super_trait_ref.args);
                         let resolved = tcx.normalize_erasing_regions(
                             ty::ParamEnv::reveal_all(),
                             alias_ty.to_ty(tcx),
@@ -351,7 +352,7 @@ pub fn transform_instance<'tcx>(
         // Adjust the type ids of VTableShims to the type id expected in the call sites for the
         // entry in the vtable (i.e., by using the signature of the closure passed as an argument
         // to the shim, or by just removing self).
-        let trait_ref = ty::TraitRef::new(tcx, trait_id, instance.args);
+        let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, instance.args);
         let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
         instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
     }
@@ -432,7 +433,7 @@ pub fn transform_instance<'tcx>(
                 x => bug!("Unexpected type kind for closure-like: {x:?}"),
             };
             let concrete_args = tcx.mk_args_trait(closure_ty, inputs.map(Into::into));
-            let trait_ref = ty::TraitRef::new(tcx, trait_id, concrete_args);
+            let trait_ref = ty::TraitRef::new_from_args(tcx, trait_id, concrete_args);
             let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
             let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
             // There should be exactly one method on this trait, and it should be the one we're
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 839cc51efce..2d38ad37133 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -498,9 +498,11 @@ pub enum OutputType {
     DepInfo,
 }
 
-// Safety: Trivial C-Style enums have a stable sort order across compilation sessions.
-unsafe impl StableOrd for OutputType {
+impl StableOrd for OutputType {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // Trivial C-Style enums have a stable sort order across compilation sessions.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index f068d093889..9a10adeb6d1 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1499,7 +1499,8 @@ options! {
     incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "enable incremental compilation"),
     inline_threshold: Option<u32> = (None, parse_opt_number, [TRACKED],
-        "set the threshold for inlining a function"),
+        "this option is deprecated and does nothing \
+        (consider using `-Cllvm-args=--inline-threshold=...`)"),
     #[rustc_lint_opt_deny_field_access("use `Session::instrument_coverage` instead of this field")]
     instrument_coverage: InstrumentCoverage = (InstrumentCoverage::No, parse_instrument_coverage, [TRACKED],
         "instrument the generated code to support LLVM source-based code coverage reports \
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index c33a52f4a7a..c9c1570a29a 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -408,7 +408,7 @@ impl RustcInternal for TraitRef {
     type T<'tcx> = rustc_ty::TraitRef<'tcx>;
 
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
-        rustc_ty::TraitRef::new(
+        rustc_ty::TraitRef::new_from_args(
             tcx,
             self.def_id.0.internal(tables, tcx),
             self.args().internal(tables, tcx),
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 1ac3a817bba..5456303b36f 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -120,9 +120,11 @@ impl Default for DefPathHash {
     }
 }
 
-// Safety: `DefPathHash` sort order is not affected (de)serialization.
-unsafe impl StableOrd for DefPathHash {
+impl StableOrd for DefPathHash {
     const CAN_USE_UNSTABLE_SORT: bool = true;
+
+    // `DefPathHash` sort order is not affected by (de)serialization.
+    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
 }
 
 /// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8d8f4927e99..6d4a8c29bc9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -174,6 +174,7 @@ symbols! {
         Center,
         Cleanup,
         Clone,
+        CoerceUnsized,
         Command,
         ConstParamTy,
         Context,
@@ -189,6 +190,7 @@ symbols! {
         DiagMessage,
         Diagnostic,
         DirBuilder,
+        DispatchFromDyn,
         Display,
         DoubleEndedIterator,
         Duration,
@@ -299,8 +301,10 @@ symbols! {
         Saturating,
         Send,
         SeqCst,
+        Sized,
         SliceIndex,
         SliceIter,
+        SmartPointer,
         Some,
         SpanCtxt,
         String,
@@ -323,6 +327,7 @@ symbols! {
         TyCtxt,
         TyKind,
         Unknown,
+        Unsize,
         Upvars,
         Vec,
         VecDeque,
@@ -707,6 +712,7 @@ symbols! {
         derive,
         derive_const,
         derive_default_enum,
+        derive_smart_pointer,
         destruct,
         destructuring_assignment,
         diagnostic,
@@ -1315,6 +1321,7 @@ symbols! {
         on,
         on_unimplemented,
         opaque,
+        ops,
         opt_out_copy,
         optimize,
         optimize_attribute,
@@ -1389,6 +1396,7 @@ symbols! {
         plugin,
         plugin_registrar,
         plugins,
+        pointee,
         pointee_trait,
         pointer,
         pointer_like,
@@ -1559,6 +1567,7 @@ symbols! {
         rust_2018_preview,
         rust_2021,
         rust_2024,
+        rust_analyzer,
         rust_begin_unwind,
         rust_cold_cc,
         rust_eh_catch_typeinfo,
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 b2fa3489dda..f4a026c0367 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -630,7 +630,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     let trait_pred_and_ty = trait_pred.map_bound(|inner| {
                         (
                             ty::TraitPredicate {
-                                trait_ref: ty::TraitRef::new(
+                                trait_ref: ty::TraitRef::new_from_args(
                                     self.tcx,
                                     inner.trait_ref.def_id,
                                     self.tcx.mk_args(
@@ -2915,38 +2915,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             }
             ObligationCauseCode::RepeatElementCopy {
                 is_constable,
-                elt_type,
+                elt_type: _,
                 elt_span,
-                elt_stmt_span,
+                elt_stmt_span: _,
             } => {
                 err.note(
                     "the `Copy` trait is required because this value will be copied for each element of the array",
                 );
-                let value_kind = match is_constable {
-                    IsConstable::Fn => Some("the result of the function call"),
-                    IsConstable::Ctor => Some("the result of the constructor"),
-                    _ => None,
-                };
                 let sm = tcx.sess.source_map();
-                if let Some(value_kind) = value_kind
+                if matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
                     && let Ok(snip) = sm.span_to_snippet(elt_span)
                 {
-                    let help_msg = format!(
-                        "consider creating a new `const` item and initializing it with {value_kind} \
-                        to be used in the repeat position"
-                    );
-                    let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default();
-                    err.multipart_suggestion(
-                        help_msg,
-                        vec![
-                            (
-                                elt_stmt_span.shrink_to_lo(),
-                                format!(
-                                    "const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}"
-                                ),
-                            ),
-                            (elt_span, "ARRAY_REPEAT_VALUE".to_string()),
-                        ],
+                    err.span_suggestion(
+                        elt_span,
+                        "create an inline `const` block",
+                        format!("const {{ {snip} }}"),
                         Applicability::MachineApplicable,
                     );
                 } else {
@@ -2954,15 +2937,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     err.help("consider using `core::array::from_fn` to initialize the array");
                     err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information");
                 }
-
-                if tcx.sess.is_nightly_build()
-                    && matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
-                {
-                    err.help(
-                        "create an inline `const` block, see RFC #2920 \
-                         <https://github.com/rust-lang/rfcs/pull/2920> for more information",
-                    );
-                }
             }
             ObligationCauseCode::VariableType(hir_id) => {
                 if let Some(typeck_results) = &self.typeck_results
@@ -3955,7 +3929,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
             // Extract `<U as Deref>::Target` assoc type and check that it is `T`
             && let Some(deref_target_did) = tcx.lang_items().deref_target()
-            && let projection = Ty::new_projection(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)]))
+            && let projection = Ty::new_projection_from_args(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)]))
             && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection)
             && obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation))
             && infcx.can_eq(param_env, deref_target, target_ty)
@@ -4290,7 +4264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             // This corresponds to `<ExprTy as Iterator>::Item = _`.
             let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
                 ty::ClauseKind::Projection(ty::ProjectionPredicate {
-                    projection_term: ty::AliasTerm::new(self.tcx, proj.def_id, args),
+                    projection_term: ty::AliasTerm::new_from_args(self.tcx, proj.def_id, args),
                     term: ty.into(),
                 }),
             ));
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index fc5a2875b67..4d10d33fa6e 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -689,7 +689,7 @@ fn receiver_is_dispatchable<'tcx>(
                 if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
             });
 
-            ty::TraitRef::new(tcx, trait_def_id, args).upcast(tcx)
+            ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
         };
 
         let caller_bounds =
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 8ab324e6601..1d7a0515044 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -727,10 +727,12 @@ fn project<'cx, 'tcx>(
         ProjectionCandidateSet::None => {
             let tcx = selcx.tcx();
             let term = match tcx.def_kind(obligation.predicate.def_id) {
-                DefKind::AssocTy => {
-                    Ty::new_projection(tcx, obligation.predicate.def_id, obligation.predicate.args)
-                        .into()
-                }
+                DefKind::AssocTy => Ty::new_projection_from_args(
+                    tcx,
+                    obligation.predicate.def_id,
+                    obligation.predicate.args,
+                )
+                .into(),
                 DefKind::AssocConst => ty::Const::new_unevaluated(
                     tcx,
                     ty::UnevaluatedConst::new(
@@ -1387,7 +1389,11 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
     };
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new_from_args(
+            tcx,
+            obligation.predicate.def_id,
+            trait_ref.args,
+        ),
         term: ty.into(),
     };
 
@@ -1431,7 +1437,11 @@ fn confirm_future_candidate<'cx, 'tcx>(
     debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new_from_args(
+            tcx,
+            obligation.predicate.def_id,
+            trait_ref.args,
+        ),
         term: return_ty.into(),
     };
 
@@ -1473,7 +1483,11 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
     debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item);
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new_from_args(
+            tcx,
+            obligation.predicate.def_id,
+            trait_ref.args,
+        ),
         term: yield_ty.into(),
     };
 
@@ -1523,7 +1537,11 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>(
     let item_ty = args.type_at(0);
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new_from_args(
+            tcx,
+            obligation.predicate.def_id,
+            trait_ref.args,
+        ),
         term: item_ty.into(),
     };
 
@@ -1592,7 +1610,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
     };
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, item_def_id, args),
+        projection_term: ty::AliasTerm::new_from_args(tcx, item_def_id, args),
         term,
     };
 
@@ -1753,7 +1771,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
         fn_host_effect,
     )
     .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(tcx, fn_once_output_def_id, trait_ref.args),
+        projection_term: ty::AliasTerm::new_from_args(tcx, fn_once_output_def_id, trait_ref.args),
         term: ret_type.into(),
     });
 
@@ -1937,7 +1955,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>(
     };
 
     let predicate = ty::ProjectionPredicate {
-        projection_term: ty::AliasTerm::new(
+        projection_term: ty::AliasTerm::new_from_args(
             selcx.tcx(),
             obligation.predicate.def_id,
             obligation.predicate.args,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c53939bfe60..e36a9ca8bd1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -940,7 +940,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             let ty = traits::normalize_projection_ty(
                 self,
                 param_env,
-                ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args),
+                ty::AliasTy::new_from_args(tcx, tcx.lang_items().deref_target()?, trait_ref.args),
                 cause.clone(),
                 0,
                 // We're *intentionally* throwing these away,
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index b50f6260ab3..8c5dc88184c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1162,7 +1162,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let InferOk { mut obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .sup(DefineOpaqueTypes::No, target, source_trait)
+                    .sup(DefineOpaqueTypes::Yes, target, source_trait)
                     .map_err(|_| Unimplemented)?;
 
                 // Register one obligation for 'a: 'b.
@@ -1229,7 +1229,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let InferOk { obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .eq(DefineOpaqueTypes::No, b, a)
+                    .eq(DefineOpaqueTypes::Yes, b, a)
                     .map_err(|_| Unimplemented)?;
 
                 ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
@@ -1277,7 +1277,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let InferOk { obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .eq(DefineOpaqueTypes::No, target, new_struct)
+                    .eq(DefineOpaqueTypes::Yes, target, new_struct)
                     .map_err(|_| Unimplemented)?;
                 nested.extend(obligations);
 
@@ -1310,7 +1310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let InferOk { mut obligations, .. } = self
                     .infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .eq(DefineOpaqueTypes::No, target, new_tuple)
+                    .eq(DefineOpaqueTypes::Yes, target, new_tuple)
                     .map_err(|_| Unimplemented)?;
 
                 // Add a nested `T: Unsize<U>` predicate.
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index fe047f9966f..68cc04bc8e6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2487,7 +2487,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                         trait_def_id,
                         &[normalized_ty.into()],
                     );
-                    ty::TraitRef::new(tcx, trait_def_id, err_args)
+                    ty::TraitRef::new_from_args(tcx, trait_def_id, err_args)
                 };
 
                 let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref);
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index 18b34f8d99b..491ef34430c 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -320,7 +320,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
                 if self.bound_vars.len() <= idx {
                     panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
                 }
-                bound_ty.assert_eq(self.bound_vars[idx]);
+                bound_ty.assert_eq(self.bound_vars.get(idx).unwrap());
             }
             _ => {}
         };
@@ -335,7 +335,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
                 if self.bound_vars.len() <= idx {
                     panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
                 }
-                br.assert_eq(self.bound_vars[idx]);
+                br.assert_eq(self.bound_vars.get(idx).unwrap());
             }
 
             _ => (),
@@ -435,15 +435,14 @@ impl<I: Interner, T> EarlyBinder<I, Option<T>> {
     }
 }
 
-impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
+impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
 where
     Iter::Item: TypeFoldable<I>,
 {
-    pub fn iter_instantiated(
-        self,
-        tcx: I,
-        args: &'s [I::GenericArg],
-    ) -> IterInstantiated<'s, I, Iter> {
+    pub fn iter_instantiated<A>(self, tcx: I, args: A) -> IterInstantiated<I, Iter, A>
+    where
+        A: SliceLike<Item = I::GenericArg>,
+    {
         IterInstantiated { it: self.value.into_iter(), tcx, args }
     }
 
@@ -454,15 +453,16 @@ where
     }
 }
 
-pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> {
+pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> {
     it: Iter::IntoIter,
     tcx: I,
-    args: &'s [I::GenericArg],
+    args: A,
 }
 
-impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A>
 where
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
     type Item = Iter::Item;
 
@@ -478,10 +478,11 @@ where
     }
 }
 
-impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A>
 where
     Iter::IntoIter: DoubleEndedIterator,
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
         Some(
@@ -491,10 +492,11 @@ where
     }
 }
 
-impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A>
 where
     Iter::IntoIter: ExactSizeIterator,
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
 }
 
@@ -589,8 +591,11 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
 }
 
 impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
-    pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T {
-        let mut folder = ArgFolder { tcx, args, binders_passed: 0 };
+    pub fn instantiate<A>(self, tcx: I, args: A) -> T
+    where
+        A: SliceLike<Item = I::GenericArg>,
+    {
+        let mut folder = ArgFolder { tcx, args: args.as_slice(), binders_passed: 0 };
         self.value.fold_with(&mut folder)
     }
 
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 61ae36265ec..7b114f565f2 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -283,7 +283,7 @@ pub struct CanonicalVarValues<I: Interner> {
 
 impl<I: Interner> CanonicalVarValues<I> {
     pub fn is_identity(&self) -> bool {
-        self.var_values.into_iter().enumerate().all(|(bv, arg)| match arg.kind() {
+        self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
             ty::GenericArgKind::Lifetime(r) => {
                 matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv)
             }
@@ -298,7 +298,7 @@ impl<I: Interner> CanonicalVarValues<I> {
 
     pub fn is_identity_modulo_regions(&self) -> bool {
         let mut var = ty::BoundVar::ZERO;
-        for arg in self.var_values {
+        for arg in self.var_values.iter() {
             match arg.kind() {
                 ty::GenericArgKind::Lifetime(r) => {
                     if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) {
@@ -332,7 +332,7 @@ impl<I: Interner> CanonicalVarValues<I> {
     // the identity response.
     pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> {
         CanonicalVarValues {
-            var_values: tcx.mk_args_from_iter(infos.into_iter().enumerate().map(
+            var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map(
                 |(i, info)| -> I::GenericArg {
                     match info.kind {
                         CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
@@ -371,10 +371,10 @@ impl<I: Interner> CanonicalVarValues<I> {
 
 impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> {
     type Item = I::GenericArg;
-    type IntoIter = <I::GenericArgs as IntoIterator>::IntoIter;
+    type IntoIter = <I::GenericArgs as SliceLike>::IntoIter;
 
     fn into_iter(self) -> Self::IntoIter {
-        self.var_values.into_iter()
+        self.var_values.iter()
     }
 }
 
@@ -382,6 +382,6 @@ impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
     type Output = I::GenericArg;
 
     fn index(&self, value: ty::BoundVar) -> &I::GenericArg {
-        &self.var_values[value.as_usize()]
+        &self.var_values.as_slice()[value.as_usize()]
     }
 }
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 953a438cb14..09ee12d1cc3 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -323,6 +323,12 @@ impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Vec<T> {
     }
 }
 
+impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<[T]> {
+    fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
+        Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice)
+    }
+}
+
 impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> {
     fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
         self.raw.try_fold_with(folder).map(IndexVec::from_raw)
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index be6deee011b..a4e1a97d505 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -5,7 +5,6 @@
 
 use std::fmt::Debug;
 use std::hash::Hash;
-use std::ops::Deref;
 
 use rustc_ast_ir::Mutability;
 
@@ -47,6 +46,14 @@ pub trait Ty<I: Interner<Ty = Self>>:
 
     fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self;
 
+    fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self {
+        Ty::new_alias(
+            interner,
+            ty::AliasTyKind::Projection,
+            ty::AliasTy::new_from_args(interner, def_id, args),
+        )
+    }
+
     fn new_projection(
         interner: I,
         def_id: I::DefId,
@@ -120,7 +127,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
     fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
         match self.kind() {
             ty::FnPtr(sig) => sig,
-            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, &args),
+            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
             ty::Error(_) => {
                 // ignore errors (#54954)
                 ty::Binder::dummy(ty::FnSig {
@@ -182,14 +189,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
 }
 
 pub trait Tys<I: Interner<Tys = Self>>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + IntoIterator<Item = I::Ty>
-    + Deref<Target: Deref<Target = [I::Ty]>>
-    + TypeFoldable<I>
-    + Default
+    Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default
 {
     fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
 }
@@ -354,14 +354,7 @@ pub trait Term<I: Interner<Term = Self>>:
 }
 
 pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + IntoIterator<Item = I::GenericArg>
-    + Deref<Target: Deref<Target = [I::GenericArg]>>
-    + Default
-    + Relate<I>
+    Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
 {
     fn rebase_onto(
         self,
@@ -553,12 +546,7 @@ pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
 }
 
 pub trait BoundExistentialPredicates<I: Interner>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + Relate<I>
-    + IntoIterator<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
+    Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
 {
     fn principal_def_id(self) -> Option<I::DefId>;
 
@@ -570,3 +558,82 @@ pub trait BoundExistentialPredicates<I: Interner>:
         self,
     ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
 }
+
+pub trait SliceLike: Sized + Copy {
+    type Item: Copy;
+    type IntoIter: Iterator<Item = Self::Item>;
+
+    fn iter(self) -> Self::IntoIter;
+
+    fn as_slice(&self) -> &[Self::Item];
+
+    fn get(self, idx: usize) -> Option<Self::Item> {
+        self.as_slice().get(idx).copied()
+    }
+
+    fn len(self) -> usize {
+        self.as_slice().len()
+    }
+
+    fn is_empty(self) -> bool {
+        self.len() == 0
+    }
+
+    fn contains(self, t: &Self::Item) -> bool
+    where
+        Self::Item: PartialEq,
+    {
+        self.as_slice().contains(t)
+    }
+
+    fn to_vec(self) -> Vec<Self::Item> {
+        self.as_slice().to_vec()
+    }
+
+    fn last(self) -> Option<Self::Item> {
+        self.as_slice().last().copied()
+    }
+
+    fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
+        self.as_slice().split_last()
+    }
+}
+
+impl<'a, T: Copy> SliceLike for &'a [T] {
+    type Item = T;
+    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
+
+    fn iter(self) -> Self::IntoIter {
+        self.iter().copied()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        *self
+    }
+}
+
+impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
+    type Item = T;
+    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
+
+    fn iter(self) -> Self::IntoIter {
+        self.into_iter().copied()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        *self
+    }
+}
+
+impl<'a, S: SliceLike> SliceLike for &'a S {
+    type Item = S::Item;
+    type IntoIter = S::IntoIter;
+
+    fn iter(self) -> Self::IntoIter {
+        (*self).iter()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        (*self).as_slice()
+    }
+}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 59ca95c09cd..b89ea30fc34 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -34,16 +34,11 @@ pub trait Interner:
     type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
 
     type GenericArgs: GenericArgs<Self>;
-    type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref<Target = [Self::GenericArg]>;
+    type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>;
     type GenericArg: GenericArg<Self>;
     type Term: Term<Self>;
 
-    type BoundVarKinds: Copy
-        + Debug
-        + Hash
-        + Eq
-        + Deref<Target: Deref<Target = [Self::BoundVarKind]>>
-        + Default;
+    type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike<Item = Self::BoundVarKind> + Default;
     type BoundVarKind: Copy + Debug + Hash + Eq;
 
     type PredefinedOpaques: Copy
@@ -63,7 +58,7 @@ pub trait Interner:
         + Default
         + Eq
         + TypeVisitable<Self>
-        + Deref<Target: Deref<Target = [Self::LocalDefId]>>;
+        + SliceLike<Item = Self::LocalDefId>;
     type CanonicalGoalEvaluationStepRef: Copy
         + Debug
         + Hash
@@ -74,8 +69,7 @@ pub trait Interner:
         + Debug
         + Hash
         + Eq
-        + IntoIterator<Item = ty::CanonicalVarInfo<Self>>
-        + Deref<Target: Deref<Target = [ty::CanonicalVarInfo<Self>]>>
+        + SliceLike<Item = ty::CanonicalVarInfo<Self>>
         + Default;
     fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
 
@@ -96,7 +90,7 @@ pub trait Interner:
     // Kinds of tys
     type Ty: Ty<Self>;
     type Tys: Tys<Self>;
-    type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]> + TypeVisitable<Self>;
+    type FnInputTys: Copy + Debug + Hash + Eq + SliceLike<Item = Self::Ty> + TypeVisitable<Self>;
     type ParamTy: Copy + Debug + Hash + Eq + ParamLike;
     type BoundTy: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
     type PlaceholderTy: PlaceholderLike;
@@ -138,11 +132,7 @@ pub trait Interner:
     type GenericsOf: GenericsOf<Self>;
     fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
 
-    type VariancesOf: Copy
-        + Debug
-        + Deref<Target = [ty::Variance]>
-        // FIXME: This is terrible!
-        + IntoIterator<Item: Deref<Target = ty::Variance>>;
+    type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
     fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
 
     fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
@@ -169,11 +159,7 @@ pub trait Interner:
 
     fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool;
 
-    fn check_and_mk_args(
-        self,
-        def_id: Self::DefId,
-        args: impl IntoIterator<Item: Into<Self::GenericArg>>,
-    ) -> Self::GenericArgs;
+    fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
 
     fn intern_canonical_goal_evaluation_step(
         self,
diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs
index 738350f1b34..d8ed4770e2d 100644
--- a/compiler/rustc_type_ir/src/opaque_ty.rs
+++ b/compiler/rustc_type_ir/src/opaque_ty.rs
@@ -24,13 +24,13 @@ pub struct OpaqueTypeKey<I: Interner> {
 impl<I: Interner> OpaqueTypeKey<I> {
     pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> {
         let variances = tcx.variances_of(self.def_id.into());
-        std::iter::zip(self.args, variances.into_iter()).enumerate().filter_map(|(i, (arg, v))| {
-            match (arg.kind(), *v) {
+        std::iter::zip(self.args.iter(), variances.iter()).enumerate().filter_map(
+            |(i, (arg, v))| match (arg.kind(), v) {
                 (_, ty::Invariant) => Some((i, arg)),
                 (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
                 _ => panic!("unexpected opaque type arg variance"),
-            }
-        })
+            },
+        )
     }
 
     pub fn fold_captured_lifetime_args(
@@ -41,7 +41,7 @@ impl<I: Interner> OpaqueTypeKey<I> {
         let Self { def_id, args } = self;
         let variances = tcx.variances_of(def_id.into());
         let args =
-            std::iter::zip(args, variances.into_iter()).map(|(arg, v)| match (arg.kind(), *v) {
+            std::iter::zip(args.iter(), variances.iter()).map(|(arg, v)| match (arg.kind(), v) {
                 (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
                 (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
                 _ => arg,
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 7a3376c7218..e5bcbc67f94 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -64,36 +64,45 @@ pub struct TraitRef<I: Interner> {
     pub def_id: I::DefId,
     pub args: I::GenericArgs,
     /// This field exists to prevent the creation of `TraitRef` without
-    /// calling [`TraitRef::new`].
+    /// calling [`TraitRef::new_from_args`].
     _use_trait_ref_new_instead: (),
 }
 
 impl<I: Interner> TraitRef<I> {
+    pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
+        interner.debug_assert_args_compatible(trait_def_id, args);
+        Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
+    }
+
     pub fn new(
         interner: I,
         trait_def_id: I::DefId,
         args: impl IntoIterator<Item: Into<I::GenericArg>>,
     ) -> Self {
-        let args = interner.check_and_mk_args(trait_def_id, args);
-        Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
+        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
+        Self::new_from_args(interner, trait_def_id, args)
     }
 
     pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
         let generics = interner.generics_of(trait_id);
-        TraitRef::new(interner, trait_id, args.into_iter().take(generics.count()))
+        TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
     }
 
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
     /// are the parameters defined on trait.
     pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
-        TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id))
+        TraitRef::new_from_args(
+            interner,
+            def_id,
+            I::GenericArgs::identity_for_item(interner, def_id),
+        )
     }
 
     pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
         TraitRef::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
@@ -274,7 +283,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
                     // If this is an ill-formed auto trait, then synthesize
                     // new error args for the missing generics.
                     let err_args = GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]);
-                    ty::TraitRef::new(tcx, did, err_args)
+                    ty::TraitRef::new_from_args(tcx, did, err_args)
                 };
                 self.rebind(trait_ref).upcast(tcx)
             }
@@ -311,7 +320,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
 
         ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            args: interner.mk_args(&trait_ref.args[1..]),
+            args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
         }
     }
 
@@ -323,11 +332,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
         // otherwise the escaping vars would be captured by the binder
         // debug_assert!(!self_ty.has_escaping_bound_vars());
 
-        TraitRef::new(
-            interner,
-            self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter()),
-        )
+        TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
     }
 }
 
@@ -370,7 +375,7 @@ impl<I: Interner> ExistentialProjection<I> {
     pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
         let def_id = interner.parent(self.def_id);
         let args_count = interner.generics_of(def_id).count() - 1;
-        let args = interner.mk_args(&self.args[..args_count]);
+        let args = interner.mk_args(&self.args.as_slice()[..args_count]);
         ExistentialTraitRef { def_id, args }
     }
 
@@ -382,7 +387,7 @@ impl<I: Interner> ExistentialProjection<I> {
             projection_term: AliasTerm::new(
                 interner,
                 self.def_id,
-                [self_ty.into()].into_iter().chain(self.args),
+                [self_ty.into()].iter().chain(self.args.iter()),
             ),
             term: self.term,
         }
@@ -394,7 +399,7 @@ impl<I: Interner> ExistentialProjection<I> {
 
         Self {
             def_id: projection_predicate.projection_term.def_id,
-            args: interner.mk_args(&projection_predicate.projection_term.args[1..]),
+            args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
             term: projection_predicate.term,
         }
     }
@@ -485,19 +490,24 @@ pub struct AliasTerm<I: Interner> {
     /// aka. `interner.parent(def_id)`.
     pub def_id: I::DefId,
 
-    /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new`].
+    /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`].
     #[derivative(Debug = "ignore")]
     _use_alias_term_new_instead: (),
 }
 
 impl<I: Interner> AliasTerm<I> {
+    pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTerm<I> {
+        interner.debug_assert_args_compatible(def_id, args);
+        AliasTerm { def_id, args, _use_alias_term_new_instead: () }
+    }
+
     pub fn new(
         interner: I,
         def_id: I::DefId,
         args: impl IntoIterator<Item: Into<I::GenericArg>>,
     ) -> AliasTerm<I> {
-        let args = interner.check_and_mk_args(def_id, args);
-        AliasTerm { def_id, args, _use_alias_term_new_instead: () }
+        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
+        Self::new_from_args(interner, def_id, args)
     }
 
     pub fn expect_ty(self, interner: I) -> ty::AliasTy<I> {
@@ -564,7 +574,7 @@ impl<I: Interner> AliasTerm<I> {
         AliasTerm::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs
index efe270ed608..b1d0f8d19b3 100644
--- a/compiler/rustc_type_ir/src/predicate_kind.rs
+++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -127,7 +127,6 @@ impl std::fmt::Display for AliasRelationDirection {
     }
 }
 
-// FIXME: Convert to DebugWithInfcx impl
 impl<I: Interner> fmt::Debug for ClauseKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
@@ -144,7 +143,6 @@ impl<I: Interner> fmt::Debug for ClauseKind<I> {
     }
 }
 
-// FIXME: Convert to DebugWithInfcx impl
 impl<I: Interner> fmt::Debug for PredicateKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 429bc3197d4..0439e7f857f 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -82,7 +82,7 @@ pub trait TypeRelation<I: Interner>: Sized {
 
         let tcx = self.tcx();
         let opt_variances = tcx.variances_of(item_def_id);
-        relate_args_with_variances(self, item_def_id, &opt_variances, a_arg, b_arg, true)
+        relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
     }
 
     /// Switch variance for the purpose of relating `a` and `b`.
@@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
     a_arg: I::GenericArgs,
     b_arg: I::GenericArgs,
 ) -> RelateResult<I, I::GenericArgs> {
-    relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
+    relation.tcx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| {
         relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
     }))
 }
@@ -136,7 +136,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
 pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
     relation: &mut R,
     ty_def_id: I::DefId,
-    variances: &[ty::Variance],
+    variances: I::VariancesOf,
     a_arg: I::GenericArgs,
     b_arg: I::GenericArgs,
     fetch_ty_for_diag: bool,
@@ -144,11 +144,11 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
     let tcx = relation.tcx();
 
     let mut cached_ty = None;
-    let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
-        let variance = variances[i];
+    let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| {
+        let variance = variances.get(i).unwrap();
         let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
             let ty =
-                *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg));
+                *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg));
             VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
         } else {
             VarianceDiagInfo::default()
@@ -185,7 +185,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
         }
 
         let inputs_and_output = iter::zip(a_inputs.iter(), b_inputs.iter())
-            .map(|(&a, &b)| ((a, b), false))
+            .map(|(a, b)| ((a, b), false))
             .chain(iter::once(((a.output(), b.output()), true)))
             .map(|((a, b), is_output)| {
                 if is_output {
@@ -249,7 +249,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
                 ty::Opaque => relate_args_with_variances(
                     relation,
                     a.def_id,
-                    &relation.tcx().variances_of(a.def_id),
+                    relation.tcx().variances_of(a.def_id),
                     a.args,
                     b.args,
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@@ -258,7 +258,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
                     relate_args_invariantly(relation, a.args, b.args)?
                 }
             };
-            Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args))
+            Ok(ty::AliasTy::new_from_args(relation.tcx(), a.def_id, args))
         }
     }
 }
@@ -280,7 +280,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
                 ty::AliasTermKind::OpaqueTy => relate_args_with_variances(
                     relation,
                     a.def_id,
-                    &relation.tcx().variances_of(a.def_id),
+                    relation.tcx().variances_of(a.def_id),
                     a.args,
                     b.args,
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@@ -293,7 +293,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
                     relate_args_invariantly(relation, a.args, b.args)?
                 }
             };
-            Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args))
+            Ok(ty::AliasTerm::new_from_args(relation.tcx(), a.def_id, args))
         }
     }
 }
@@ -343,7 +343,7 @@ impl<I: Interner> Relate<I> for ty::TraitRef<I> {
             }))
         } else {
             let args = relate_args_invariantly(relation, a.args, b.args)?;
-            Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
+            Ok(ty::TraitRef::new_from_args(relation.tcx(), a.def_id, args))
         }
     }
 }
@@ -525,7 +525,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
             if as_.len() == bs.len() {
                 Ok(Ty::new_tup_from_iter(
                     tcx,
-                    iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
+                    iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)),
                 )?)
             } else if !(as_.is_empty() || bs.is_empty()) {
                 Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len())))
@@ -607,8 +607,8 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
         // be stabilized.
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
             if cfg!(debug_assertions) {
-                let a_ty = tcx.type_of(au.def).instantiate(tcx, &au.args);
-                let b_ty = tcx.type_of(bu.def).instantiate(tcx, &bu.args);
+                let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args);
+                let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args);
                 assert_eq!(a_ty, b_ty);
             }
 
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 915888ab59b..4ffebef9f1f 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -352,7 +352,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
             Float(float) => write!(f, "{float:?}"),
             Adt(d, s) => {
                 write!(f, "{d:?}")?;
-                let mut s = s.into_iter();
+                let mut s = s.iter();
                 let first = s.next();
                 match first {
                     Some(first) => write!(f, "<{:?}", first)?,
@@ -388,7 +388,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
             Tuple(t) => {
                 write!(f, "(")?;
                 let mut count = 0;
-                for ty in *t {
+                for ty in t.iter() {
                     if count > 0 {
                         write!(f, ", ")?;
                     }
@@ -452,19 +452,24 @@ pub struct AliasTy<I: Interner> {
     /// aka. `interner.parent(def_id)`.
     pub def_id: I::DefId,
 
-    /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new`].
+    /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`].
     #[derivative(Debug = "ignore")]
     pub(crate) _use_alias_ty_new_instead: (),
 }
 
 impl<I: Interner> AliasTy<I> {
+    pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
+        interner.debug_assert_args_compatible(def_id, args);
+        AliasTy { def_id, args, _use_alias_ty_new_instead: () }
+    }
+
     pub fn new(
         interner: I,
         def_id: I::DefId,
         args: impl IntoIterator<Item: Into<I::GenericArg>>,
     ) -> AliasTy<I> {
-        let args = interner.check_and_mk_args(def_id, args);
-        AliasTy { def_id, args, _use_alias_ty_new_instead: () }
+        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
+        Self::new_from_args(interner, def_id, args)
     }
 
     pub fn kind(self, interner: I) -> AliasTyKind {
@@ -491,7 +496,7 @@ impl<I: Interner> AliasTy<I> {
         AliasTy::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
@@ -539,7 +544,7 @@ impl<I: Interner> AliasTy<I> {
         interner: I,
     ) -> I::GenericArgs {
         debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
-        interner.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1)))
+        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
     }
 }
 
@@ -1000,7 +1005,7 @@ impl<I: Interner> ty::Binder<I, FnSig<I>> {
     #[inline]
     #[track_caller]
     pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
-        self.map_bound(|fn_sig| fn_sig.inputs()[index])
+        self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
     }
 
     pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index 3a17a27bd03..24a7c0c67e9 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -138,7 +138,7 @@ impl<I: Interner> ClosureArgs<I> {
     /// for the closure parent, alongside additional closure-specific components.
     pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> {
         ClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.closure_kind_ty.into(),
                 parts.closure_sig_as_fn_ptr_ty.into(),
                 parts.tupled_upvars_ty.into(),
@@ -260,7 +260,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
 impl<I: Interner> CoroutineClosureArgs<I> {
     pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> {
         CoroutineClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.closure_kind_ty.into(),
                 parts.signature_parts_ty.into(),
                 parts.tupled_upvars_ty.into(),
@@ -309,10 +309,10 @@ impl<I: Interner> CoroutineClosureArgs<I> {
         let interior = self.coroutine_witness_ty();
         let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { panic!() };
         sig.map_bound(|sig| {
-            let [resume_ty, tupled_inputs_ty] = *sig.inputs() else {
+            let [resume_ty, tupled_inputs_ty] = *sig.inputs().as_slice() else {
                 panic!();
             };
-            let [yield_ty, return_ty] = **sig.output().tuple_fields() else { panic!() };
+            let [yield_ty, return_ty] = *sig.output().tuple_fields().as_slice() else { panic!() };
             CoroutineClosureSignature {
                 interior,
                 tupled_inputs_ty,
@@ -496,16 +496,16 @@ impl<I: Interner> CoroutineClosureSignature<I> {
                     tcx,
                     tupled_inputs_ty
                         .tuple_fields()
-                        .into_iter()
-                        .chain(coroutine_captures_by_ref_ty.tuple_fields()),
+                        .iter()
+                        .chain(coroutine_captures_by_ref_ty.tuple_fields().iter()),
                 )
             }
             ty::ClosureKind::FnOnce => Ty::new_tup_from_iter(
                 tcx,
                 tupled_inputs_ty
                     .tuple_fields()
-                    .into_iter()
-                    .chain(closure_tupled_upvars_ty.tuple_fields()),
+                    .iter()
+                    .chain(closure_tupled_upvars_ty.tuple_fields().iter()),
             ),
         }
     }
@@ -617,7 +617,7 @@ impl<I: Interner> CoroutineArgs<I> {
     /// for the coroutine parent, alongside additional coroutine-specific components.
     pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> {
         CoroutineArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.kind_ty.into(),
                 parts.resume_ty.into(),
                 parts.yield_ty.into(),