about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml14
-rw-r--r--compiler/rustc/Cargo.toml3
-rw-r--r--compiler/rustc_abi/Cargo.toml3
-rw-r--r--compiler/rustc_abi/src/layout.rs192
-rw-r--r--compiler/rustc_abi/src/layout/coroutine.rs320
-rw-r--r--compiler/rustc_abi/src/layout/simple.rs148
-rw-r--r--compiler/rustc_abi/src/layout/ty.rs6
-rw-r--r--compiler/rustc_abi/src/lib.rs50
-rw-r--r--compiler/rustc_arena/Cargo.toml3
-rw-r--r--compiler/rustc_arena/src/lib.rs27
-rw-r--r--compiler/rustc_ast/Cargo.toml3
-rw-r--r--compiler/rustc_ast/src/lib.rs1
-rw-r--r--compiler/rustc_ast_ir/Cargo.toml3
-rw-r--r--compiler/rustc_ast_ir/src/lib.rs1
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml3
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs1
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml3
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs1
-rw-r--r--compiler/rustc_ast_pretty/Cargo.toml3
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_attr_data_structures/Cargo.toml3
-rw-r--r--compiler/rustc_attr_data_structures/src/lib.rs45
-rw-r--r--compiler/rustc_attr_parsing/Cargo.toml4
-rw-r--r--compiler/rustc_attr_parsing/src/lib.rs45
-rw-r--r--compiler/rustc_baked_icu_data/Cargo.toml3
-rw-r--r--compiler/rustc_baked_icu_data/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/Cargo.toml3
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml7
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs6
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml3
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/Cargo.toml3
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/Cargo.toml3
-rw-r--r--compiler/rustc_data_structures/src/aligned.rs8
-rw-r--r--compiler/rustc_data_structures/src/graph/tests.rs4
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs2
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs6
-rw-r--r--compiler/rustc_data_structures/src/sharded.rs4
-rw-r--r--compiler/rustc_data_structures/src/sync.rs2
-rw-r--r--compiler/rustc_data_structures/src/sync/parallel.rs2
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/tests.rs2
-rw-r--r--compiler/rustc_driver/Cargo.toml3
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml3
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs1
-rw-r--r--compiler/rustc_error_codes/Cargo.toml3
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_error_messages/Cargo.toml3
-rw-r--r--compiler/rustc_error_messages/src/lib.rs1
-rw-r--r--compiler/rustc_errors/Cargo.toml3
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_expand/Cargo.toml3
-rw-r--r--compiler/rustc_expand/src/lib.rs1
-rw-r--r--compiler/rustc_feature/Cargo.toml3
-rw-r--r--compiler/rustc_feature/src/lib.rs1
-rw-r--r--compiler/rustc_fluent_macro/Cargo.toml3
-rw-r--r--compiler/rustc_fluent_macro/src/lib.rs1
-rw-r--r--compiler/rustc_fs_util/Cargo.toml3
-rw-r--r--compiler/rustc_graphviz/Cargo.toml3
-rw-r--r--compiler/rustc_graphviz/src/lib.rs1
-rw-r--r--compiler/rustc_hashes/Cargo.toml3
-rw-r--r--compiler/rustc_hir/Cargo.toml3
-rw-r--r--compiler/rustc_hir/src/def.rs4
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml3
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_hir_pretty/Cargo.toml5
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs3
-rw-r--r--compiler/rustc_hir_typeck/Cargo.toml3
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs68
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_incremental/Cargo.toml3
-rw-r--r--compiler/rustc_incremental/src/lib.rs1
-rw-r--r--compiler/rustc_incremental/src/persist/file_format.rs2
-rw-r--r--compiler/rustc_index/Cargo.toml3
-rw-r--r--compiler/rustc_index/src/bit_set.rs6
-rw-r--r--compiler/rustc_index/src/lib.rs1
-rw-r--r--compiler/rustc_index/src/vec/tests.rs2
-rw-r--r--compiler/rustc_index_macros/Cargo.toml3
-rw-r--r--compiler/rustc_index_macros/src/newtype.rs2
-rw-r--r--compiler/rustc_infer/Cargo.toml3
-rw-r--r--compiler/rustc_infer/src/lib.rs1
-rw-r--r--compiler/rustc_interface/Cargo.toml3
-rw-r--r--compiler/rustc_interface/src/lib.rs1
-rw-r--r--compiler/rustc_lexer/Cargo.toml3
-rw-r--r--compiler/rustc_lexer/src/lib.rs1
-rw-r--r--compiler/rustc_lint/Cargo.toml3
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint_defs/Cargo.toml3
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs39
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_llvm/Cargo.toml3
-rw-r--r--compiler/rustc_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_log/Cargo.toml3
-rw-r--r--compiler/rustc_macros/Cargo.toml3
-rw-r--r--compiler/rustc_macros/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/Cargo.toml3
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_middle/Cargo.toml6
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_middle/src/query/erase.rs16
-rw-r--r--compiler/rustc_middle/src/query/mod.rs8
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs4
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs7
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs47
-rw-r--r--compiler/rustc_middle/src/ty/list.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs60
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs8
-rw-r--r--compiler/rustc_mir_build/Cargo.toml3
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_dataflow/Cargo.toml3
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs1
-rw-r--r--compiler/rustc_mir_transform/Cargo.toml3
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--compiler/rustc_monomorphize/Cargo.toml3
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs1
-rw-r--r--compiler/rustc_next_trait_solver/Cargo.toml3
-rw-r--r--compiler/rustc_next_trait_solver/src/lib.rs1
-rw-r--r--compiler/rustc_parse/Cargo.toml2
-rw-r--r--compiler/rustc_parse/src/lib.rs1
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs2
-rw-r--r--compiler/rustc_parse_format/Cargo.toml3
-rw-r--r--compiler/rustc_parse_format/src/lib.rs1
-rw-r--r--compiler/rustc_passes/Cargo.toml3
-rw-r--r--compiler/rustc_passes/src/input_stats.rs4
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_passes/src/liveness/rwu_table.rs2
-rw-r--r--compiler/rustc_pattern_analysis/Cargo.toml3
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_pattern_analysis/tests/common/mod.rs14
-rw-r--r--compiler/rustc_privacy/Cargo.toml3
-rw-r--r--compiler/rustc_privacy/src/lib.rs1
-rw-r--r--compiler/rustc_query_impl/Cargo.toml3
-rw-r--r--compiler/rustc_query_impl/src/lib.rs1
-rw-r--r--compiler/rustc_query_system/Cargo.toml3
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs11
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/Cargo.toml3
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs1
-rw-r--r--compiler/rustc_sanitizers/Cargo.toml3
-rw-r--r--compiler/rustc_sanitizers/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/Cargo.toml3
-rw-r--r--compiler/rustc_serialize/src/leb128.rs2
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_session/Cargo.toml3
-rw-r--r--compiler/rustc_session/src/filesearch.rs2
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_smir/Cargo.toml3
-rw-r--r--compiler/rustc_smir/src/lib.rs1
-rw-r--r--compiler/rustc_span/Cargo.toml3
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml3
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs1
-rw-r--r--compiler/rustc_target/Cargo.toml3
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/Cargo.toml3
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs7
-rw-r--r--compiler/rustc_traits/Cargo.toml3
-rw-r--r--compiler/rustc_traits/src/lib.rs1
-rw-r--r--compiler/rustc_transmute/Cargo.toml3
-rw-r--r--compiler/rustc_transmute/src/lib.rs1
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml3
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs587
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs1
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs58
-rw-r--r--compiler/rustc_type_ir/Cargo.toml4
-rw-r--r--compiler/rustc_type_ir/src/lib.rs1
-rw-r--r--compiler/rustc_type_ir_macros/Cargo.toml3
-rw-r--r--compiler/stable_mir/Cargo.toml3
-rw-r--r--compiler/stable_mir/src/mir/alloc.rs4
-rw-r--r--library/alloc/src/string.rs17
-rw-r--r--library/alloc/src/vec/mod.rs14
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs13
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs25
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs13
-rw-r--r--src/bootstrap/src/core/builder/mod.rs18
-rw-r--r--src/bootstrap/src/core/builder/tests.rs34
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs135
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs3
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/triagebot.rs93
-rw-r--r--tests/crashes/136138.rs7
-rw-r--r--tests/crashes/136175-2.rs13
-rw-r--r--tests/crashes/136175.rs13
-rw-r--r--tests/crashes/136188.rs9
-rw-r--r--tests/crashes/136286.rs7
-rw-r--r--tests/crashes/136379.rs11
-rw-r--r--tests/crashes/136381.rs18
-rw-r--r--tests/crashes/136416.rs6
-rw-r--r--tests/crashes/136442.rs9
-rw-r--r--tests/crashes/136661.rs25
-rw-r--r--tests/crashes/136666.rs36
-rw-r--r--tests/crashes/136678.rs18
-rw-r--r--tests/crashes/136766.rs6
-rw-r--r--tests/crashes/136859.rs27
-rw-r--r--tests/crashes/136894.rs8
-rw-r--r--tests/crashes/137049.rs29
-rw-r--r--tests/crashes/137084.rs6
-rw-r--r--tests/crashes/137187.rs9
-rw-r--r--tests/crashes/137188.rs6
-rw-r--r--tests/crashes/137190-1.rs10
-rw-r--r--tests/crashes/137190-2.rs18
-rw-r--r--tests/crashes/137190-3.rs10
-rw-r--r--tests/crashes/137260.rs11
-rw-r--r--tests/crashes/137287.rs29
-rw-r--r--tests/crashes/137467-1.rs17
-rw-r--r--tests/crashes/137467-2.rs18
-rw-r--r--tests/crashes/137467-3.rs8
-rw-r--r--tests/crashes/137468.rs16
-rw-r--r--tests/crashes/137514.rs9
-rw-r--r--tests/crashes/137580.rs4
-rw-r--r--tests/crashes/137582.rs16
-rw-r--r--tests/crashes/137706.rs7
-rw-r--r--tests/crashes/137751.rs6
-rw-r--r--tests/crashes/137813.rs18
-rw-r--r--tests/crashes/137865.rs5
-rw-r--r--tests/crashes/137874.rs4
-rw-r--r--tests/crashes/137888.rs11
-rw-r--r--tests/crashes/137895.rs6
-rw-r--r--tests/crashes/137916.rs13
-rw-r--r--tests/crashes/138008.rs8
-rw-r--r--tests/crashes/138009.rs6
-rw-r--r--tests/crashes/138048.rs8
-rw-r--r--tests/crashes/138088.rs5
-rw-r--r--tests/crashes/138089.rs13
-rw-r--r--tests/crashes/138131.rs12
-rw-r--r--tests/crashes/138132.rs10
-rw-r--r--tests/crashes/138166.rs8
-rw-r--r--tests/ui-fulldeps/hash-stable-is-unstable.rs1
-rw-r--r--tests/ui-fulldeps/hash-stable-is-unstable.stderr10
-rw-r--r--tests/ui-fulldeps/pathless-extern-unstable.rs1
-rw-r--r--tests/ui-fulldeps/pathless-extern-unstable.stderr2
-rw-r--r--tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr3
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs36
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr48
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs36
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr43
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs41
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr140
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap.rs33
-rw-r--r--tests/ui/consts/issue-94675.rs2
-rw-r--r--tests/ui/layout/post-mono-layout-cycle-2.rs2
-rw-r--r--tests/ui/layout/post-mono-layout-cycle-2.stderr6
-rw-r--r--tests/ui/lint/lint-incoherent-auto-trait-objects.rs3
-rw-r--r--tests/ui/lint/lint-incoherent-auto-trait-objects.stderr65
-rw-r--r--tests/ui/traits/issue-33140-hack-boundaries.rs2
-rw-r--r--tests/ui/traits/issue-33140-hack-boundaries.stderr22
-rw-r--r--tests/ui/traits/object/issue-33140-traitobject-crate.rs12
-rw-r--r--tests/ui/traits/object/issue-33140-traitobject-crate.stderr86
-rw-r--r--triagebot.toml16
273 files changed, 2399 insertions, 1359 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5886b96b728..ecd26d6199c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3297,6 +3297,7 @@ dependencies = [
  "rustc_hir",
  "rustc_lexer",
  "rustc_macros",
+ "rustc_middle",
  "rustc_serialize",
  "rustc_session",
  "rustc_span",
@@ -3752,7 +3753,7 @@ dependencies = [
  "rustc_abi",
  "rustc_ast",
  "rustc_ast_pretty",
- "rustc_attr_parsing",
+ "rustc_attr_data_structures",
  "rustc_hir",
  "rustc_span",
 ]
@@ -4020,7 +4021,8 @@ dependencies = [
  "rustc_apfloat",
  "rustc_arena",
  "rustc_ast",
- "rustc_attr_parsing",
+ "rustc_ast_ir",
+ "rustc_attr_data_structures",
  "rustc_data_structures",
  "rustc_error_messages",
  "rustc_errors",
@@ -5271,6 +5273,7 @@ dependencies = [
  "serde",
  "similar",
  "termcolor",
+ "toml 0.7.8",
  "walkdir",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index 20a43aaaeeb..e2d032e0806 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -63,6 +63,20 @@ exclude = [
   "src/tools/x",
 ]
 
+# These lints are applied to many crates in the workspace. In practice, this is
+# all crates under `compiler/`.
+#
+# NOTE: rustc-specific lints (e.g. `rustc::internal`) aren't supported by
+# Cargo. (Support for them is possibly blocked by #44690 (attributes for
+# tools).) Those lints are instead specified for `compiler/` crates in
+# `src/bootstrap/src/core/builder/cargo.rs`.
+[workspace.lints.rust]
+# FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all of the
+# individual lints are satisfied.
+keyword_idents_2024 = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+
 [profile.release.package.rustc-rayon-core]
 # The rustc fork of Rayon has deadlock detection code which intermittently
 # causes overflows in the CI (see https://github.com/rust-lang/rust/issues/90227)
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index f4caa3ef769..7af0b34d2da 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -32,3 +32,6 @@ llvm = ['rustc_driver_impl/llvm']
 max_level_info = ['rustc_driver_impl/max_level_info']
 rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml
index 86dc84e2016..4713b3474bd 100644
--- a/compiler/rustc_abi/Cargo.toml
+++ b/compiler/rustc_abi/Cargo.toml
@@ -31,3 +31,6 @@ nightly = [
 ]
 randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"]
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index d3ae6a29f10..7bffeaf4cc9 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -4,6 +4,7 @@ use std::{cmp, iter};
 
 use rustc_hashes::Hash64;
 use rustc_index::Idx;
+use rustc_index::bit_set::BitMatrix;
 use tracing::debug;
 
 use crate::{
@@ -12,6 +13,9 @@ use crate::{
     Variants, WrappingRange,
 };
 
+mod coroutine;
+mod simple;
+
 #[cfg(feature = "nightly")]
 mod ty;
 
@@ -60,17 +64,28 @@ pub enum LayoutCalculatorError<F> {
 
     /// The fields or variants have irreconcilable reprs
     ReprConflict,
+
+    /// The length of an SIMD type is zero
+    ZeroLengthSimdType,
+
+    /// The length of an SIMD type exceeds the maximum number of lanes
+    OversizedSimdType { max_lanes: u64 },
+
+    /// An element type of an SIMD type isn't a primitive
+    NonPrimitiveSimdType(F),
 }
 
 impl<F> LayoutCalculatorError<F> {
     pub fn without_payload(&self) -> LayoutCalculatorError<()> {
-        match self {
-            LayoutCalculatorError::UnexpectedUnsized(_) => {
-                LayoutCalculatorError::UnexpectedUnsized(())
-            }
-            LayoutCalculatorError::SizeOverflow => LayoutCalculatorError::SizeOverflow,
-            LayoutCalculatorError::EmptyUnion => LayoutCalculatorError::EmptyUnion,
-            LayoutCalculatorError::ReprConflict => LayoutCalculatorError::ReprConflict,
+        use LayoutCalculatorError::*;
+        match *self {
+            UnexpectedUnsized(_) => UnexpectedUnsized(()),
+            SizeOverflow => SizeOverflow,
+            EmptyUnion => EmptyUnion,
+            ReprConflict => ReprConflict,
+            ZeroLengthSimdType => ZeroLengthSimdType,
+            OversizedSimdType { max_lanes } => OversizedSimdType { max_lanes },
+            NonPrimitiveSimdType(_) => NonPrimitiveSimdType(()),
         }
     }
 
@@ -78,13 +93,15 @@ impl<F> LayoutCalculatorError<F> {
     ///
     /// Intended for use by rust-analyzer, as neither it nor `rustc_abi` depend on fluent infra.
     pub fn fallback_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        use LayoutCalculatorError::*;
         f.write_str(match self {
-            LayoutCalculatorError::UnexpectedUnsized(_) => {
-                "an unsized type was found where a sized type was expected"
+            UnexpectedUnsized(_) => "an unsized type was found where a sized type was expected",
+            SizeOverflow => "size overflow",
+            EmptyUnion => "type is a union with no fields",
+            ReprConflict => "type has an invalid repr",
+            ZeroLengthSimdType | OversizedSimdType { .. } | NonPrimitiveSimdType(_) => {
+                "invalid simd type definition"
             }
-            LayoutCalculatorError::SizeOverflow => "size overflow",
-            LayoutCalculatorError::EmptyUnion => "type is a union with no fields",
-            LayoutCalculatorError::ReprConflict => "type has an invalid repr",
         })
     }
 }
@@ -102,41 +119,115 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         Self { cx }
     }
 
-    pub fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
+    pub fn array_like<FieldIdx: Idx, VariantIdx: Idx, F>(
         &self,
-        a: Scalar,
-        b: Scalar,
-    ) -> LayoutData<FieldIdx, VariantIdx> {
-        let dl = self.cx.data_layout();
-        let b_align = b.align(dl);
-        let align = a.align(dl).max(b_align).max(dl.aggregate_align);
-        let b_offset = a.size(dl).align_to(b_align.abi);
-        let size = (b_offset + b.size(dl)).align_to(align.abi);
+        element: &LayoutData<FieldIdx, VariantIdx>,
+        count_if_sized: Option<u64>, // None for slices
+    ) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
+        let count = count_if_sized.unwrap_or(0);
+        let size =
+            element.size.checked_mul(count, &self.cx).ok_or(LayoutCalculatorError::SizeOverflow)?;
 
-        // HACK(nox): We iter on `b` and then `a` because `max_by_key`
-        // returns the last maximum.
-        let largest_niche = Niche::from_scalar(dl, b_offset, b)
-            .into_iter()
-            .chain(Niche::from_scalar(dl, Size::ZERO, a))
-            .max_by_key(|niche| niche.available(dl));
+        Ok(LayoutData {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Array { stride: element.size, count },
+            backend_repr: BackendRepr::Memory { sized: count_if_sized.is_some() },
+            largest_niche: element.largest_niche.filter(|_| count != 0),
+            uninhabited: element.uninhabited && count != 0,
+            align: element.align,
+            size,
+            max_repr_align: None,
+            unadjusted_abi_align: element.align.abi,
+            randomization_seed: element.randomization_seed.wrapping_add(Hash64::new(count)),
+        })
+    }
 
-        let combined_seed = a.size(&self.cx).bytes().wrapping_add(b.size(&self.cx).bytes());
+    pub fn simd_type<
+        FieldIdx: Idx,
+        VariantIdx: Idx,
+        F: AsRef<LayoutData<FieldIdx, VariantIdx>> + fmt::Debug,
+    >(
+        &self,
+        element: F,
+        count: u64,
+        repr_packed: bool,
+    ) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
+        let elt = element.as_ref();
+        if count == 0 {
+            return Err(LayoutCalculatorError::ZeroLengthSimdType);
+        } else if count > crate::MAX_SIMD_LANES {
+            return Err(LayoutCalculatorError::OversizedSimdType {
+                max_lanes: crate::MAX_SIMD_LANES,
+            });
+        }
 
-        LayoutData {
+        let BackendRepr::Scalar(e_repr) = elt.backend_repr else {
+            return Err(LayoutCalculatorError::NonPrimitiveSimdType(element));
+        };
+
+        // Compute the size and alignment of the vector
+        let dl = self.cx.data_layout();
+        let size =
+            elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?;
+        let (repr, align) = if repr_packed && !count.is_power_of_two() {
+            // Non-power-of-two vectors have padding up to the next power-of-two.
+            // If we're a packed repr, remove the padding while keeping the alignment as close
+            // to a vector as possible.
+            (
+                BackendRepr::Memory { sized: true },
+                AbiAndPrefAlign {
+                    abi: Align::max_aligned_factor(size),
+                    pref: dl.llvmlike_vector_align(size).pref,
+                },
+            )
+        } else {
+            (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size))
+        };
+        let size = size.align_to(align.abi);
+
+        Ok(LayoutData {
             variants: Variants::Single { index: VariantIdx::new(0) },
             fields: FieldsShape::Arbitrary {
-                offsets: [Size::ZERO, b_offset].into(),
-                memory_index: [0, 1].into(),
+                offsets: [Size::ZERO].into(),
+                memory_index: [0].into(),
             },
-            backend_repr: BackendRepr::ScalarPair(a, b),
-            largest_niche,
+            backend_repr: repr,
+            largest_niche: elt.largest_niche,
             uninhabited: false,
-            align,
             size,
+            align,
             max_repr_align: None,
-            unadjusted_abi_align: align.abi,
-            randomization_seed: Hash64::new(combined_seed),
-        }
+            unadjusted_abi_align: elt.align.abi,
+            randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)),
+        })
+    }
+
+    /// Compute the layout for a coroutine.
+    ///
+    /// This uses dedicated code instead of [`Self::layout_of_struct_or_enum`], as coroutine
+    /// fields may be shared between multiple variants (see the [`coroutine`] module for details).
+    pub fn coroutine<
+        'a,
+        F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
+        VariantIdx: Idx,
+        FieldIdx: Idx,
+        LocalIdx: Idx,
+    >(
+        &self,
+        local_layouts: &IndexSlice<LocalIdx, F>,
+        prefix_layouts: IndexVec<FieldIdx, F>,
+        variant_fields: &IndexSlice<VariantIdx, IndexVec<FieldIdx, LocalIdx>>,
+        storage_conflicts: &BitMatrix<LocalIdx, LocalIdx>,
+        tag_to_layout: impl Fn(Scalar) -> F,
+    ) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
+        coroutine::layout(
+            self,
+            local_layouts,
+            prefix_layouts,
+            variant_fields,
+            storage_conflicts,
+            tag_to_layout,
+        )
     }
 
     pub fn univariant<
@@ -214,25 +305,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
         layout
     }
 
-    pub fn layout_of_never_type<FieldIdx: Idx, VariantIdx: Idx>(
-        &self,
-    ) -> LayoutData<FieldIdx, VariantIdx> {
-        let dl = self.cx.data_layout();
-        // This is also used for uninhabited enums, so we use `Variants::Empty`.
-        LayoutData {
-            variants: Variants::Empty,
-            fields: FieldsShape::Primitive,
-            backend_repr: BackendRepr::Memory { sized: true },
-            largest_niche: None,
-            uninhabited: true,
-            align: dl.i8_align,
-            size: Size::ZERO,
-            max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
-            randomization_seed: Hash64::ZERO,
-        }
-    }
-
     pub fn layout_of_struct_or_enum<
         'a,
         FieldIdx: Idx,
@@ -260,7 +332,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             Some(present_first) => present_first,
             // Uninhabited because it has no variants, or only absent ones.
             None if is_enum => {
-                return Ok(self.layout_of_never_type());
+                return Ok(LayoutData::never_type(&self.cx));
             }
             // If it's a struct, still compute a layout so that we can still compute the
             // field offsets.
@@ -949,7 +1021,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                     // Common prim might be uninit.
                     Scalar::Union { value: prim }
                 };
-                let pair = self.scalar_pair::<FieldIdx, VariantIdx>(tag, prim_scalar);
+                let pair =
+                    LayoutData::<FieldIdx, VariantIdx>::scalar_pair(&self.cx, tag, prim_scalar);
                 let pair_offsets = match pair.fields {
                     FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                         assert_eq!(memory_index.raw, [0, 1]);
@@ -1341,7 +1414,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
                             } else {
                                 ((j, b), (i, a))
                             };
-                            let pair = self.scalar_pair::<FieldIdx, VariantIdx>(a, b);
+                            let pair =
+                                LayoutData::<FieldIdx, VariantIdx>::scalar_pair(&self.cx, a, b);
                             let pair_offsets = match pair.fields {
                                 FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
                                     assert_eq!(memory_index.raw, [0, 1]);
diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs
new file mode 100644
index 00000000000..27e704d538c
--- /dev/null
+++ b/compiler/rustc_abi/src/layout/coroutine.rs
@@ -0,0 +1,320 @@
+//! Coroutine layout logic.
+//!
+//! When laying out coroutines, we divide our saved local fields into two
+//! categories: overlap-eligible and overlap-ineligible.
+//!
+//! Those fields which are ineligible for overlap go in a "prefix" at the
+//! beginning of the layout, and always have space reserved for them.
+//!
+//! Overlap-eligible fields are only assigned to one variant, so we lay
+//! those fields out for each variant and put them right after the
+//! prefix.
+//!
+//! Finally, in the layout details, we point to the fields from the
+//! variants they are assigned to. It is possible for some fields to be
+//! included in multiple variants. No field ever "moves around" in the
+//! layout; its offset is always the same.
+//!
+//! Also included in the layout are the upvars and the discriminant.
+//! These are included as fields on the "outer" layout; they are not part
+//! of any variant.
+
+use std::iter;
+
+use rustc_index::bit_set::{BitMatrix, DenseBitSet};
+use rustc_index::{Idx, IndexSlice, IndexVec};
+use tracing::{debug, trace};
+
+use crate::{
+    BackendRepr, FieldsShape, HasDataLayout, Integer, LayoutData, Primitive, ReprOptions, Scalar,
+    StructKind, TagEncoding, Variants, WrappingRange,
+};
+
+/// Overlap eligibility and variant assignment for each CoroutineSavedLocal.
+#[derive(Clone, Debug, PartialEq)]
+enum SavedLocalEligibility<VariantIdx, FieldIdx> {
+    Unassigned,
+    Assigned(VariantIdx),
+    Ineligible(Option<FieldIdx>),
+}
+
+/// Compute the eligibility and assignment of each local.
+fn coroutine_saved_local_eligibility<VariantIdx: Idx, FieldIdx: Idx, LocalIdx: Idx>(
+    nb_locals: usize,
+    variant_fields: &IndexSlice<VariantIdx, IndexVec<FieldIdx, LocalIdx>>,
+    storage_conflicts: &BitMatrix<LocalIdx, LocalIdx>,
+) -> (DenseBitSet<LocalIdx>, IndexVec<LocalIdx, SavedLocalEligibility<VariantIdx, FieldIdx>>) {
+    use SavedLocalEligibility::*;
+
+    let mut assignments: IndexVec<LocalIdx, _> = IndexVec::from_elem_n(Unassigned, nb_locals);
+
+    // The saved locals not eligible for overlap. These will get
+    // "promoted" to the prefix of our coroutine.
+    let mut ineligible_locals = DenseBitSet::new_empty(nb_locals);
+
+    // Figure out which of our saved locals are fields in only
+    // one variant. The rest are deemed ineligible for overlap.
+    for (variant_index, fields) in variant_fields.iter_enumerated() {
+        for local in fields {
+            match assignments[*local] {
+                Unassigned => {
+                    assignments[*local] = Assigned(variant_index);
+                }
+                Assigned(idx) => {
+                    // We've already seen this local at another suspension
+                    // point, so it is no longer a candidate.
+                    trace!(
+                        "removing local {:?} in >1 variant ({:?}, {:?})",
+                        local, variant_index, idx
+                    );
+                    ineligible_locals.insert(*local);
+                    assignments[*local] = Ineligible(None);
+                }
+                Ineligible(_) => {}
+            }
+        }
+    }
+
+    // Next, check every pair of eligible locals to see if they
+    // conflict.
+    for local_a in storage_conflicts.rows() {
+        let conflicts_a = storage_conflicts.count(local_a);
+        if ineligible_locals.contains(local_a) {
+            continue;
+        }
+
+        for local_b in storage_conflicts.iter(local_a) {
+            // local_a and local_b are storage live at the same time, therefore they
+            // cannot overlap in the coroutine layout. The only way to guarantee
+            // this is if they are in the same variant, or one is ineligible
+            // (which means it is stored in every variant).
+            if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] {
+                continue;
+            }
+
+            // If they conflict, we will choose one to make ineligible.
+            // This is not always optimal; it's just a greedy heuristic that
+            // seems to produce good results most of the time.
+            let conflicts_b = storage_conflicts.count(local_b);
+            let (remove, other) =
+                if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) };
+            ineligible_locals.insert(remove);
+            assignments[remove] = Ineligible(None);
+            trace!("removing local {:?} due to conflict with {:?}", remove, other);
+        }
+    }
+
+    // Count the number of variants in use. If only one of them, then it is
+    // impossible to overlap any locals in our layout. In this case it's
+    // always better to make the remaining locals ineligible, so we can
+    // lay them out with the other locals in the prefix and eliminate
+    // unnecessary padding bytes.
+    {
+        let mut used_variants = DenseBitSet::new_empty(variant_fields.len());
+        for assignment in &assignments {
+            if let Assigned(idx) = assignment {
+                used_variants.insert(*idx);
+            }
+        }
+        if used_variants.count() < 2 {
+            for assignment in assignments.iter_mut() {
+                *assignment = Ineligible(None);
+            }
+            ineligible_locals.insert_all();
+        }
+    }
+
+    // Write down the order of our locals that will be promoted to the prefix.
+    {
+        for (idx, local) in ineligible_locals.iter().enumerate() {
+            assignments[local] = Ineligible(Some(FieldIdx::new(idx)));
+        }
+    }
+    debug!("coroutine saved local assignments: {:?}", assignments);
+
+    (ineligible_locals, assignments)
+}
+
+/// Compute the full coroutine layout.
+pub(super) fn layout<
+    'a,
+    F: core::ops::Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + core::fmt::Debug + Copy,
+    VariantIdx: Idx,
+    FieldIdx: Idx,
+    LocalIdx: Idx,
+>(
+    calc: &super::LayoutCalculator<impl HasDataLayout>,
+    local_layouts: &IndexSlice<LocalIdx, F>,
+    mut prefix_layouts: IndexVec<FieldIdx, F>,
+    variant_fields: &IndexSlice<VariantIdx, IndexVec<FieldIdx, LocalIdx>>,
+    storage_conflicts: &BitMatrix<LocalIdx, LocalIdx>,
+    tag_to_layout: impl Fn(Scalar) -> F,
+) -> super::LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
+    use SavedLocalEligibility::*;
+
+    let (ineligible_locals, assignments) =
+        coroutine_saved_local_eligibility(local_layouts.len(), variant_fields, storage_conflicts);
+
+    // Build a prefix layout, including "promoting" all ineligible
+    // locals as part of the prefix. We compute the layout of all of
+    // these fields at once to get optimal packing.
+    let tag_index = prefix_layouts.len();
+
+    // `variant_fields` already accounts for the reserved variants, so no need to add them.
+    let max_discr = (variant_fields.len() - 1) as u128;
+    let discr_int = Integer::fit_unsigned(max_discr);
+    let tag = Scalar::Initialized {
+        value: Primitive::Int(discr_int, /* signed = */ false),
+        valid_range: WrappingRange { start: 0, end: max_discr },
+    };
+
+    let promoted_layouts = ineligible_locals.iter().map(|local| local_layouts[local]);
+    prefix_layouts.push(tag_to_layout(tag));
+    prefix_layouts.extend(promoted_layouts);
+    let prefix =
+        calc.univariant(&prefix_layouts, &ReprOptions::default(), StructKind::AlwaysSized)?;
+
+    let (prefix_size, prefix_align) = (prefix.size, prefix.align);
+
+    // Split the prefix layout into the "outer" fields (upvars and
+    // discriminant) and the "promoted" fields. Promoted fields will
+    // get included in each variant that requested them in
+    // CoroutineLayout.
+    debug!("prefix = {:#?}", prefix);
+    let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
+        FieldsShape::Arbitrary { mut offsets, memory_index } => {
+            let mut inverse_memory_index = memory_index.invert_bijective_mapping();
+
+            // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
+            // "outer" and "promoted" fields respectively.
+            let b_start = FieldIdx::new(tag_index + 1);
+            let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.index()));
+            let offsets_a = offsets;
+
+            // Disentangle the "a" and "b" components of `inverse_memory_index`
+            // by preserving the order but keeping only one disjoint "half" each.
+            // FIXME(eddyb) build a better abstraction for permutations, if possible.
+            let inverse_memory_index_b: IndexVec<u32, FieldIdx> = inverse_memory_index
+                .iter()
+                .filter_map(|&i| i.index().checked_sub(b_start.index()).map(FieldIdx::new))
+                .collect();
+            inverse_memory_index.raw.retain(|&i| i.index() < b_start.index());
+            let inverse_memory_index_a = inverse_memory_index;
+
+            // Since `inverse_memory_index_{a,b}` each only refer to their
+            // respective fields, they can be safely inverted
+            let memory_index_a = inverse_memory_index_a.invert_bijective_mapping();
+            let memory_index_b = inverse_memory_index_b.invert_bijective_mapping();
+
+            let outer_fields =
+                FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
+            (outer_fields, offsets_b, memory_index_b)
+        }
+        _ => unreachable!(),
+    };
+
+    let mut size = prefix.size;
+    let mut align = prefix.align;
+    let variants = variant_fields
+        .iter_enumerated()
+        .map(|(index, variant_fields)| {
+            // Only include overlap-eligible fields when we compute our variant layout.
+            let variant_only_tys = variant_fields
+                .iter()
+                .filter(|local| match assignments[**local] {
+                    Unassigned => unreachable!(),
+                    Assigned(v) if v == index => true,
+                    Assigned(_) => unreachable!("assignment does not match variant"),
+                    Ineligible(_) => false,
+                })
+                .map(|local| local_layouts[*local]);
+
+            let mut variant = calc.univariant(
+                &variant_only_tys.collect::<IndexVec<_, _>>(),
+                &ReprOptions::default(),
+                StructKind::Prefixed(prefix_size, prefix_align.abi),
+            )?;
+            variant.variants = Variants::Single { index };
+
+            let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
+                unreachable!();
+            };
+
+            // Now, stitch the promoted and variant-only fields back together in
+            // the order they are mentioned by our CoroutineLayout.
+            // Because we only use some subset (that can differ between variants)
+            // of the promoted fields, we can't just pick those elements of the
+            // `promoted_memory_index` (as we'd end up with gaps).
+            // So instead, we build an "inverse memory_index", as if all of the
+            // promoted fields were being used, but leave the elements not in the
+            // subset as `invalid_field_idx`, which we can filter out later to
+            // obtain a valid (bijective) mapping.
+            let invalid_field_idx = promoted_memory_index.len() + memory_index.len();
+            let mut combined_inverse_memory_index =
+                IndexVec::from_elem_n(FieldIdx::new(invalid_field_idx), invalid_field_idx);
+
+            let mut offsets_and_memory_index = iter::zip(offsets, memory_index);
+            let combined_offsets = variant_fields
+                .iter_enumerated()
+                .map(|(i, local)| {
+                    let (offset, memory_index) = match assignments[*local] {
+                        Unassigned => unreachable!(),
+                        Assigned(_) => {
+                            let (offset, memory_index) = offsets_and_memory_index.next().unwrap();
+                            (offset, promoted_memory_index.len() as u32 + memory_index)
+                        }
+                        Ineligible(field_idx) => {
+                            let field_idx = field_idx.unwrap();
+                            (promoted_offsets[field_idx], promoted_memory_index[field_idx])
+                        }
+                    };
+                    combined_inverse_memory_index[memory_index] = i;
+                    offset
+                })
+                .collect();
+
+            // Remove the unused slots and invert the mapping to obtain the
+            // combined `memory_index` (also see previous comment).
+            combined_inverse_memory_index.raw.retain(|&i| i.index() != invalid_field_idx);
+            let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping();
+
+            variant.fields = FieldsShape::Arbitrary {
+                offsets: combined_offsets,
+                memory_index: combined_memory_index,
+            };
+
+            size = size.max(variant.size);
+            align = align.max(variant.align);
+            Ok(variant)
+        })
+        .collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
+
+    size = size.align_to(align.abi);
+
+    let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited());
+    let abi = BackendRepr::Memory { sized: true };
+
+    Ok(LayoutData {
+        variants: Variants::Multiple {
+            tag,
+            tag_encoding: TagEncoding::Direct,
+            tag_field: tag_index,
+            variants,
+        },
+        fields: outer_fields,
+        backend_repr: abi,
+        // Suppress niches inside coroutines. If the niche is inside a field that is aliased (due to
+        // self-referentiality), getting the discriminant can cause aliasing violations.
+        // `UnsafeCell` blocks niches for the same reason, but we don't yet have `UnsafePinned` that
+        // would do the same for us here.
+        // See <https://github.com/rust-lang/rust/issues/63818>, <https://github.com/rust-lang/miri/issues/3780>.
+        // FIXME: Remove when <https://github.com/rust-lang/rust/issues/125735> is implemented and aliased coroutine fields are wrapped in `UnsafePinned`.
+        largest_niche: None,
+        uninhabited,
+        size,
+        align,
+        max_repr_align: None,
+        unadjusted_abi_align: align.abi,
+        randomization_seed: Default::default(),
+    })
+}
diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs
new file mode 100644
index 00000000000..0d0706defc2
--- /dev/null
+++ b/compiler/rustc_abi/src/layout/simple.rs
@@ -0,0 +1,148 @@
+use std::num::NonZero;
+
+use rustc_hashes::Hash64;
+use rustc_index::{Idx, IndexVec};
+
+use crate::{
+    BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size, Variants,
+};
+
+/// "Simple" layout constructors that cannot fail.
+impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
+    pub fn unit<C: HasDataLayout>(cx: &C, sized: bool) -> Self {
+        let dl = cx.data_layout();
+        LayoutData {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Arbitrary {
+                offsets: IndexVec::new(),
+                memory_index: IndexVec::new(),
+            },
+            backend_repr: BackendRepr::Memory { sized },
+            largest_niche: None,
+            uninhabited: false,
+            align: dl.i8_align,
+            size: Size::ZERO,
+            max_repr_align: None,
+            unadjusted_abi_align: dl.i8_align.abi,
+            randomization_seed: Hash64::new(0),
+        }
+    }
+
+    pub fn never_type<C: HasDataLayout>(cx: &C) -> Self {
+        let dl = cx.data_layout();
+        // This is also used for uninhabited enums, so we use `Variants::Empty`.
+        LayoutData {
+            variants: Variants::Empty,
+            fields: FieldsShape::Primitive,
+            backend_repr: BackendRepr::Memory { sized: true },
+            largest_niche: None,
+            uninhabited: true,
+            align: dl.i8_align,
+            size: Size::ZERO,
+            max_repr_align: None,
+            unadjusted_abi_align: dl.i8_align.abi,
+            randomization_seed: Hash64::ZERO,
+        }
+    }
+
+    pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
+        let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
+        let size = scalar.size(cx);
+        let align = scalar.align(cx);
+
+        let range = scalar.valid_range(cx);
+
+        // All primitive types for which we don't have subtype coercions should get a distinct seed,
+        // so that types wrapping them can use randomization to arrive at distinct layouts.
+        //
+        // Some type information is already lost at this point, so as an approximation we derive
+        // the seed from what remains. For example on 64-bit targets usize and u64 can no longer
+        // be distinguished.
+        let randomization_seed = size
+            .bytes()
+            .wrapping_add(
+                match scalar.primitive() {
+                    Primitive::Int(_, true) => 1,
+                    Primitive::Int(_, false) => 2,
+                    Primitive::Float(_) => 3,
+                    Primitive::Pointer(_) => 4,
+                } << 32,
+            )
+            // distinguishes references from pointers
+            .wrapping_add((range.start as u64).rotate_right(16))
+            // distinguishes char from u32 and bool from u8
+            .wrapping_add((range.end as u64).rotate_right(16));
+
+        LayoutData {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Primitive,
+            backend_repr: BackendRepr::Scalar(scalar),
+            largest_niche,
+            uninhabited: false,
+            size,
+            align,
+            max_repr_align: None,
+            unadjusted_abi_align: align.abi,
+            randomization_seed: Hash64::new(randomization_seed),
+        }
+    }
+
+    pub fn scalar_pair<C: HasDataLayout>(cx: &C, a: Scalar, b: Scalar) -> Self {
+        let dl = cx.data_layout();
+        let b_align = b.align(dl);
+        let align = a.align(dl).max(b_align).max(dl.aggregate_align);
+        let b_offset = a.size(dl).align_to(b_align.abi);
+        let size = (b_offset + b.size(dl)).align_to(align.abi);
+
+        // HACK(nox): We iter on `b` and then `a` because `max_by_key`
+        // returns the last maximum.
+        let largest_niche = Niche::from_scalar(dl, b_offset, b)
+            .into_iter()
+            .chain(Niche::from_scalar(dl, Size::ZERO, a))
+            .max_by_key(|niche| niche.available(dl));
+
+        let combined_seed = a.size(dl).bytes().wrapping_add(b.size(dl).bytes());
+
+        LayoutData {
+            variants: Variants::Single { index: VariantIdx::new(0) },
+            fields: FieldsShape::Arbitrary {
+                offsets: [Size::ZERO, b_offset].into(),
+                memory_index: [0, 1].into(),
+            },
+            backend_repr: BackendRepr::ScalarPair(a, b),
+            largest_niche,
+            uninhabited: false,
+            align,
+            size,
+            max_repr_align: None,
+            unadjusted_abi_align: align.abi,
+            randomization_seed: Hash64::new(combined_seed),
+        }
+    }
+
+    /// Returns a dummy layout for an uninhabited variant.
+    ///
+    /// Uninhabited variants get pruned as part of the layout calculation,
+    /// so this can be used after the fact to reconstitute a layout.
+    pub fn uninhabited_variant<C: HasDataLayout>(cx: &C, index: VariantIdx, fields: usize) -> Self {
+        let dl = cx.data_layout();
+        LayoutData {
+            variants: Variants::Single { index },
+            fields: match NonZero::new(fields) {
+                Some(fields) => FieldsShape::Union(fields),
+                None => FieldsShape::Arbitrary {
+                    offsets: IndexVec::new(),
+                    memory_index: IndexVec::new(),
+                },
+            },
+            backend_repr: BackendRepr::Memory { sized: true },
+            largest_niche: None,
+            uninhabited: true,
+            align: dl.i8_align,
+            size: Size::ZERO,
+            max_repr_align: None,
+            unadjusted_abi_align: dl.i8_align.abi,
+            randomization_seed: Hash64::ZERO,
+        }
+    }
+}
diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs
index 03f3f043c21..4f43c0e6f8e 100644
--- a/compiler/rustc_abi/src/layout/ty.rs
+++ b/compiler/rustc_abi/src/layout/ty.rs
@@ -150,6 +150,12 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
     }
 }
 
+impl<'a, Ty> AsRef<LayoutData<FieldIdx, VariantIdx>> for TyAndLayout<'a, Ty> {
+    fn as_ref(&self) -> &LayoutData<FieldIdx, VariantIdx> {
+        &*self.layout.0.0
+    }
+}
+
 /// Trait that needs to be implemented by the higher-level type representation
 /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
 pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug {
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index a59dc870aa3..078b676e40e 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -5,7 +5,6 @@
 #![cfg_attr(feature = "nightly", feature(rustc_attrs))]
 #![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
 #![cfg_attr(feature = "nightly", feature(step_trait))]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 /*! ABI handling for rustc
@@ -205,6 +204,13 @@ impl ReprOptions {
     }
 }
 
+/// The maximum supported number of lanes in a SIMD vector.
+///
+/// This value is selected based on backend support:
+/// * LLVM does not appear to have a vector width limit.
+/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
+pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
+
 /// Parsed [Data layout](https://llvm.org/docs/LangRef.html#data-layout)
 /// for a target, which contains everything needed to compute layouts.
 #[derive(Debug, PartialEq, Eq)]
@@ -1744,48 +1750,6 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
     pub fn is_uninhabited(&self) -> bool {
         self.uninhabited
     }
-
-    pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
-        let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
-        let size = scalar.size(cx);
-        let align = scalar.align(cx);
-
-        let range = scalar.valid_range(cx);
-
-        // All primitive types for which we don't have subtype coercions should get a distinct seed,
-        // so that types wrapping them can use randomization to arrive at distinct layouts.
-        //
-        // Some type information is already lost at this point, so as an approximation we derive
-        // the seed from what remains. For example on 64-bit targets usize and u64 can no longer
-        // be distinguished.
-        let randomization_seed = size
-            .bytes()
-            .wrapping_add(
-                match scalar.primitive() {
-                    Primitive::Int(_, true) => 1,
-                    Primitive::Int(_, false) => 2,
-                    Primitive::Float(_) => 3,
-                    Primitive::Pointer(_) => 4,
-                } << 32,
-            )
-            // distinguishes references from pointers
-            .wrapping_add((range.start as u64).rotate_right(16))
-            // distinguishes char from u32 and bool from u8
-            .wrapping_add((range.end as u64).rotate_right(16));
-
-        LayoutData {
-            variants: Variants::Single { index: VariantIdx::new(0) },
-            fields: FieldsShape::Primitive,
-            backend_repr: BackendRepr::Scalar(scalar),
-            largest_niche,
-            uninhabited: false,
-            size,
-            align,
-            max_repr_align: None,
-            unadjusted_abi_align: align.abi,
-            randomization_seed: Hash64::new(randomization_seed),
-        }
-    }
 }
 
 impl<FieldIdx: Idx, VariantIdx: Idx> fmt::Debug for LayoutData<FieldIdx, VariantIdx>
diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml
index bbcd8ea6d38..1a600f0ee3f 100644
--- a/compiler/rustc_arena/Cargo.toml
+++ b/compiler/rustc_arena/Cargo.toml
@@ -7,3 +7,6 @@ edition = "2024"
 # tidy-alphabetical-start
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index b21ccba93bb..6aaac072e4b 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -23,7 +23,6 @@
 #![feature(maybe_uninit_slice)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::alloc::Layout;
@@ -93,7 +92,7 @@ impl<T> ArenaChunk<T> {
     #[inline]
     fn end(&mut self) -> *mut T {
         unsafe {
-            if mem::size_of::<T>() == 0 {
+            if size_of::<T>() == 0 {
                 // A pointer as large as possible for zero-sized elements.
                 ptr::without_provenance_mut(!0)
             } else {
@@ -151,7 +150,7 @@ impl<T> TypedArena<T> {
         }
 
         unsafe {
-            if mem::size_of::<T>() == 0 {
+            if size_of::<T>() == 0 {
                 self.ptr.set(self.ptr.get().wrapping_byte_add(1));
                 let ptr = ptr::NonNull::<T>::dangling().as_ptr();
                 // Don't drop the object. This `write` is equivalent to `forget`.
@@ -173,13 +172,13 @@ impl<T> TypedArena<T> {
         // FIXME: this should *likely* use `offset_from`, but more
         // investigation is needed (including running tests in miri).
         let available_bytes = self.end.get().addr() - self.ptr.get().addr();
-        let additional_bytes = additional.checked_mul(mem::size_of::<T>()).unwrap();
+        let additional_bytes = additional.checked_mul(size_of::<T>()).unwrap();
         available_bytes >= additional_bytes
     }
 
     #[inline]
     fn alloc_raw_slice(&self, len: usize) -> *mut T {
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
         assert!(len != 0);
 
         // Ensure the current chunk can fit `len` objects.
@@ -213,7 +212,7 @@ impl<T> TypedArena<T> {
         // So we collect all the elements beforehand, which takes care of reentrancy and panic
         // safety. This function is much less hot than `DroplessArena::alloc_from_iter`, so it
         // doesn't need to be hyper-optimized.
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
 
         let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
         if vec.is_empty() {
@@ -236,7 +235,7 @@ impl<T> TypedArena<T> {
         unsafe {
             // We need the element size to convert chunk sizes (ranging from
             // PAGE to HUGE_PAGE bytes) to element counts.
-            let elem_size = cmp::max(1, mem::size_of::<T>());
+            let elem_size = cmp::max(1, size_of::<T>());
             let mut chunks = self.chunks.borrow_mut();
             let mut new_cap;
             if let Some(last_chunk) = chunks.last_mut() {
@@ -246,7 +245,7 @@ impl<T> TypedArena<T> {
                     // FIXME: this should *likely* use `offset_from`, but more
                     // investigation is needed (including running tests in miri).
                     let used_bytes = self.ptr.get().addr() - last_chunk.start().addr();
-                    last_chunk.entries = used_bytes / mem::size_of::<T>();
+                    last_chunk.entries = used_bytes / size_of::<T>();
                 }
 
                 // If the previous chunk's len is less than HUGE_PAGE
@@ -276,7 +275,7 @@ impl<T> TypedArena<T> {
         let end = self.ptr.get().addr();
         // We then calculate the number of elements to be dropped in the last chunk,
         // which is the filled area's length.
-        let diff = if mem::size_of::<T>() == 0 {
+        let diff = if size_of::<T>() == 0 {
             // `T` is ZST. It can't have a drop flag, so the value here doesn't matter. We get
             // the number of zero-sized values in the last and only chunk, just out of caution.
             // Recall that `end` was incremented for each allocated value.
@@ -284,7 +283,7 @@ impl<T> TypedArena<T> {
         } else {
             // FIXME: this should *likely* use `offset_from`, but more
             // investigation is needed (including running tests in miri).
-            (end - start) / mem::size_of::<T>()
+            (end - start) / size_of::<T>()
         };
         // Pass that to the `destroy` method.
         unsafe {
@@ -329,7 +328,7 @@ fn align_up(val: usize, align: usize) -> usize {
 
 // Pointer alignment is common in compiler types, so keep `DroplessArena` aligned to them
 // to optimize away alignment code.
-const DROPLESS_ALIGNMENT: usize = mem::align_of::<usize>();
+const DROPLESS_ALIGNMENT: usize = align_of::<usize>();
 
 /// An arena that can hold objects of multiple different types that impl `Copy`
 /// and/or satisfy `!mem::needs_drop`.
@@ -447,7 +446,7 @@ impl DroplessArena {
     #[inline]
     pub fn alloc<T>(&self, object: T) -> &mut T {
         assert!(!mem::needs_drop::<T>());
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
 
         let mem = self.alloc_raw(Layout::new::<T>()) as *mut T;
 
@@ -471,7 +470,7 @@ impl DroplessArena {
         T: Copy,
     {
         assert!(!mem::needs_drop::<T>());
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
         assert!(!slice.is_empty());
 
         let mem = self.alloc_raw(Layout::for_value::<[T]>(slice)) as *mut T;
@@ -546,7 +545,7 @@ impl DroplessArena {
         // Warning: this function is reentrant: `iter` could hold a reference to `&self` and
         // allocate additional elements while we're iterating.
         let iter = iter.into_iter();
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
         assert!(!mem::needs_drop::<T>());
 
         let size_hint = iter.size_hint();
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml
index 902287d0328..259b51689e4 100644
--- a/compiler/rustc_ast/Cargo.toml
+++ b/compiler/rustc_ast/Cargo.toml
@@ -18,3 +18,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 6372c66050e..294c6c9ba7a 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -19,7 +19,6 @@
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
 #![feature(stmt_expr_attributes)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod util {
diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml
index f54e9687d8c..668c45438d6 100644
--- a/compiler/rustc_ast_ir/Cargo.toml
+++ b/compiler/rustc_ast_ir/Cargo.toml
@@ -19,3 +19,6 @@ nightly = [
     "dep:rustc_macros",
     "dep:rustc_span",
 ]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs
index 9884e191ea7..6d05cd18cec 100644
--- a/compiler/rustc_ast_ir/src/lib.rs
+++ b/compiler/rustc_ast_ir/src/lib.rs
@@ -9,7 +9,6 @@
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 #![cfg_attr(feature = "nightly", feature(never_type))]
 #![cfg_attr(feature = "nightly", feature(rustc_attrs))]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[cfg(feature = "nightly")]
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 2ec4f4b0555..358963c7997 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1c4edd8348f..4cecc56909e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -38,7 +38,6 @@
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::sync::Arc;
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index c738cb2aa2f..5966308a262 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -20,3 +20,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index b4ed70d83e5..093199cf342 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -10,7 +10,6 @@
 #![feature(iter_is_partitioned)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod ast_validation;
diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml
index 2634dd1fdf9..b120bdc2f05 100644
--- a/compiler/rustc_ast_pretty/Cargo.toml
+++ b/compiler/rustc_ast_pretty/Cargo.toml
@@ -12,3 +12,6 @@ rustc_lexer = { path = "../rustc_lexer" }
 rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 602ab69ee5b..84d9ce278a2 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -3,7 +3,6 @@
 #![doc(rust_logo)]
 #![feature(box_patterns)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod helpers;
diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml
index b18923c337f..8fbc21f3ba2 100644
--- a/compiler/rustc_attr_data_structures/Cargo.toml
+++ b/compiler/rustc_attr_data_structures/Cargo.toml
@@ -14,3 +14,6 @@ rustc_serialize = {path = "../rustc_serialize"}
 rustc_span = {path = "../rustc_span"}
 thin-vec = "0.2.12"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs
index e4bb459e6df..be00d1c10e0 100644
--- a/compiler/rustc_attr_data_structures/src/lib.rs
+++ b/compiler/rustc_attr_data_structures/src/lib.rs
@@ -3,7 +3,6 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod attributes;
@@ -149,3 +148,47 @@ print_tup!(A B C D E F G H);
 print_skip!(Span, ());
 print_disp!(Symbol, u16, bool, NonZero<u32>);
 print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
+
+/// Finds attributes in sequences of attributes by pattern matching.
+///
+/// A little like `matches` but for attributes.
+///
+/// ```rust,ignore (illustrative)
+/// // finds the repr attribute
+/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) {
+///
+/// }
+///
+/// // checks if one has matched
+/// if find_attr!(attrs, AttributeKind::Repr(_)) {
+///
+/// }
+/// ```
+///
+/// Often this requires you to first end up with a list of attributes.
+/// A common way to get those is through `tcx.get_all_attrs(did)`
+#[macro_export]
+macro_rules! find_attr {
+    ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
+        $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
+    }};
+
+    ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
+        fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator<Item = &'a rustc_hir::Attribute>) {}
+        check_attribute_iterator(&$attributes_list);
+
+        let find_attribute = |iter| {
+            for i in $attributes_list {
+                match i {
+                    rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
+                        return Some($e);
+                    }
+                    _ => {}
+                }
+            }
+
+            None
+        };
+        find_attribute($attributes_list)
+    }};
+}
diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml
index c335eeb5f71..24b552e2de4 100644
--- a/compiler/rustc_attr_parsing/Cargo.toml
+++ b/compiler/rustc_attr_parsing/Cargo.toml
@@ -16,8 +16,12 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
+rustc_middle = { path = "../rustc_middle" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs
index 9841166b37d..249e71ef70d 100644
--- a/compiler/rustc_attr_parsing/src/lib.rs
+++ b/compiler/rustc_attr_parsing/src/lib.rs
@@ -80,7 +80,6 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[macro_use]
@@ -95,47 +94,3 @@ pub use context::{AttributeParser, OmitDoc};
 pub use rustc_attr_data_structures::*;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
-
-/// Finds attributes in sequences of attributes by pattern matching.
-///
-/// A little like `matches` but for attributes.
-///
-/// ```rust,ignore (illustrative)
-/// // finds the repr attribute
-/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) {
-///
-/// }
-///
-/// // checks if one has matched
-/// if find_attr!(attrs, AttributeKind::Repr(_)) {
-///
-/// }
-/// ```
-///
-/// Often this requires you to first end up with a list of attributes.
-/// A common way to get those is through `tcx.get_all_attrs(did)`
-#[macro_export]
-macro_rules! find_attr {
-    ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
-        $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
-    }};
-
-    ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
-        fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator<Item = &'a rustc_hir::Attribute>) {}
-        check_attribute_iterator(&$attributes_list);
-
-        let find_attribute = |iter| {
-            for i in $attributes_list {
-                match i {
-                    rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
-                        return Some($e);
-                    }
-                    _ => {}
-                }
-            }
-
-            None
-        };
-        find_attribute($attributes_list)
-    }};
-}
diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml
index cb0e145386b..1480b59f1e0 100644
--- a/compiler/rustc_baked_icu_data/Cargo.toml
+++ b/compiler/rustc_baked_icu_data/Cargo.toml
@@ -11,3 +11,6 @@ icu_locid_transform = "1.3.2"
 icu_provider = { version = "1.2", features = ["sync"] }
 zerovec = "0.10.0"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs
index f86a9db61c6..df9bee0ebf5 100644
--- a/compiler/rustc_baked_icu_data/src/lib.rs
+++ b/compiler/rustc_baked_icu_data/src/lib.rs
@@ -23,9 +23,9 @@
 // tidy-alphabetical-start
 #![allow(elided_lifetimes_in_paths)]
 #![allow(internal_features)]
+#![allow(unreachable_pub)] // because this crate is mostly generated code
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-// #![warn(unreachable_pub)] // don't use because this crate is mostly generated code
 // tidy-alphabetical-end
 
 mod data {
diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml
index 9e7d55180a2..15338eeb37a 100644
--- a/compiler/rustc_borrowck/Cargo.toml
+++ b/compiler/rustc_borrowck/Cargo.toml
@@ -27,3 +27,6 @@ rustc_traits = { path = "../rustc_traits" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 64a533e05ff..4d3774682ce 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -13,7 +13,6 @@
 #![feature(rustdoc_internals)]
 #![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index b5f4f2efd1f..da3572eebee 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -3,10 +3,6 @@ name = "rustc_builtin_macros"
 version = "0.0.0"
 edition = "2024"
 
-
-[lints.rust]
-unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] }
-
 [lib]
 doctest = false
 
@@ -34,3 +30,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index ca16583a45d..c23ce1e5e4a 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -18,7 +18,6 @@
 #![feature(rustdoc_internals)]
 #![feature(string_from_utf8_lossy_owned)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate proc_macro;
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index c8b7616e645..6573b5b165e 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -2439,9 +2439,5 @@ fn get_maybe_pointer_size(value: RValue<'_>) -> u32 {
 #[cfg(not(feature = "master"))]
 fn get_maybe_pointer_size(value: RValue<'_>) -> u32 {
     let type_ = value.get_type();
-    if type_.get_pointee().is_some() {
-        std::mem::size_of::<*const ()>() as _
-    } else {
-        type_.get_size()
-    }
+    if type_.get_pointee().is_some() { size_of::<*const ()>() as _ } else { type_.get_size() }
 }
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index d3ce7c5a113..1741c3bacc7 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -43,3 +43,6 @@ serde_json = "1"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index e51d4852db2..2f3c8c75b0b 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -19,7 +19,6 @@
 #![feature(rustdoc_internals)]
 #![feature(slice_as_array)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::any::Any;
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 1346efcb87c..c00be0e9926 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -63,3 +63,6 @@ features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive",
 [target.'cfg(windows)'.dependencies.windows]
 version = "0.59.0"
 features = ["Win32_Globalization"]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 3407117a06e..7d9971c021d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1177,7 +1177,7 @@ mod win {
             let mut cp: u32 = 0;
             // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32.
             // But the API requires us to pass the data as though it's a [u16] string.
-            let len = std::mem::size_of::<u32>() / std::mem::size_of::<u16>();
+            let len = size_of::<u32>() / size_of::<u16>();
             let data = std::slice::from_raw_parts_mut(&mut cp as *mut u32 as *mut u16, len);
             let len_written = GetLocaleInfoEx(
                 LOCALE_NAME_SYSTEM_DEFAULT,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 4e758bfdec3..8ad04032414 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -14,7 +14,6 @@
 #![feature(rustdoc_internals)]
 #![feature(trait_alias)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 //! This crate contains codegen code that is used by all codegen backends (LLVM and others).
diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml
index a0cc2c65e6e..d76238a3992 100644
--- a/compiler/rustc_const_eval/Cargo.toml
+++ b/compiler/rustc_const_eval/Cargo.toml
@@ -26,3 +26,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index ed5489652fb..da52d60ae59 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -16,7 +16,6 @@
 #![feature(unqualified_local_imports)]
 #![feature(yeet_expr)]
 #![warn(unqualified_local_imports)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod check_consts;
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index bdf5494f210..b364ab0dde4 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -54,3 +54,6 @@ memmap2 = "0.2.1"
 
 [target.'cfg(not(target_has_atomic = "64"))'.dependencies]
 portable-atomic = "1.5.1"
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs
index 0e5ecfd9bff..a636d09fcae 100644
--- a/compiler/rustc_data_structures/src/aligned.rs
+++ b/compiler/rustc_data_structures/src/aligned.rs
@@ -2,10 +2,8 @@ use std::ptr::Alignment;
 
 /// Returns the ABI-required minimum alignment of a type in bytes.
 ///
-/// This is equivalent to [`mem::align_of`], but also works for some unsized
+/// This is equivalent to [`align_of`], but also works for some unsized
 /// types (e.g. slices or rustc's `List`s).
-///
-/// [`mem::align_of`]: std::mem::align_of
 pub const fn align_of<T: ?Sized + Aligned>() -> Alignment {
     T::ALIGN
 }
@@ -15,10 +13,10 @@ pub const fn align_of<T: ?Sized + Aligned>() -> Alignment {
 /// # Safety
 ///
 /// `Self::ALIGN` must be equal to the alignment of `Self`. For sized types it
-/// is [`mem::align_of<Self>()`], for unsized types it depends on the type, for
+/// is [`align_of::<Self>()`], for unsized types it depends on the type, for
 /// example `[T]` has alignment of `T`.
 ///
-/// [`mem::align_of<Self>()`]: std::mem::align_of
+/// [`align_of::<Self>()`]: align_of
 pub unsafe trait Aligned {
     /// Alignment of `Self`.
     const ALIGN: Alignment;
diff --git a/compiler/rustc_data_structures/src/graph/tests.rs b/compiler/rustc_data_structures/src/graph/tests.rs
index b69b9dbc4a8..e48b9686c26 100644
--- a/compiler/rustc_data_structures/src/graph/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/tests.rs
@@ -3,7 +3,7 @@ use std::cmp::max;
 use super::*;
 use crate::fx::FxHashMap;
 
-pub struct TestGraph {
+pub(super) struct TestGraph {
     num_nodes: usize,
     start_node: usize,
     successors: FxHashMap<usize, Vec<usize>>,
@@ -11,7 +11,7 @@ pub struct TestGraph {
 }
 
 impl TestGraph {
-    pub fn new(start_node: usize, edges: &[(usize, usize)]) -> Self {
+    pub(super) fn new(start_node: usize, edges: &[(usize, usize)]) -> Self {
         let mut graph = TestGraph {
             num_nodes: start_node + 1,
             start_node,
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 78d69a66edc..8d19fc5f9cc 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -313,7 +313,7 @@ pub struct Error<O, E> {
 
 mod helper {
     use super::*;
-    pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
+    pub(super) type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
     impl<O: ForestObligation> ObligationForest<O> {
         pub fn new() -> ObligationForest<O> {
             ObligationForest {
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 39db551adfb..60f007083ba 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -863,15 +863,13 @@ fn get_thread_id() -> u32 {
 cfg_match! {
     windows => {
         pub fn get_resident_set_size() -> Option<usize> {
-            use std::mem;
-
             use windows::{
                 Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
                 Win32::System::Threading::GetCurrentProcess,
             };
 
             let mut pmc = PROCESS_MEMORY_COUNTERS::default();
-            let pmc_size = mem::size_of_val(&pmc);
+            let pmc_size = size_of_val(&pmc);
             unsafe {
                 K32GetProcessMemoryInfo(
                     GetCurrentProcess(),
@@ -889,7 +887,7 @@ cfg_match! {
         pub fn get_resident_set_size() -> Option<usize> {
             use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO};
             use std::mem;
-            const PROC_TASKINFO_SIZE: c_int = mem::size_of::<proc_taskinfo>() as c_int;
+            const PROC_TASKINFO_SIZE: c_int = size_of::<proc_taskinfo>() as c_int;
 
             unsafe {
                 let mut info: proc_taskinfo = mem::zeroed();
diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index e6be9c256f0..3016348f224 100644
--- a/compiler/rustc_data_structures/src/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
@@ -1,7 +1,7 @@
 use std::borrow::Borrow;
 use std::collections::hash_map::RawEntryMut;
 use std::hash::{Hash, Hasher};
-use std::{iter, mem};
+use std::iter;
 
 use either::Either;
 
@@ -221,7 +221,7 @@ pub fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
 /// consistently for each `Sharded` instance.
 #[inline]
 fn get_shard_hash(hash: u64) -> usize {
-    let hash_len = mem::size_of::<usize>();
+    let hash_len = size_of::<usize>();
     // Ignore the top 7 bits as hashbrown uses these and get the next SHARD_BITS highest bits.
     // hashbrown also uses the lowest bits, so we can't use those
     (hash >> (hash_len * 8 - 7 - SHARD_BITS)) as usize
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index a1cc75c4985..616a18a72ab 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -88,7 +88,7 @@ mod mode {
 
     // Whether thread safety might be enabled.
     #[inline]
-    pub fn might_be_dyn_thread_safe() -> bool {
+    pub(super) fn might_be_dyn_thread_safe() -> bool {
         DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) != DYN_NOT_THREAD_SAFE
     }
 
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index 1ba631b8623..8ef8a3f3585 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -46,7 +46,7 @@ pub fn parallel_guard<R>(f: impl FnOnce(&ParallelGuard) -> R) -> R {
     ret
 }
 
-pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
 where
     A: FnOnce() -> RA,
     B: FnOnce() -> RB,
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
index 9c1e4cefa69..85b21a7c8ec 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
@@ -7,7 +7,7 @@ use crate::stable_hasher::{HashStable, StableHasher};
 
 /// A tag type used in [`TaggedRef`] tests.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Tag2 {
+enum Tag2 {
     B00 = 0b00,
     B01 = 0b01,
     B10 = 0b10,
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index e3ee8351295..d27895a5e7a 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -10,3 +10,6 @@ crate-type = ["dylib"]
 # tidy-alphabetical-start
 rustc_driver_impl = { path = "../rustc_driver_impl" }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 8593d1faba2..4469fa4e1f3 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -79,3 +79,6 @@ rustc_randomized_layouts = [
     'rustc_middle/rustc_randomized_layouts'
 ]
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index a2ddff7183e..6e4020c6eca 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -16,7 +16,6 @@
 #![feature(result_flattening)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cmp::max;
diff --git a/compiler/rustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml
index 55b4e899051..d89e4526016 100644
--- a/compiler/rustc_error_codes/Cargo.toml
+++ b/compiler/rustc_error_codes/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index d53d5678832..dfeef5a957d 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -6,7 +6,6 @@
 #![deny(rustdoc::invalid_codeblock_attributes)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // This higher-order macro defines the error codes that are in use. It is used
diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml
index 578af7fc51d..e9047ba16e5 100644
--- a/compiler/rustc_error_messages/Cargo.toml
+++ b/compiler/rustc_error_messages/Cargo.toml
@@ -19,3 +19,6 @@ rustc_span = { path = "../rustc_span" }
 tracing = "0.1"
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index ba1c3e185c2..a6fbbb29ccd 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -4,7 +4,6 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(type_alias_impl_trait)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index b11793c190a..fc39a726093 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -39,3 +39,6 @@ features = [
     "Win32_Security",
     "Win32_System_Threading",
 ]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 7fffeaddb86..9f4d2ea5c1a 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -490,7 +490,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
 // would be bad.
 impl<G> !Clone for Diag<'_, G> {}
 
-rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * std::mem::size_of::<usize>());
+rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * size_of::<usize>());
 
 impl<G: EmissionGuarantee> Deref for Diag<'_, G> {
     type Target = DiagInner;
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 86959b28e53..80e43ede445 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -25,7 +25,6 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_errors;
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml
index 0ba139ea5cc..f051ea0c2ac 100644
--- a/compiler/rustc_expand/Cargo.toml
+++ b/compiler/rustc_expand/Cargo.toml
@@ -29,3 +29,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 777044e3f33..4222c9fe906 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -13,7 +13,6 @@
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate proc_macro as pm;
diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml
index a5ae06473cb..1aaace75404 100644
--- a/compiler/rustc_feature/Cargo.toml
+++ b/compiler/rustc_feature/Cargo.toml
@@ -10,3 +10,6 @@ rustc_span = { path = "../rustc_span" }
 serde = { version = "1.0.125", features = [ "derive" ] }
 serde_json = "1.0.59"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 0b034a2ae10..25764755a8f 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -15,7 +15,6 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod accepted;
diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml
index ce76b2745ea..695e8b3fd5d 100644
--- a/compiler/rustc_fluent_macro/Cargo.toml
+++ b/compiler/rustc_fluent_macro/Cargo.toml
@@ -16,3 +16,6 @@ quote = "1"
 syn = { version = "2", features = ["full"] }
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index 3ad51fa1e64..c6e0484b921 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -7,7 +7,6 @@
 #![feature(proc_macro_span)]
 #![feature(rustdoc_internals)]
 #![feature(track_path)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use proc_macro::TokenStream;
diff --git a/compiler/rustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml
index baca3bc7d49..3518209ea5b 100644
--- a/compiler/rustc_fs_util/Cargo.toml
+++ b/compiler/rustc_fs_util/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml
index d84943760ba..2672a624eab 100644
--- a/compiler/rustc_graphviz/Cargo.toml
+++ b/compiler/rustc_graphviz/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index b5774f64b66..c8f8fd5be02 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -277,7 +277,6 @@
 )]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
diff --git a/compiler/rustc_hashes/Cargo.toml b/compiler/rustc_hashes/Cargo.toml
index c7a273cff88..ff46696c4c0 100644
--- a/compiler/rustc_hashes/Cargo.toml
+++ b/compiler/rustc_hashes/Cargo.toml
@@ -7,3 +7,6 @@ edition = "2024"
 # tidy-alphabetical-start
 rustc-stable-hash = { version = "0.1.0" }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml
index 7ca8539845a..e45c49cd7db 100644
--- a/compiler/rustc_hir/Cargo.toml
+++ b/compiler/rustc_hir/Cargo.toml
@@ -21,3 +21,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index ea2581787e4..5f8941d4754 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -435,7 +435,7 @@ pub enum Res<Id = hir::HirId> {
         /// mention any generic parameters to allow the following with `min_const_generics`:
         /// ```
         /// # struct Foo;
-        /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
+        /// impl Foo { fn test() -> [u8; size_of::<Self>()] { todo!() } }
         ///
         /// struct Bar([u8; baz::<Self>()]);
         /// const fn baz<T>() -> usize { 10 }
@@ -445,7 +445,7 @@ pub enum Res<Id = hir::HirId> {
         /// compat lint:
         /// ```
         /// fn foo<T>() {
-        ///     let _bar = [1_u8; std::mem::size_of::<*mut T>()];
+        ///     let _bar = [1_u8; size_of::<*mut T>()];
         /// }
         /// ```
         // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 270d4fbec30..84d369f1edd 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -13,7 +13,6 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_hir;
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index 55a816a855a..99ced5ff0a9 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -32,3 +32,6 @@ rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 50b0e32b95e..26a20690a95 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -73,7 +73,6 @@ This API is completely unstable and subject to change.
 #![feature(slice_partition_dedup)]
 #![feature(try_blocks)]
 #![feature(unwrap_infallible)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // These are used by Clippy.
diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml
index 86989d1e55b..bc6431d0271 100644
--- a/compiler/rustc_hir_pretty/Cargo.toml
+++ b/compiler/rustc_hir_pretty/Cargo.toml
@@ -8,7 +8,10 @@ edition = "2024"
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
-rustc_attr_parsing = { path = "../rustc_attr_parsing" }
+rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_span = { path = "../rustc_span" }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index aafbd2738f9..0e3721126fb 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -3,7 +3,6 @@
 
 // tidy-alphabetical-start
 #![recursion_limit = "256"]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cell::Cell;
@@ -16,7 +15,7 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
 use rustc_ast_pretty::pp::{self, Breaks};
 use rustc_ast_pretty::pprust::state::MacHeader;
 use rustc_ast_pretty::pprust::{Comments, PrintState};
-use rustc_attr_parsing::{AttributeKind, PrintAttribute};
+use rustc_attr_data_structures::{AttributeKind, PrintAttribute};
 use rustc_hir::{
     BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
     HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml
index f1afb7b712d..1d6486fb7dc 100644
--- a/compiler/rustc_hir_typeck/Cargo.toml
+++ b/compiler/rustc_hir_typeck/Cargo.toml
@@ -27,3 +27,6 @@ rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 67419fdf1c3..d7b5c1ed5e1 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -41,8 +41,8 @@ use rustc_abi::ExternAbi;
 use rustc_attr_parsing::InlineAttr;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, struct_span_code_err};
-use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{self as hir, LangItem};
 use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
 use rustc_infer::infer::relate::RelateResult;
 use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
@@ -56,7 +56,7 @@ use rustc_middle::ty::adjustment::{
 };
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::visit::TypeVisitableExt;
-use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, AliasTy, GenericArgsRef, Ty, TyCtxt};
 use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -593,6 +593,63 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Create an obligation for `Source: CoerceUnsized<Target>`.
         let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target });
+        let root_obligation = Obligation::new(
+            self.tcx,
+            cause.clone(),
+            self.fcx.param_env,
+            ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target]),
+        );
+
+        // If the root `Source: CoerceUnsized<Target>` obligation can't possibly hold,
+        // we don't have to assume that this is unsizing coercion (it will always lead to an error)
+        //
+        // However, we don't want to bail early all the time, since the unholdable obligations
+        // may be interesting for diagnostics (such as trying to coerce `&T` to `&dyn Id<This = U>`),
+        // so we only bail if there (likely) is another way to convert the types.
+        if !self.infcx.predicate_may_hold(&root_obligation) {
+            if let Some(dyn_metadata_adt_def_id) = self.tcx.lang_items().get(LangItem::DynMetadata)
+                && let Some(metadata_type_def_id) = self.tcx.lang_items().get(LangItem::Metadata)
+            {
+                self.probe(|_| {
+                    let ocx = ObligationCtxt::new(&self.infcx);
+
+                    // returns `true` if `<ty as Pointee>::Metadata` is `DynMetadata<_>`
+                    let has_dyn_trait_metadata = |ty| {
+                        let metadata_ty: Result<_, _> = ocx.structurally_normalize_ty(
+                            &ObligationCause::dummy(),
+                            self.fcx.param_env,
+                            Ty::new_alias(
+                                self.tcx,
+                                ty::AliasTyKind::Projection,
+                                AliasTy::new(self.tcx, metadata_type_def_id, [ty]),
+                            ),
+                        );
+
+                        metadata_ty.is_ok_and(|metadata_ty| {
+                            metadata_ty
+                                .ty_adt_def()
+                                .is_some_and(|d| d.did() == dyn_metadata_adt_def_id)
+                        })
+                    };
+
+                    // If both types are raw pointers to a (wrapper over a) trait object,
+                    // this might be a cast like `*const W<dyn Trait> -> *const dyn Trait`.
+                    // So it's better to bail and try that. (even if the cast is not possible, for
+                    // example due to vtables not matching, cast diagnostic will likely still be better)
+                    //
+                    // N.B. use `target`, not `coerce_target` (the latter is a var)
+                    if let &ty::RawPtr(source_pointee, _) = coerce_source.kind()
+                        && let &ty::RawPtr(target_pointee, _) = target.kind()
+                        && has_dyn_trait_metadata(source_pointee)
+                        && has_dyn_trait_metadata(target_pointee)
+                    {
+                        return Err(TypeError::Mismatch);
+                    }
+
+                    Ok(())
+                })?;
+            }
+        }
 
         // Use a FIFO queue for this custom fulfillment procedure.
         //
@@ -601,12 +658,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // and almost never more than 3. By using a SmallVec we avoid an
         // allocation, at the (very small) cost of (occasionally) having to
         // shift subsequent elements down when removing the front element.
-        let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![Obligation::new(
-            self.tcx,
-            cause,
-            self.fcx.param_env,
-            ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
-        )];
+        let mut queue: SmallVec<[PredicateObligation<'tcx>; 4]> = smallvec![root_obligation];
 
         // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
         // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 8b9c2b4a6ca..263fb84206e 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -8,7 +8,6 @@
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod _match;
diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml
index 4939bfb3a1c..754881309bf 100644
--- a/compiler/rustc_incremental/Cargo.toml
+++ b/compiler/rustc_incremental/Cargo.toml
@@ -22,3 +22,6 @@ rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 563ed7614c6..299ee487638 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -7,7 +7,6 @@
 #![doc(rust_logo)]
 #![feature(file_buffered)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod assert_dep_graph;
diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs
index 4c664ea6ba0..9cec2702a41 100644
--- a/compiler/rustc_incremental/src/persist/file_format.rs
+++ b/compiler/rustc_incremental/src/persist/file_format.rs
@@ -123,7 +123,7 @@ pub(crate) fn read_file(
 
     // Check HEADER_FORMAT_VERSION
     {
-        debug_assert!(::std::mem::size_of_val(&HEADER_FORMAT_VERSION) == 2);
+        debug_assert!(size_of_val(&HEADER_FORMAT_VERSION) == 2);
         let mut header_format_version = [0u8; 2];
         file.read_exact(&mut header_format_version)?;
         let header_format_version =
diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml
index 3d83a3c98da..ee6fe11f9a5 100644
--- a/compiler/rustc_index/Cargo.toml
+++ b/compiler/rustc_index/Cargo.toml
@@ -21,3 +21,6 @@ nightly = [
 ]
 rustc_randomized_layouts = []
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index 6dc044a6d38..598409c9051 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -1,7 +1,9 @@
 use std::marker::PhantomData;
+#[cfg(not(feature = "nightly"))]
+use std::mem;
 use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl};
 use std::rc::Rc;
-use std::{fmt, iter, mem, slice};
+use std::{fmt, iter, slice};
 
 use Chunk::*;
 #[cfg(feature = "nightly")]
@@ -14,7 +16,7 @@ use crate::{Idx, IndexVec};
 mod tests;
 
 type Word = u64;
-const WORD_BYTES: usize = mem::size_of::<Word>();
+const WORD_BYTES: usize = size_of::<Word>();
 const WORD_BITS: usize = WORD_BYTES * 8;
 
 // The choice of chunk size has some trade-offs.
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 3441a5f65c7..cc680838e7e 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -4,7 +4,6 @@
 #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))]
 #![cfg_attr(feature = "nightly", feature(new_range_api))]
 #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod bit_set;
diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs
index 381d79c24fc..5b0ca4b2b92 100644
--- a/compiler/rustc_index/src/vec/tests.rs
+++ b/compiler/rustc_index/src/vec/tests.rs
@@ -9,8 +9,6 @@ crate::newtype_index! {
 
 #[test]
 fn index_size_is_optimized() {
-    use std::mem::size_of;
-
     assert_eq!(size_of::<MyIdx>(), 4);
     // Uses 0xFFFF_FFFB
     assert_eq!(size_of::<Option<MyIdx>>(), 4);
diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml
index 891e7ded619..de100bd0e2c 100644
--- a/compiler/rustc_index_macros/Cargo.toml
+++ b/compiler/rustc_index_macros/Cargo.toml
@@ -13,3 +13,6 @@ quote = "1"
 
 [features]
 nightly = []
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs
index 67ec7761133..f0b58eabbff 100644
--- a/compiler/rustc_index_macros/src/newtype.rs
+++ b/compiler/rustc_index_macros/src/newtype.rs
@@ -305,7 +305,7 @@ impl Parse for Newtype {
     }
 }
 
-pub fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+pub(crate) fn newtype(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     let input = parse_macro_input!(input as Newtype);
     input.0.into()
 }
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
index 08c03614884..242886a9248 100644
--- a/compiler/rustc_infer/Cargo.toml
+++ b/compiler/rustc_infer/Cargo.toml
@@ -21,3 +21,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index a04b2bb2b08..ece18f4ea64 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -24,7 +24,6 @@
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
 #![recursion_limit = "512"] // For rustdoc
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod errors;
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 9c9660cf504..add8c0e20e6 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -56,3 +56,6 @@ tracing = "0.1"
 # tidy-alphabetical-start
 llvm = ['dep:rustc_codegen_llvm']
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 54cd341698f..67e0be93523 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -4,7 +4,6 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod callbacks;
diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index 448a50faf45..b9b16eebc54 100644
--- a/compiler/rustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -24,3 +24,6 @@ features = ["emoji"]
 
 [dev-dependencies]
 expect-test = "1.4.0"
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index bf18845a083..61638e45253 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -23,7 +23,6 @@
 // We want to be able to build this crate with a stable compiler,
 // so no `#![feature]` attributes should be added.
 #![deny(unstable_features)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod cursor;
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index d6014f5006a..f6c10aa9744 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 unicode-security = "0.1.0"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 7018774e5c6..35867d8c9ef 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -32,7 +32,6 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod async_closures;
diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml
index 9ab350daf69..f9b45a00ec1 100644
--- a/compiler/rustc_lint_defs/Cargo.toml
+++ b/compiler/rustc_lint_defs/Cargo.toml
@@ -15,3 +15,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 serde = { version = "1.0.125", features = ["derive"] }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 10b85be2cfb..592c934997c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -73,7 +73,6 @@ declare_lint_pass! {
         NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
         NON_CONTIGUOUS_RANGE_ENDPOINTS,
         NON_EXHAUSTIVE_OMITTED_PATTERNS,
-        ORDER_DEPENDENT_TRAIT_OBJECTS,
         OUT_OF_SCOPE_MACRO_CALLS,
         OVERLAPPING_RANGE_ENDPOINTS,
         PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -1502,42 +1501,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `order_dependent_trait_objects` lint detects a trait coherency
-    /// violation that would allow creating two trait impls for the same
-    /// dynamic trait object involving marker traits.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// pub trait Trait {}
-    ///
-    /// impl Trait for dyn Send + Sync { }
-    /// impl Trait for dyn Sync + Send { }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// A previous bug caused the compiler to interpret traits with different
-    /// orders (such as `Send + Sync` and `Sync + Send`) as distinct types
-    /// when they were intended to be treated the same. This allowed code to
-    /// define separate trait implementations when there should be a coherence
-    /// error. This is a [future-incompatible] lint to transition this to a
-    /// hard error in the future. See [issue #56484] for more details.
-    ///
-    /// [issue #56484]: https://github.com/rust-lang/rust/issues/56484
-    /// [future-incompatible]: ../index.md#future-incompatible-lints
-    pub ORDER_DEPENDENT_TRAIT_OBJECTS,
-    Deny,
-    "trait-object types were treated as different depending on marker-trait order",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
-    };
-}
-
-declare_lint! {
     /// The `coherence_leak_check` lint detects conflicting implementations of
     /// a trait that are only distinguished by the old leak-check code.
     ///
@@ -2710,7 +2673,7 @@ declare_lint! {
     ///
     /// ```rust
     /// const fn foo<T>() -> usize {
-    ///     if std::mem::size_of::<*mut T>() < 8 { // size of *mut T does not depend on T
+    ///     if size_of::<*mut T>() < 8 { // size of *mut T does not depend on T
     ///         4
     ///     } else {
     ///         8
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index e564235c41a..46b4b1d4383 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,7 +1,3 @@
-// tidy-alphabetical-start
-#![warn(unreachable_pub)]
-// tidy-alphabetical-end
-
 use rustc_abi::ExternAbi;
 use rustc_ast::AttrId;
 use rustc_ast::attr::AttributeExt;
diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 061562b2ec5..dcfaf9a0282 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -14,3 +14,6 @@ libc = "0.2.73"
 # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here.
 cc = "=1.2.16"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index eda9b2b1fc0..68058250a26 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -4,7 +4,6 @@
 #![doc(rust_logo)]
 #![feature(extern_types)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cell::RefCell;
diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml
index 30f6e9ba805..665ebd52f47 100644
--- a/compiler/rustc_log/Cargo.toml
+++ b/compiler/rustc_log/Cargo.toml
@@ -20,3 +20,6 @@ rustc_span = { path = "../rustc_span" }
 # tidy-alphabetical-start
 max_level_info = ['tracing/max_level_info']
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml
index f9d3b758359..b937f75e892 100644
--- a/compiler/rustc_macros/Cargo.toml
+++ b/compiler/rustc_macros/Cargo.toml
@@ -13,3 +13,6 @@ quote = "1"
 syn = { version = "2.0.9", features = ["full"] }
 synstructure = "0.13.0"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 34fc0f00320..44ba064dd82 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_span)]
 #![feature(proc_macro_tracked_env)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use proc_macro::TokenStream;
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index a8821640f04..5fa3047d14e 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -31,3 +31,6 @@ rustc_type_ir = { path = "../rustc_type_ir" }
 tempfile = "3.2"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index ebcc0efd5a6..8898c5824fa 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(proc_macro_internals)]
 #![feature(rustdoc_internals)]
 #![feature(trusted_len)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate proc_macro;
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index aebd2181f31..3a6216e63a9 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -14,7 +14,8 @@ rustc_abi = { path = "../rustc_abi" }
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
-rustc_attr_parsing = { path = "../rustc_attr_parsing" }
+rustc_ast_ir = { path = "../rustc_ast_ir" }
+rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links
 rustc_errors = { path = "../rustc_errors" }
@@ -42,3 +43,6 @@ tracing = "0.1"
 # tidy-alphabetical-start
 rustc_randomized_layouts = []
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 48ea7df5c23..8fe2cc7101b 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -61,7 +61,6 @@
 #![feature(try_trait_v2_yeet)]
 #![feature(type_alias_impl_trait)]
 #![feature(yeet_expr)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 #[cfg(test)]
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 311bc60c3cd..a94ead161c3 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -1,6 +1,6 @@
 use rustc_abi::Align;
 use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs;
-use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr};
+use rustc_attr_data_structures::{InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::Symbol;
 use rustc_target::spec::SanitizerSet;
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 2260cad41b9..ec128c8c478 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -4,7 +4,7 @@
 use std::num::NonZero;
 
 use rustc_ast::NodeId;
-use rustc_attr_parsing::{
+use rustc_attr_data_structures::{
     self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
 };
 use rustc_data_structures::unord::UnordMap;
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
index cc6389e2989..fea5038e6dd 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs
@@ -223,8 +223,8 @@ impl<D: TyDecoder> Decodable<D> for InitMaskMaterialized {
 // large.
 impl hash::Hash for InitMaskMaterialized {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
-        const MAX_BLOCKS_TO_HASH: usize = super::MAX_BYTES_TO_HASH / std::mem::size_of::<Block>();
-        const MAX_BLOCKS_LEN: usize = super::MAX_HASHED_BUFFER_LEN / std::mem::size_of::<Block>();
+        const MAX_BLOCKS_TO_HASH: usize = super::MAX_BYTES_TO_HASH / size_of::<Block>();
+        const MAX_BLOCKS_LEN: usize = super::MAX_HASHED_BUFFER_LEN / size_of::<Block>();
 
         // Partially hash the `blocks` buffer when it is large. To limit collisions with common
         // prefixes and suffixes, we hash the length and some slices of the buffer.
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index c48cfffa05c..2675b7e0fc5 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -573,7 +573,7 @@ pub fn write_target_uint(
 #[inline]
 pub fn read_target_uint(endianness: Endian, mut source: &[u8]) -> Result<u128, io::Error> {
     // This u128 holds an "any-size uint" (since smaller uints can fits in it)
-    let mut buf = [0u8; std::mem::size_of::<u128>()];
+    let mut buf = [0u8; size_of::<u128>()];
     // So we do not read exactly 16 bytes into the u128, just the "payload".
     let uint = match endianness {
         Endian::Little => {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index ea0bb5feb12..83857ab6c5c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -332,13 +332,13 @@ pub struct Body<'tcx> {
     ///
     /// ```rust
     /// fn test<T>() {
-    ///     let _ = [0; std::mem::size_of::<*mut T>()];
+    ///     let _ = [0; size_of::<*mut T>()];
     /// }
     /// ```
     ///
     /// **WARNING**: Do not change this flags after the MIR was originally created, even if an optimization
     /// removed the last mention of all generic params. We do not want to rely on optimizations and
-    /// potentially allow things like `[u8; std::mem::size_of::<T>() * 0]` due to this.
+    /// potentially allow things like `[u8; size_of::<T>() * 0]` due to this.
     pub is_polymorphic: bool,
 
     /// The phase at which this MIR should be "injected" into the compilation process.
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 58d5c94d033..897119c0712 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -2,7 +2,7 @@ use std::fmt;
 use std::hash::Hash;
 
 use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
-use rustc_attr_parsing::InlineAttr;
+use rustc_attr_data_structures::InlineAttr;
 use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxIndexMap;
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index cbd60920bc5..907618e428f 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -27,7 +27,7 @@ pub type Erase<T: EraseType> = Erased<impl Copy>;
 pub fn erase<T: EraseType>(src: T) -> Erase<T> {
     // Ensure the sizes match
     const {
-        if std::mem::size_of::<T>() != std::mem::size_of::<T::Result>() {
+        if size_of::<T>() != size_of::<T::Result>() {
             panic!("size of T must match erased type T::Result")
         }
     };
@@ -231,9 +231,9 @@ trivial! {
     bool,
     Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
     Option<rustc_ast::expand::allocator::AllocatorKind>,
-    Option<rustc_attr_parsing::ConstStability>,
-    Option<rustc_attr_parsing::DefaultBodyStability>,
-    Option<rustc_attr_parsing::Stability>,
+    Option<rustc_attr_data_structures::ConstStability>,
+    Option<rustc_attr_data_structures::DefaultBodyStability>,
+    Option<rustc_attr_data_structures::Stability>,
     Option<rustc_data_structures::svh::Svh>,
     Option<rustc_hir::def::DefKind>,
     Option<rustc_hir::CoroutineKind>,
@@ -256,10 +256,10 @@ trivial! {
     Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
     rustc_abi::ReprOptions,
     rustc_ast::expand::allocator::AllocatorKind,
-    rustc_attr_parsing::ConstStability,
-    rustc_attr_parsing::DefaultBodyStability,
-    rustc_attr_parsing::Deprecation,
-    rustc_attr_parsing::Stability,
+    rustc_attr_data_structures::ConstStability,
+    rustc_attr_data_structures::DefaultBodyStability,
+    rustc_attr_data_structures::Deprecation,
+    rustc_attr_data_structures::Stability,
     rustc_data_structures::svh::Svh,
     rustc_errors::ErrorGuaranteed,
     rustc_hir::Constness,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3ad9201dd6f..c8708857565 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -41,7 +41,7 @@ use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, Span, Symbol};
 use rustc_target::spec::PanicStrategy;
-use {rustc_abi as abi, rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
+use {rustc_abi as abi, rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};
 
 use crate::infer::canonical::{self, Canonical};
 use crate::lint::LintExpectation;
@@ -999,12 +999,6 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
-        key: DefId
-    ) -> Option<ty::EarlyBinder<'tcx, ty::Ty<'tcx>>> {
-        desc { |tcx| "computing self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
-    }
-
     /// Maps a `DefId` of a type to a list of its inherent impls.
     /// Contains implementations of methods that are inherent to a type.
     /// Methods in these implementations don't need to be exported.
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 66a9e5fed4c..d78a589f203 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -370,7 +370,7 @@ macro_rules! define_callbacks {
                 // Increase this limit if necessary, but do try to keep the size low if possible
                 #[cfg(target_pointer_width = "64")]
                 const _: () = {
-                    if mem::size_of::<Key<'static>>() > 88 {
+                    if size_of::<Key<'static>>() > 88 {
                         panic!("{}", concat!(
                             "the query `",
                             stringify!($name),
@@ -386,7 +386,7 @@ macro_rules! define_callbacks {
                 #[cfg(target_pointer_width = "64")]
                 #[cfg(not(feature = "rustc_randomized_layouts"))]
                 const _: () = {
-                    if mem::size_of::<Value<'static>>() > 64 {
+                    if size_of::<Value<'static>>() > 64 {
                         panic!("{}", concat!(
                             "the query `",
                             stringify!($name),
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 7c9280fae16..9f5e31d894c 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -408,7 +408,7 @@ macro_rules! from_x_for_scalar_int {
                 fn from(u: $ty) -> Self {
                     Self {
                         data: u128::from(u),
-                        size: NonZero::new(std::mem::size_of::<$ty>() as u8).unwrap(),
+                        size: NonZero::new(size_of::<$ty>() as u8).unwrap(),
                     }
                 }
             }
@@ -424,7 +424,7 @@ macro_rules! from_scalar_int_for_x {
                 fn from(int: ScalarInt) -> Self {
                     // The `unwrap` cannot fail because to_bits (if it succeeds)
                     // is guaranteed to return a value that fits into the size.
-                    int.to_bits(Size::from_bytes(std::mem::size_of::<$ty>()))
+                    int.to_bits(Size::from_bytes(size_of::<$ty>()))
                        .try_into().unwrap()
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 27576a2ec4a..f24910477dc 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -2,7 +2,6 @@
 
 use core::intrinsics;
 use std::marker::PhantomData;
-use std::mem;
 use std::num::NonZero;
 use std::ptr::NonNull;
 
@@ -176,17 +175,17 @@ impl<'tcx> GenericArgKind<'tcx> {
         let (tag, ptr) = match self {
             GenericArgKind::Lifetime(lt) => {
                 // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0);
+                assert_eq!(align_of_val(&*lt.0.0) & TAG_MASK, 0);
                 (REGION_TAG, NonNull::from(lt.0.0).cast())
             }
             GenericArgKind::Type(ty) => {
                 // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
+                assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
                 (TYPE_TAG, NonNull::from(ty.0.0).cast())
             }
             GenericArgKind::Const(ct) => {
                 // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
+                assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
                 (CONST_TAG, NonNull::from(ct.0.0).cast())
             }
         };
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 98ca71b86be..b99148f3368 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -203,7 +203,7 @@ impl<'tcx> Instance<'tcx> {
         if !tcx.sess.opts.share_generics()
             // However, if the def_id is marked inline(never), then it's fine to just reuse the
             // upstream monomorphization.
-            && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_parsing::InlineAttr::Never
+            && tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_data_structures::InlineAttr::Never
         {
             return None;
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 272bb0cc915..ebb6a8c08a5 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1,20 +1,17 @@
-use std::num::NonZero;
 use std::ops::Bound;
 use std::{cmp, fmt};
 
 use rustc_abi::{
-    AddressSpace, Align, BackendRepr, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData,
-    PointeeInfo, PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout,
+    AddressSpace, Align, ExternAbi, FieldIdx, FieldsShape, HasDataLayout, LayoutData, PointeeInfo,
+    PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout,
     TyAbiInterface, VariantIdx, Variants,
 };
 use rustc_error_messages::DiagMessage;
 use rustc_errors::{
     Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
 };
-use rustc_hashes::Hash64;
 use rustc_hir::LangItem;
 use rustc_hir::def_id::DefId;
-use rustc_index::IndexVec;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension};
 use rustc_session::config::OptLevel;
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
@@ -185,12 +182,7 @@ pub const WIDE_PTR_ADDR: usize = 0;
 /// - For a slice, this is the length.
 pub const WIDE_PTR_EXTRA: usize = 1;
 
-/// The maximum supported number of lanes in a SIMD vector.
-///
-/// This value is selected based on backend support:
-/// * LLVM does not appear to have a vector width limit.
-/// * Cranelift stores the base-2 log of the lane count in a 4 bit integer.
-pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
+pub const MAX_SIMD_LANES: u64 = rustc_abi::MAX_SIMD_LANES;
 
 /// Used in `check_validity_requirement` to indicate the kind of initialization
 /// that is checked to be valid
@@ -762,11 +754,9 @@ where
         variant_index: VariantIdx,
     ) -> TyAndLayout<'tcx> {
         let layout = match this.variants {
-            Variants::Single { index }
-                // If all variants but one are uninhabited, the variant layout is the enum layout.
-                if index == variant_index =>
-            {
-                this.layout
+            // If all variants but one are uninhabited, the variant layout is the enum layout.
+            Variants::Single { index } if index == variant_index => {
+                return this;
             }
 
             Variants::Single { .. } | Variants::Empty => {
@@ -783,29 +773,18 @@ where
                 }
 
                 let fields = match this.ty.kind() {
-                    ty::Adt(def, _) if def.variants().is_empty() =>
-                        bug!("for_variant called on zero-variant enum {}", this.ty),
+                    ty::Adt(def, _) if def.variants().is_empty() => {
+                        bug!("for_variant called on zero-variant enum {}", this.ty)
+                    }
                     ty::Adt(def, _) => def.variant(variant_index).fields.len(),
                     _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty),
                 };
-                tcx.mk_layout(LayoutData {
-                    variants: Variants::Single { index: variant_index },
-                    fields: match NonZero::new(fields) {
-                        Some(fields) => FieldsShape::Union(fields),
-                        None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() },
-                    },
-                    backend_repr: BackendRepr::Memory { sized: true },
-                    largest_niche: None,
-                    uninhabited: true,
-                    align: tcx.data_layout.i8_align,
-                    size: Size::ZERO,
-                    max_repr_align: None,
-                    unadjusted_abi_align: tcx.data_layout.i8_align.abi,
-                    randomization_seed: Hash64::ZERO,
-                })
+                tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields))
             }
 
-            Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()),
+            Variants::Multiple { ref variants, .. } => {
+                cx.tcx().mk_layout(variants[variant_index].clone())
+            }
         };
 
         assert_eq!(*layout.variants(), Variants::Single { index: variant_index });
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 6718493f6b3..0fd370a5619 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -93,7 +93,7 @@ impl<H, T> RawList<H, T> {
         T: Copy,
     {
         assert!(!mem::needs_drop::<T>());
-        assert!(mem::size_of::<T>() != 0);
+        assert!(size_of::<T>() != 0);
         assert!(!slice.is_empty());
 
         let (layout, _offset) =
@@ -155,7 +155,7 @@ macro_rules! impl_list_empty {
                 static EMPTY: ListSkeleton<$header_ty, MaxAlign> =
                     ListSkeleton { header: $header_init, len: 0, data: [] };
 
-                assert!(mem::align_of::<T>() <= mem::align_of::<MaxAlign>());
+                assert!(align_of::<T>() <= align_of::<MaxAlign>());
 
                 // SAFETY: `EMPTY` is sufficiently aligned to be an empty list for all
                 // types with `align_of(T) <= align_of(MaxAlign)`, which we checked above.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 527509af05f..c5509c0a608 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -17,7 +17,7 @@ use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::num::NonZero;
 use std::ptr::NonNull;
-use std::{fmt, mem, str};
+use std::{fmt, str};
 
 pub use adt::*;
 pub use assoc::*;
@@ -27,7 +27,8 @@ pub use intrinsic::IntrinsicDef;
 use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
 use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::node_id::NodeMap;
-use rustc_attr_parsing::AttributeKind;
+pub use rustc_ast_ir::{Movability, Mutability, try_visit};
+use rustc_attr_data_structures::AttributeKind;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -51,7 +52,7 @@ pub use rustc_type_ir::relate::VarianceDiagInfo;
 pub use rustc_type_ir::*;
 use tracing::{debug, instrument};
 pub use vtable::*;
-use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
+use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};
 
 pub use self::closure::{
     BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,
@@ -637,12 +638,12 @@ impl<'tcx> TermKind<'tcx> {
         let (tag, ptr) = match self {
             TermKind::Ty(ty) => {
                 // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
+                assert_eq!(align_of_val(&*ty.0.0) & TAG_MASK, 0);
                 (TYPE_TAG, NonNull::from(ty.0.0).cast())
             }
             TermKind::Const(ct) => {
                 // Ensure we can use the tag bits.
-                assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
+                assert_eq!(align_of_val(&*ct.0.0) & TAG_MASK, 0);
                 (CONST_TAG, NonNull::from(ct.0.0).cast())
             }
         };
@@ -1414,39 +1415,6 @@ pub enum ImplOverlapKind {
         /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
         marker: bool,
     },
-    /// These impls are allowed to overlap, but that raises an
-    /// issue #33140 future-compatibility warning (tracked in #56484).
-    ///
-    /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
-    /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
-    ///
-    /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied on
-    /// that difference, doing what reduces to the following set of impls:
-    ///
-    /// ```compile_fail,(E0119)
-    /// trait Trait {}
-    /// impl Trait for dyn Send + Sync {}
-    /// impl Trait for dyn Sync + Send {}
-    /// ```
-    ///
-    /// Obviously, once we made these types be identical, that code causes a coherence
-    /// error and a fairly big headache for us. However, luckily for us, the trait
-    /// `Trait` used in this case is basically a marker trait, and therefore having
-    /// overlapping impls for it is sound.
-    ///
-    /// To handle this, we basically regard the trait as a marker trait, with an additional
-    /// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
-    /// it has the following restrictions:
-    ///
-    /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
-    /// positive impls.
-    /// 2. The trait-ref of both impls must be equal.
-    /// 3. The trait-ref of both impls must be a trait object type consisting only of
-    /// marker traits.
-    /// 4. Neither of the impls can have any where-clauses.
-    ///
-    /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
-    FutureCompatOrderDepTraitObjects,
 }
 
 /// Useful source information about where a desugared associated type for an
@@ -1624,7 +1592,7 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    /// Returns `true` if the impls are the same polarity and the trait either
+    /// Returns `Some` if the impls are the same polarity and the trait either
     /// has no items or is annotated `#[marker]` and prevents item overrides.
     #[instrument(level = "debug", skip(self), ret)]
     pub fn impls_are_allowed_to_overlap(
@@ -1665,18 +1633,6 @@ impl<'tcx> TyCtxt<'tcx> {
             return Some(ImplOverlapKind::Permitted { marker: true });
         }
 
-        if let Some(self_ty1) =
-            self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id1)
-            && let Some(self_ty2) =
-                self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id2)
-        {
-            if self_ty1 == self_ty2 {
-                return Some(ImplOverlapKind::FutureCompatOrderDepTraitObjects);
-            } else {
-                debug!("found {self_ty1:?} != {self_ty2:?}");
-            }
-        }
-
         None
     }
 
@@ -1757,7 +1713,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Gets all attributes.
     ///
-    /// To see if an item has a specific attribute, you should use [`rustc_attr_parsing::find_attr!`] so you can use matching.
+    /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching.
     pub fn get_all_attrs(
         self,
         did: impl Into<DefId>,
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 8eaf0a58f70..71fc38cb7ed 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -80,10 +80,10 @@ trivially_parameterized_over_tcx! {
     rustc_ast::Attribute,
     rustc_ast::DelimArgs,
     rustc_ast::expand::StrippedCfgItem<rustc_hir::def_id::DefIndex>,
-    rustc_attr_parsing::ConstStability,
-    rustc_attr_parsing::DefaultBodyStability,
-    rustc_attr_parsing::Deprecation,
-    rustc_attr_parsing::Stability,
+    rustc_attr_data_structures::ConstStability,
+    rustc_attr_data_structures::DefaultBodyStability,
+    rustc_attr_data_structures::Deprecation,
+    rustc_attr_data_structures::Stability,
     rustc_hir::Constness,
     rustc_hir::Defaultness,
     rustc_hir::Safety,
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
index d70d70a31a4..a29c0116266 100644
--- a/compiler/rustc_mir_build/Cargo.toml
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -28,3 +28,6 @@ rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index fa5db32d913..8e96d46dac2 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -8,7 +8,6 @@
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // The `builder` module used to be named `build`, but that was causing GitHub's
diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml
index 293bcbef21b..a171f9641bb 100644
--- a/compiler/rustc_mir_dataflow/Cargo.toml
+++ b/compiler/rustc_mir_dataflow/Cargo.toml
@@ -21,3 +21,6 @@ rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index a8a56baa1ff..a0efc623b8e 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -7,7 +7,6 @@
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_middle::ty;
diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
index fb8d0ac5e74..4dc91723f03 100644
--- a/compiler/rustc_mir_transform/Cargo.toml
+++ b/compiler/rustc_mir_transform/Cargo.toml
@@ -30,3 +30,6 @@ rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 8aa14d15644..739cee5d7f4 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(never_type)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use hir::ConstContext;
diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml
index 36b76d261de..51be8e55fa7 100644
--- a/compiler/rustc_monomorphize/Cargo.toml
+++ b/compiler/rustc_monomorphize/Cargo.toml
@@ -22,3 +22,6 @@ serde = "1"
 serde_json = "1"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index 714b64b3a23..8f6914f3d72 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -4,7 +4,6 @@
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(let_chains)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_hir::lang_items::LangItem;
diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml
index 63aa60f2f26..e119d23d41a 100644
--- a/compiler/rustc_next_trait_solver/Cargo.toml
+++ b/compiler/rustc_next_trait_solver/Cargo.toml
@@ -24,3 +24,6 @@ nightly = [
     "rustc_index/nightly",
     "rustc_type_ir/nightly",
 ]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index d67ae2550d9..f6963a79067 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -6,7 +6,6 @@
 
 // tidy-alphabetical-start
 #![allow(rustc::usage_of_type_ir_inherent)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod canonicalizer;
diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml
index c9dcab0c871..b78ac197dbb 100644
--- a/compiler/rustc_parse/Cargo.toml
+++ b/compiler/rustc_parse/Cargo.toml
@@ -26,3 +26,5 @@ unicode-width = "0.2.0"
 [dev-dependencies]
 termcolor = "1.2"
 
+[lints]
+workspace = true
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 1a104ff5e33..2edc8c83017 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(string_from_utf8_lossy_owned)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs
index 110546d0ba6..886438fd583 100644
--- a/compiler/rustc_parse/src/parser/token_type.rs
+++ b/compiler/rustc_parse/src/parser/token_type.rs
@@ -619,7 +619,7 @@ impl Iterator for TokenTypeSetIter {
     type Item = TokenType;
 
     fn next(&mut self) -> Option<TokenType> {
-        let num_bits: u32 = (std::mem::size_of_val(&self.0.0) * 8) as u32;
+        let num_bits: u32 = (size_of_val(&self.0.0) * 8) as u32;
         assert_eq!(num_bits, 128);
         let z = self.0.0.trailing_zeros();
         if z == num_bits {
diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml
index a39cca716d2..a720903097a 100644
--- a/compiler/rustc_parse_format/Cargo.toml
+++ b/compiler/rustc_parse_format/Cargo.toml
@@ -8,3 +8,6 @@ edition = "2024"
 rustc_index = { path = "../rustc_index", default-features = false }
 rustc_lexer = { path = "../rustc_lexer" }
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 3b985621b57..287bd8678da 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -13,7 +13,6 @@
     html_playground_url = "https://play.rust-lang.org/",
     test(attr(deny(warnings)))
 )]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub use Alignment::*;
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
index ba81ef3103b..4cd7fde6034 100644
--- a/compiler/rustc_passes/Cargo.toml
+++ b/compiler/rustc_passes/Cargo.toml
@@ -26,3 +26,6 @@ rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 844f74372de..1278e98afcf 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -107,12 +107,12 @@ impl<'k> StatCollector<'k> {
 
         let node = self.nodes.entry(label1).or_insert(Node::new());
         node.stats.count += 1;
-        node.stats.size = std::mem::size_of_val(val);
+        node.stats.size = size_of_val(val);
 
         if let Some(label2) = label2 {
             let subnode = node.subnodes.entry(label2).or_insert(NodeStats::new());
             subnode.count += 1;
-            subnode.size = std::mem::size_of_val(val);
+            subnode.size = size_of_val(val);
         }
     }
 
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 1aa077ad2bb..93ff0f66d69 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(map_try_insert)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_passes/src/liveness/rwu_table.rs b/compiler/rustc_passes/src/liveness/rwu_table.rs
index 6e2f976e5b0..4c1f6ea141e 100644
--- a/compiler/rustc_passes/src/liveness/rwu_table.rs
+++ b/compiler/rustc_passes/src/liveness/rwu_table.rs
@@ -39,7 +39,7 @@ impl RWUTable {
     /// Size of packed RWU in bits.
     const RWU_BITS: usize = 4;
     /// Size of a word in bits.
-    const WORD_BITS: usize = std::mem::size_of::<u8>() * 8;
+    const WORD_BITS: usize = size_of::<u8>() * 8;
     /// Number of packed RWUs that fit into a single word.
     const WORD_RWU_COUNT: usize = Self::WORD_BITS / Self::RWU_BITS;
 
diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml
index 40d549630ac..0624fe96cd9 100644
--- a/compiler/rustc_pattern_analysis/Cargo.toml
+++ b/compiler/rustc_pattern_analysis/Cargo.toml
@@ -43,3 +43,6 @@ rustc = [
     "smallvec/may_dangle",
     "rustc_index/nightly",
 ]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index a3400ebb799..eeea724a29b 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -6,7 +6,6 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 #![cfg_attr(feature = "rustc", feature(let_chains))]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod constructor;
diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs
index 365bc2d863f..8980b644f59 100644
--- a/compiler/rustc_pattern_analysis/tests/common/mod.rs
+++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs
@@ -5,7 +5,7 @@ use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport};
 use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField};
 
 /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup.
-pub fn init_tracing() {
+fn init_tracing() {
     use tracing_subscriber::Layer;
     use tracing_subscriber::layer::SubscriberExt;
     use tracing_subscriber::util::SubscriberInitExt;
@@ -24,7 +24,7 @@ pub fn init_tracing() {
 /// A simple set of types.
 #[allow(dead_code)]
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub enum Ty {
+pub(super) enum Ty {
     /// Booleans
     Bool,
     /// 8-bit unsigned integers
@@ -41,7 +41,7 @@ pub enum Ty {
 
 /// The important logic.
 impl Ty {
-    pub fn sub_tys(&self, ctor: &Constructor<Cx>) -> Vec<Self> {
+    pub(super) fn sub_tys(&self, ctor: &Constructor<Cx>) -> Vec<Self> {
         use Constructor::*;
         match (ctor, *self) {
             (Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(),
@@ -63,7 +63,7 @@ impl Ty {
         }
     }
 
-    pub fn ctor_set(&self) -> ConstructorSet<Cx> {
+    fn ctor_set(&self) -> ConstructorSet<Cx> {
         match *self {
             Ty::Bool => ConstructorSet::Bool,
             Ty::U8 => ConstructorSet::Integers {
@@ -104,7 +104,7 @@ impl Ty {
         }
     }
 
-    pub fn write_variant_name(
+    fn write_variant_name(
         &self,
         f: &mut std::fmt::Formatter<'_>,
         ctor: &Constructor<Cx>,
@@ -120,7 +120,7 @@ impl Ty {
 }
 
 /// Compute usefulness in our simple context (and set up tracing for easier debugging).
-pub fn compute_match_usefulness<'p>(
+pub(super) fn compute_match_usefulness<'p>(
     arms: &[MatchArm<'p, Cx>],
     ty: Ty,
     scrut_validity: PlaceValidity,
@@ -137,7 +137,7 @@ pub fn compute_match_usefulness<'p>(
 }
 
 #[derive(Debug)]
-pub struct Cx;
+pub(super) struct Cx;
 
 /// The context for pattern analysis. Forwards anything interesting to `Ty` methods.
 impl PatCx for Cx {
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index 242c67d732a..dc00ea8af43 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -18,3 +18,6 @@ rustc_span = { path = "../rustc_span" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 5271d03a6f6..5e3e8d69b60 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod errors;
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index c85156e059e..42f78448151 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -20,3 +20,6 @@ rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 73c205fdb17..40da46a027d 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -8,7 +8,6 @@
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_data_structures::stable_hasher::HashStable;
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 3e8ccb51021..c34d1170f0e 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -25,3 +25,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index bc78878a84a..2c6fd7d494f 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -63,7 +63,7 @@ rustc_index::newtype_index! {
     pub struct SerializedDepNodeIndex {}
 }
 
-const DEP_NODE_SIZE: usize = std::mem::size_of::<SerializedDepNodeIndex>();
+const DEP_NODE_SIZE: usize = size_of::<SerializedDepNodeIndex>();
 /// Amount of padding we need to add to the edge list data so that we can retrieve every
 /// SerializedDepNodeIndex with a fixed-size read then mask.
 const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1;
@@ -175,7 +175,7 @@ impl EdgeHeader {
 
 #[inline]
 fn mask(bits: usize) -> usize {
-    usize::MAX >> ((std::mem::size_of::<usize>() * 8) - bits)
+    usize::MAX >> ((size_of::<usize>() * 8) - bits)
 }
 
 impl SerializedDepGraph {
@@ -208,9 +208,8 @@ impl SerializedDepGraph {
         // for a node with length 64, which means the spilled 1-byte leb128 length is 1 byte of at
         // least (34 byte header + 1 byte len + 64 bytes edge data), which is ~1%. A 2-byte leb128
         // length is about the same fractional overhead and it amortizes for yet greater lengths.
-        let mut edge_list_data = Vec::with_capacity(
-            graph_bytes - node_count * std::mem::size_of::<SerializedNodeHeader<D>>(),
-        );
+        let mut edge_list_data =
+            Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader<D>>());
 
         for _index in 0..node_count {
             // Decode the header for this edge; the header packs together as many of the fixed-size
@@ -300,7 +299,7 @@ struct Unpacked {
 // M..M+N  bytes per index
 // M+N..16 kind
 impl<D: Deps> SerializedNodeHeader<D> {
-    const TOTAL_BITS: usize = std::mem::size_of::<DepKind>() * 8;
+    const TOTAL_BITS: usize = size_of::<DepKind>() * 8;
     const LEN_BITS: usize = Self::TOTAL_BITS - Self::KIND_BITS - Self::WIDTH_BITS;
     const WIDTH_BITS: usize = DEP_NODE_WIDTH_BITS;
     const KIND_BITS: usize = Self::TOTAL_BITS - D::DEP_KIND_MAX.leading_zeros() as usize;
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index ee984095ad8..a546362414c 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(hash_raw_entry)]
 #![feature(let_chains)]
 #![feature(min_specialization)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod cache;
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index f4771f1af2c..8958a3ac304 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -28,3 +28,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 92f5fba1f9b..79479986d07 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2995,7 +2995,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
     }
 
     // HACK(min_const_generics, generic_const_exprs): We
-    // want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
+    // want to keep allowing `[0; size_of::<*mut T>()]`
     // with a future compat lint for now. We do this by adding an
     // additional special case for repeat expressions.
     //
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index ccdca855232..f724ecf76b3 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -20,7 +20,6 @@
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::cell::{Cell, RefCell};
diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml
index 900cd4243b1..e18ed121ca5 100644
--- a/compiler/rustc_sanitizers/Cargo.toml
+++ b/compiler/rustc_sanitizers/Cargo.toml
@@ -15,3 +15,6 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs
index 55be931bcd6..e4792563e71 100644
--- a/compiler/rustc_sanitizers/src/lib.rs
+++ b/compiler/rustc_sanitizers/src/lib.rs
@@ -5,7 +5,6 @@
 
 // tidy-alphabetical-start
 #![feature(let_chains)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod cfi;
diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index 948242352e7..10bfe14abde 100644
--- a/compiler/rustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -16,3 +16,6 @@ thin-vec = "0.2.12"
 rustc_macros = { path = "../rustc_macros" }
 tempfile = "3.2"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs
index aa7c2858466..4a475805697 100644
--- a/compiler/rustc_serialize/src/leb128.rs
+++ b/compiler/rustc_serialize/src/leb128.rs
@@ -7,7 +7,7 @@ use crate::serialize::Decoder;
 /// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type
 pub const fn max_leb128_len<T>() -> usize {
     // The longest LEB128 encoding for an integer uses 7 bits per byte.
-    (std::mem::size_of::<T>() * 8 + 6) / 7
+    (size_of::<T>() * 8 + 6) / 7
 }
 
 /// Returns the length of the longest LEB128 encoding of all supported integer types.
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 9e9b78cfdd5..13c1a273eb8 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -14,7 +14,6 @@
 #![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index a087725d34d..4b2b41ba845 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -37,3 +37,6 @@ features = [
     "Win32_Foundation",
     "Win32_System_LibraryLoader",
 ]
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index ec83761da4a..cc2decc2fe4 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -92,7 +92,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
             if libc::loadquery(
                 libc::L_GETINFO,
                 buffer.as_mut_ptr() as *mut u8,
-                (std::mem::size_of::<libc::ld_info>() * buffer.len()) as u32,
+                (size_of::<libc::ld_info>() * buffer.len()) as u32,
             ) >= 0
             {
                 break;
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index d432e84fdb2..0e19b982a13 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -7,7 +7,6 @@
 // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums
 // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers").
 #![recursion_limit = "256"]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod errors;
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index a11df9a9c9b..d14bff73b8b 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -18,3 +18,6 @@ scoped-tls = "1.0"
 stable_mir = {path = "../stable_mir" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 2215e2f01ad..9f888875306 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -15,7 +15,6 @@
 )]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub mod rustc_internal;
diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml
index 43a2d692577..a6f86151b81 100644
--- a/compiler/rustc_span/Cargo.toml
+++ b/compiler/rustc_span/Cargo.toml
@@ -22,3 +22,6 @@ sha2 = "0.10.1"
 tracing = "0.1"
 unicode-width = "0.2.0"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 798e186a94b..f19d4d9f362 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -32,7 +32,6 @@
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(slice_as_chunks)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 // The code produced by the `Encodable`/`Decodable` derive macros refer to
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
index 90ddf4c8a04..89fe7ef2e40 100644
--- a/compiler/rustc_symbol_mangling/Cargo.toml
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -19,3 +19,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 4312c82815c..269401ef3a2 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -93,7 +93,6 @@
 #![doc(rust_logo)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_hir::def::DefKind;
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 189b19b0286..6a0268cdee7 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -22,3 +22,6 @@ default-features = false
 features = ["elf", "macho"]
 version = "0.36.2"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 7ebe96960ed..a8d7da5692d 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -16,7 +16,6 @@
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
index 1c61e23362a..5def437bd80 100644
--- a/compiler/rustc_trait_selection/Cargo.toml
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -26,3 +26,6 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index b235d0da83c..b18fb0fb8fd 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -31,7 +31,6 @@
 #![feature(unwrap_infallible)]
 #![feature(yeet_expr)]
 #![recursion_limit = "512"] // For rustdoc
-#![warn(unreachable_pub)] // For rustdoc
 // tidy-alphabetical-end
 
 pub mod error_reporting;
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 75f53b063d1..39333082acd 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -2,7 +2,7 @@
 //!
 //! For concrete constants, this is fairly simple as we can just try and evaluate it.
 //!
-//! When dealing with polymorphic constants, for example `std::mem::size_of::<T>() - 1`,
+//! When dealing with polymorphic constants, for example `size_of::<T>() - 1`,
 //! this is not as easy.
 //!
 //! In this case we try to build an abstract representation of this constant using
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 77dbb43465e..0a54b8468fe 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1925,9 +1925,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         let mut impl_candidate = None;
         for c in impls {
             if let Some(prev) = impl_candidate.replace(c) {
-                if self.prefer_lhs_over_victim(has_non_region_infer, c, prev) {
+                if self.prefer_lhs_over_victim(has_non_region_infer, c, prev.0) {
                     // Ok, prefer `c` over the previous entry
-                } else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c) {
+                } else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c.0) {
                     // Ok, keep `prev` instead of the new entry
                     impl_candidate = Some(prev);
                 } else {
@@ -1986,7 +1986,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         &self,
         has_non_region_infer: bool,
         (lhs, lhs_evaluation): (DefId, EvaluationResult),
-        (victim, victim_evaluation): (DefId, EvaluationResult),
+        victim: DefId,
     ) -> bool {
         let tcx = self.tcx();
         // See if we can toss out `victim` based on specialization.
@@ -2002,14 +2002,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         }
 
         match tcx.impls_are_allowed_to_overlap(lhs, victim) {
-            // For #33140 the impl headers must be exactly equal, the trait must not have
-            // any associated items and there are no where-clauses.
-            //
-            // We can just arbitrarily drop one of the impls.
-            Some(ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects) => {
-                assert_eq!(lhs_evaluation, victim_evaluation);
-                true
-            }
             // For candidates which already reference errors it doesn't really
             // matter what we do 🤷
             Some(ty::ImplOverlapKind::Permitted { marker: false }) => {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index cb3e81f5477..448ac558cad 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -20,7 +20,7 @@ use rustc_middle::bug;
 use rustc_middle::query::LocalCrate;
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
-use rustc_session::lint::builtin::{COHERENCE_LEAK_CHECK, ORDER_DEPENDENT_TRAIT_OBJECTS};
+use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
 use rustc_type_ir::solve::NoSolution;
 use specialization_graph::GraphExt;
@@ -557,13 +557,9 @@ fn report_conflicting_impls<'tcx>(
 
     let msg = || {
         format!(
-            "conflicting implementations of trait `{}`{}{}",
+            "conflicting implementations of trait `{}`{}",
             overlap.trait_ref.print_trait_sugared(),
             overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
-            match used_to_be_allowed {
-                Some(FutureCompatOverlapErrorKind::OrderDepTraitObjects) => ": (E0119)",
-                _ => "",
-            }
         )
     };
 
@@ -588,7 +584,6 @@ fn report_conflicting_impls<'tcx>(
         }
         Some(kind) => {
             let lint = match kind {
-                FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS,
                 FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
             };
             tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index 19d3561dd59..9452dca9a4f 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -12,7 +12,6 @@ use crate::traits;
 
 #[derive(Copy, Clone, Debug)]
 pub enum FutureCompatOverlapErrorKind {
-    OrderDepTraitObjects,
     LeakCheck,
 }
 
@@ -151,12 +150,6 @@ impl<'tcx> Children {
                 {
                     match overlap_kind {
                         ty::ImplOverlapKind::Permitted { marker: _ } => {}
-                        ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects => {
-                            *last_lint_mut = Some(FutureCompatOverlapError {
-                                error: create_overlap_error(overlap),
-                                kind: FutureCompatOverlapErrorKind::OrderDepTraitObjects,
-                            });
-                        }
                     }
 
                     return Ok((false, false));
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
index 04aef4e7b9e..49bcaae8571 100644
--- a/compiler/rustc_traits/Cargo.toml
+++ b/compiler/rustc_traits/Cargo.toml
@@ -13,3 +13,6 @@ rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index d2f979bd6d9..697c8391803 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -2,7 +2,6 @@
 
 // tidy-alphabetical-start
 #![recursion_limit = "256"]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 mod codegen;
diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml
index f0c783b3002..ae1beb10728 100644
--- a/compiler/rustc_transmute/Cargo.toml
+++ b/compiler/rustc_transmute/Cargo.toml
@@ -25,3 +25,6 @@ rustc = [
 # tidy-alphabetical-start
 itertools = "0.12"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 81a11f7cfb2..00928137d29 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -1,6 +1,5 @@
 // tidy-alphabetical-start
 #![feature(never_type)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set};
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index 4c7a57f2931..61acc12d0eb 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -23,3 +23,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index a53f0538c58..5a4bb2c95da 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -1,31 +1,25 @@
-use std::fmt::Debug;
-use std::iter;
-
 use hir::def_id::DefId;
 use rustc_abi::Integer::{I8, I32};
 use rustc_abi::Primitive::{self, Float, Int, Pointer};
 use rustc_abi::{
-    AbiAndPrefAlign, AddressSpace, Align, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape,
-    HasDataLayout, Layout, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size,
-    StructKind, TagEncoding, VariantIdx, Variants, WrappingRange,
+    AddressSpace, BackendRepr, FIRST_VARIANT, FieldIdx, FieldsShape, HasDataLayout, Layout,
+    LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding,
+    VariantIdx, Variants, WrappingRange,
 };
 use rustc_hashes::Hash64;
-use rustc_index::bit_set::DenseBitSet;
-use rustc_index::{IndexSlice, IndexVec};
+use rustc_index::IndexVec;
 use rustc_middle::bug;
-use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{
-    FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, MAX_SIMD_LANES, TyAndLayout,
+    FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout,
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
-    self, AdtDef, CoroutineArgsExt, EarlyBinder, GenericArgsRef, PseudoCanonicalInput, Ty, TyCtxt,
-    TypeVisitableExt,
+    self, AdtDef, CoroutineArgsExt, EarlyBinder, PseudoCanonicalInput, Ty, TyCtxt, TypeVisitableExt,
 };
 use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use rustc_span::{Symbol, sym};
-use tracing::{debug, instrument, trace};
+use tracing::{debug, instrument};
 use {rustc_abi as abi, rustc_hir as hir};
 
 use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};
@@ -124,20 +118,23 @@ fn map_error<'tcx>(
                 .delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
             LayoutError::ReferencesError(guar)
         }
+        LayoutCalculatorError::ZeroLengthSimdType => {
+            // Can't be caught in typeck if the array length is generic.
+            cx.tcx().dcx().emit_fatal(ZeroLengthSimdType { ty })
+        }
+        LayoutCalculatorError::OversizedSimdType { max_lanes } => {
+            // Can't be caught in typeck if the array length is generic.
+            cx.tcx().dcx().emit_fatal(OversizedSimdType { ty, max_lanes })
+        }
+        LayoutCalculatorError::NonPrimitiveSimdType(field) => {
+            // This error isn't caught in typeck, e.g., if
+            // the element type of the vector is generic.
+            cx.tcx().dcx().emit_fatal(NonPrimitiveSimdType { ty, e_ty: field.ty })
+        }
     };
     error(cx, err)
 }
 
-fn univariant_uninterned<'tcx>(
-    cx: &LayoutCx<'tcx>,
-    ty: Ty<'tcx>,
-    fields: &IndexSlice<FieldIdx, TyAndLayout<'tcx>>,
-    kind: StructKind,
-) -> Result<LayoutData<FieldIdx, VariantIdx>, &'tcx LayoutError<'tcx>> {
-    let repr = ReprOptions::default();
-    cx.calc.univariant(fields, &repr, kind).map_err(|err| map_error(cx, ty, err))
-}
-
 fn extract_const_value<'tcx>(
     cx: &LayoutCx<'tcx>,
     ty: Ty<'tcx>,
@@ -188,6 +185,10 @@ fn layout_of_uncached<'tcx>(
 
     let tcx = cx.tcx();
     let dl = cx.data_layout();
+    let map_layout = |result: Result<_, _>| match result {
+        Ok(layout) => Ok(tcx.mk_layout(layout)),
+        Err(err) => Err(map_error(cx, ty, err)),
+    };
     let scalar_unit = |value: Primitive| {
         let size = value.size(dl);
         assert!(size.bits() <= 128);
@@ -195,8 +196,10 @@ fn layout_of_uncached<'tcx>(
     };
     let scalar = |value: Primitive| tcx.mk_layout(LayoutData::scalar(cx, scalar_unit(value)));
 
-    let univariant = |fields: &IndexSlice<FieldIdx, TyAndLayout<'tcx>>, kind| {
-        Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, kind)?))
+    let univariant = |tys: &[Ty<'tcx>], kind| {
+        let fields = tys.iter().map(|ty| cx.layout_of(*ty)).try_collect::<IndexVec<_, _>>()?;
+        let repr = ReprOptions::default();
+        map_layout(cx.calc.univariant(&fields, &repr, kind))
     };
     debug_assert!(!ty.has_non_region_infer());
 
@@ -258,7 +261,7 @@ fn layout_of_uncached<'tcx>(
         }
 
         // The never type.
-        ty::Never => tcx.mk_layout(cx.calc.layout_of_never_type()),
+        ty::Never => tcx.mk_layout(LayoutData::never_type(cx)),
 
         // Potentially-wide pointers.
         ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => {
@@ -329,7 +332,7 @@ fn layout_of_uncached<'tcx>(
             };
 
             // Effectively a (ptr, meta) tuple.
-            tcx.mk_layout(cx.calc.scalar_pair(data_ptr, metadata))
+            tcx.mk_layout(LayoutData::scalar_pair(cx, data_ptr, metadata))
         }
 
         ty::Dynamic(_, _, ty::DynStar) => {
@@ -337,7 +340,7 @@ fn layout_of_uncached<'tcx>(
             data.valid_range_mut().start = 0;
             let mut vtable = scalar_unit(Pointer(AddressSpace::DATA));
             vtable.valid_range_mut().start = 1;
-            tcx.mk_layout(cx.calc.scalar_pair(data, vtable))
+            tcx.mk_layout(LayoutData::scalar_pair(cx, data, vtable))
         }
 
         // Arrays and slices.
@@ -347,96 +350,87 @@ fn layout_of_uncached<'tcx>(
                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
             let element = cx.layout_of(element)?;
-            let size = element
-                .size
-                .checked_mul(count, dl)
-                .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
-
-            let abi = BackendRepr::Memory { sized: true };
-
-            let largest_niche = if count != 0 { element.largest_niche } else { None };
-            let uninhabited = if count != 0 { element.uninhabited } else { false };
-
-            tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
-                fields: FieldsShape::Array { stride: element.size, count },
-                backend_repr: abi,
-                largest_niche,
-                uninhabited,
-                align: element.align,
-                size,
-                max_repr_align: None,
-                unadjusted_abi_align: element.align.abi,
-                randomization_seed: element.randomization_seed.wrapping_add(Hash64::new(count)),
-            })
+            map_layout(cx.calc.array_like(&element, Some(count)))?
         }
         ty::Slice(element) => {
             let element = cx.layout_of(element)?;
-            tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
-                fields: FieldsShape::Array { stride: element.size, count: 0 },
-                backend_repr: BackendRepr::Memory { sized: false },
-                largest_niche: None,
-                uninhabited: false,
-                align: element.align,
-                size: Size::ZERO,
-                max_repr_align: None,
-                unadjusted_abi_align: element.align.abi,
-                // adding a randomly chosen value to distinguish slices
-                randomization_seed: element
-                    .randomization_seed
-                    .wrapping_add(Hash64::new(0x2dcba99c39784102)),
-            })
+            map_layout(cx.calc.array_like(&element, None).map(|mut layout| {
+                // a randomly chosen value to distinguish slices
+                layout.randomization_seed = Hash64::new(0x2dcba99c39784102);
+                layout
+            }))?
+        }
+        ty::Str => {
+            let element = scalar(Int(I8, false));
+            map_layout(cx.calc.array_like(&element, None).map(|mut layout| {
+                // another random value
+                layout.randomization_seed = Hash64::new(0xc1325f37d127be22);
+                layout
+            }))?
         }
-        ty::Str => tcx.mk_layout(LayoutData {
-            variants: Variants::Single { index: FIRST_VARIANT },
-            fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
-            backend_repr: BackendRepr::Memory { sized: false },
-            largest_niche: None,
-            uninhabited: false,
-            align: dl.i8_align,
-            size: Size::ZERO,
-            max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
-            // another random value
-            randomization_seed: Hash64::new(0xc1325f37d127be22),
-        }),
 
         // Odd unit types.
-        ty::FnDef(..) => univariant(IndexSlice::empty(), StructKind::AlwaysSized)?,
-        ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => {
-            let mut unit =
-                univariant_uninterned(cx, ty, IndexSlice::empty(), StructKind::AlwaysSized)?;
-            match unit.backend_repr {
-                BackendRepr::Memory { ref mut sized } => *sized = false,
-                _ => bug!(),
-            }
-            tcx.mk_layout(unit)
+        ty::FnDef(..) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => {
+            let sized = matches!(ty.kind(), ty::FnDef(..));
+            tcx.mk_layout(LayoutData::unit(cx, sized))
         }
 
-        ty::Coroutine(def_id, args) => coroutine_layout(cx, ty, def_id, args)?,
+        ty::Coroutine(def_id, args) => {
+            use rustc_middle::ty::layout::PrimitiveExt as _;
+
+            let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else {
+                return Err(error(cx, LayoutError::Unknown(ty)));
+            };
+
+            let local_layouts = info
+                .field_tys
+                .iter()
+                .map(|local| {
+                    let field_ty = EarlyBinder::bind(local.ty);
+                    let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args));
+                    cx.spanned_layout_of(uninit_ty, local.source_info.span)
+                })
+                .try_collect::<IndexVec<_, _>>()?;
 
-        ty::Closure(_, args) => {
-            let tys = args.as_closure().upvar_tys();
-            univariant(
-                &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
-                StructKind::AlwaysSized,
-            )?
+            let prefix_layouts = args
+                .as_coroutine()
+                .prefix_tys()
+                .iter()
+                .map(|ty| cx.layout_of(ty))
+                .try_collect::<IndexVec<_, _>>()?;
+
+            let layout = cx
+                .calc
+                .coroutine(
+                    &local_layouts,
+                    prefix_layouts,
+                    &info.variant_fields,
+                    &info.storage_conflicts,
+                    |tag| TyAndLayout {
+                        ty: tag.primitive().to_ty(tcx),
+                        layout: tcx.mk_layout(LayoutData::scalar(cx, tag)),
+                    },
+                )
+                .map(|mut layout| {
+                    // this is similar to how ReprOptions populates its field_shuffle_seed
+                    layout.randomization_seed = tcx.def_path_hash(def_id).0.to_smaller_hash();
+                    debug!("coroutine layout ({:?}): {:#?}", ty, layout);
+                    layout
+                });
+            map_layout(layout)?
         }
 
+        ty::Closure(_, args) => univariant(args.as_closure().upvar_tys(), StructKind::AlwaysSized)?,
+
         ty::CoroutineClosure(_, args) => {
-            let tys = args.as_coroutine_closure().upvar_tys();
-            univariant(
-                &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
-                StructKind::AlwaysSized,
-            )?
+            univariant(args.as_coroutine_closure().upvar_tys(), StructKind::AlwaysSized)?
         }
 
         ty::Tuple(tys) => {
             let kind =
                 if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
 
-            univariant(&tys.iter().map(|k| cx.layout_of(k)).try_collect::<IndexVec<_, _>>()?, kind)?
+            univariant(tys, kind)?
         }
 
         // SIMD vector types.
@@ -461,65 +455,9 @@ fn layout_of_uncached<'tcx>(
                 .try_to_target_usize(tcx)
                 .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
-            // SIMD vectors of zero length are not supported.
-            // Additionally, lengths are capped at 2^16 as a fixed maximum backends must
-            // support.
-            //
-            // Can't be caught in typeck if the array length is generic.
-            if e_len == 0 {
-                tcx.dcx().emit_fatal(ZeroLengthSimdType { ty });
-            } else if e_len > MAX_SIMD_LANES {
-                tcx.dcx().emit_fatal(OversizedSimdType { ty, max_lanes: MAX_SIMD_LANES });
-            }
-
-            // Compute the ABI of the element type:
             let e_ly = cx.layout_of(e_ty)?;
-            let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else {
-                // This error isn't caught in typeck, e.g., if
-                // the element type of the vector is generic.
-                tcx.dcx().emit_fatal(NonPrimitiveSimdType { ty, e_ty });
-            };
 
-            // Compute the size and alignment of the vector:
-            let size = e_ly
-                .size
-                .checked_mul(e_len, dl)
-                .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?;
-
-            let (abi, align) = if def.repr().packed() && !e_len.is_power_of_two() {
-                // Non-power-of-two vectors have padding up to the next power-of-two.
-                // If we're a packed repr, remove the padding while keeping the alignment as close
-                // to a vector as possible.
-                (
-                    BackendRepr::Memory { sized: true },
-                    AbiAndPrefAlign {
-                        abi: Align::max_aligned_factor(size),
-                        pref: dl.llvmlike_vector_align(size).pref,
-                    },
-                )
-            } else {
-                (
-                    BackendRepr::SimdVector { element: e_abi, count: e_len },
-                    dl.llvmlike_vector_align(size),
-                )
-            };
-            let size = size.align_to(align.abi);
-
-            tcx.mk_layout(LayoutData {
-                variants: Variants::Single { index: FIRST_VARIANT },
-                fields: FieldsShape::Arbitrary {
-                    offsets: [Size::ZERO].into(),
-                    memory_index: [0].into(),
-                },
-                backend_repr: abi,
-                largest_niche: e_ly.largest_niche,
-                uninhabited: false,
-                size,
-                align,
-                max_repr_align: None,
-                unadjusted_abi_align: align.abi,
-                randomization_seed: e_ly.randomization_seed.wrapping_add(Hash64::new(e_len)),
-            })
+            map_layout(cx.calc.simd_type(e_ly, e_len, def.repr().packed()))?
         }
 
         // ADTs.
@@ -545,11 +483,7 @@ fn layout_of_uncached<'tcx>(
                     return Err(error(cx, LayoutError::ReferencesError(guar)));
                 }
 
-                return Ok(tcx.mk_layout(
-                    cx.calc
-                        .layout_of_union(&def.repr(), &variants)
-                        .map_err(|err| map_error(cx, ty, err))?,
-                ));
+                return map_layout(cx.calc.layout_of_union(&def.repr(), &variants));
             }
 
             let get_discriminant_type =
@@ -677,335 +611,6 @@ fn layout_of_uncached<'tcx>(
     })
 }
 
-/// Overlap eligibility and variant assignment for each CoroutineSavedLocal.
-#[derive(Clone, Debug, PartialEq)]
-enum SavedLocalEligibility {
-    Unassigned,
-    Assigned(VariantIdx),
-    Ineligible(Option<FieldIdx>),
-}
-
-// When laying out coroutines, we divide our saved local fields into two
-// categories: overlap-eligible and overlap-ineligible.
-//
-// Those fields which are ineligible for overlap go in a "prefix" at the
-// beginning of the layout, and always have space reserved for them.
-//
-// Overlap-eligible fields are only assigned to one variant, so we lay
-// those fields out for each variant and put them right after the
-// prefix.
-//
-// Finally, in the layout details, we point to the fields from the
-// variants they are assigned to. It is possible for some fields to be
-// included in multiple variants. No field ever "moves around" in the
-// layout; its offset is always the same.
-//
-// Also included in the layout are the upvars and the discriminant.
-// These are included as fields on the "outer" layout; they are not part
-// of any variant.
-
-/// Compute the eligibility and assignment of each local.
-fn coroutine_saved_local_eligibility(
-    info: &CoroutineLayout<'_>,
-) -> (DenseBitSet<CoroutineSavedLocal>, IndexVec<CoroutineSavedLocal, SavedLocalEligibility>) {
-    use SavedLocalEligibility::*;
-
-    let mut assignments: IndexVec<CoroutineSavedLocal, SavedLocalEligibility> =
-        IndexVec::from_elem(Unassigned, &info.field_tys);
-
-    // The saved locals not eligible for overlap. These will get
-    // "promoted" to the prefix of our coroutine.
-    let mut ineligible_locals = DenseBitSet::new_empty(info.field_tys.len());
-
-    // Figure out which of our saved locals are fields in only
-    // one variant. The rest are deemed ineligible for overlap.
-    for (variant_index, fields) in info.variant_fields.iter_enumerated() {
-        for local in fields {
-            match assignments[*local] {
-                Unassigned => {
-                    assignments[*local] = Assigned(variant_index);
-                }
-                Assigned(idx) => {
-                    // We've already seen this local at another suspension
-                    // point, so it is no longer a candidate.
-                    trace!(
-                        "removing local {:?} in >1 variant ({:?}, {:?})",
-                        local, variant_index, idx
-                    );
-                    ineligible_locals.insert(*local);
-                    assignments[*local] = Ineligible(None);
-                }
-                Ineligible(_) => {}
-            }
-        }
-    }
-
-    // Next, check every pair of eligible locals to see if they
-    // conflict.
-    for local_a in info.storage_conflicts.rows() {
-        let conflicts_a = info.storage_conflicts.count(local_a);
-        if ineligible_locals.contains(local_a) {
-            continue;
-        }
-
-        for local_b in info.storage_conflicts.iter(local_a) {
-            // local_a and local_b are storage live at the same time, therefore they
-            // cannot overlap in the coroutine layout. The only way to guarantee
-            // this is if they are in the same variant, or one is ineligible
-            // (which means it is stored in every variant).
-            if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] {
-                continue;
-            }
-
-            // If they conflict, we will choose one to make ineligible.
-            // This is not always optimal; it's just a greedy heuristic that
-            // seems to produce good results most of the time.
-            let conflicts_b = info.storage_conflicts.count(local_b);
-            let (remove, other) =
-                if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) };
-            ineligible_locals.insert(remove);
-            assignments[remove] = Ineligible(None);
-            trace!("removing local {:?} due to conflict with {:?}", remove, other);
-        }
-    }
-
-    // Count the number of variants in use. If only one of them, then it is
-    // impossible to overlap any locals in our layout. In this case it's
-    // always better to make the remaining locals ineligible, so we can
-    // lay them out with the other locals in the prefix and eliminate
-    // unnecessary padding bytes.
-    {
-        let mut used_variants = DenseBitSet::new_empty(info.variant_fields.len());
-        for assignment in &assignments {
-            if let Assigned(idx) = assignment {
-                used_variants.insert(*idx);
-            }
-        }
-        if used_variants.count() < 2 {
-            for assignment in assignments.iter_mut() {
-                *assignment = Ineligible(None);
-            }
-            ineligible_locals.insert_all();
-        }
-    }
-
-    // Write down the order of our locals that will be promoted to the prefix.
-    {
-        for (idx, local) in ineligible_locals.iter().enumerate() {
-            assignments[local] = Ineligible(Some(FieldIdx::from_usize(idx)));
-        }
-    }
-    debug!("coroutine saved local assignments: {:?}", assignments);
-
-    (ineligible_locals, assignments)
-}
-
-/// Compute the full coroutine layout.
-fn coroutine_layout<'tcx>(
-    cx: &LayoutCx<'tcx>,
-    ty: Ty<'tcx>,
-    def_id: hir::def_id::DefId,
-    args: GenericArgsRef<'tcx>,
-) -> Result<Layout<'tcx>, &'tcx LayoutError<'tcx>> {
-    use SavedLocalEligibility::*;
-    let tcx = cx.tcx();
-    let instantiate_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args);
-
-    let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else {
-        return Err(error(cx, LayoutError::Unknown(ty)));
-    };
-    let (ineligible_locals, assignments) = coroutine_saved_local_eligibility(info);
-
-    // Build a prefix layout, including "promoting" all ineligible
-    // locals as part of the prefix. We compute the layout of all of
-    // these fields at once to get optimal packing.
-    let tag_index = args.as_coroutine().prefix_tys().len();
-
-    // `info.variant_fields` already accounts for the reserved variants, so no need to add them.
-    let max_discr = (info.variant_fields.len() - 1) as u128;
-    let discr_int = abi::Integer::fit_unsigned(max_discr);
-    let tag = Scalar::Initialized {
-        value: Primitive::Int(discr_int, /* signed = */ false),
-        valid_range: WrappingRange { start: 0, end: max_discr },
-    };
-    let tag_layout = TyAndLayout {
-        ty: discr_int.to_ty(tcx, /* signed = */ false),
-        layout: tcx.mk_layout(LayoutData::scalar(cx, tag)),
-    };
-
-    let promoted_layouts = ineligible_locals.iter().map(|local| {
-        let field_ty = instantiate_field(info.field_tys[local].ty);
-        let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty);
-        cx.spanned_layout_of(uninit_ty, info.field_tys[local].source_info.span)
-    });
-    let prefix_layouts = args
-        .as_coroutine()
-        .prefix_tys()
-        .iter()
-        .map(|ty| cx.layout_of(ty))
-        .chain(iter::once(Ok(tag_layout)))
-        .chain(promoted_layouts)
-        .try_collect::<IndexVec<_, _>>()?;
-    let prefix = univariant_uninterned(cx, ty, &prefix_layouts, StructKind::AlwaysSized)?;
-
-    let (prefix_size, prefix_align) = (prefix.size, prefix.align);
-
-    // Split the prefix layout into the "outer" fields (upvars and
-    // discriminant) and the "promoted" fields. Promoted fields will
-    // get included in each variant that requested them in
-    // CoroutineLayout.
-    debug!("prefix = {:#?}", prefix);
-    let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
-        FieldsShape::Arbitrary { mut offsets, memory_index } => {
-            let mut inverse_memory_index = memory_index.invert_bijective_mapping();
-
-            // "a" (`0..b_start`) and "b" (`b_start..`) correspond to
-            // "outer" and "promoted" fields respectively.
-            let b_start = FieldIdx::from_usize(tag_index + 1);
-            let offsets_b = IndexVec::from_raw(offsets.raw.split_off(b_start.as_usize()));
-            let offsets_a = offsets;
-
-            // Disentangle the "a" and "b" components of `inverse_memory_index`
-            // by preserving the order but keeping only one disjoint "half" each.
-            // FIXME(eddyb) build a better abstraction for permutations, if possible.
-            let inverse_memory_index_b: IndexVec<u32, FieldIdx> = inverse_memory_index
-                .iter()
-                .filter_map(|&i| i.as_u32().checked_sub(b_start.as_u32()).map(FieldIdx::from_u32))
-                .collect();
-            inverse_memory_index.raw.retain(|&i| i < b_start);
-            let inverse_memory_index_a = inverse_memory_index;
-
-            // Since `inverse_memory_index_{a,b}` each only refer to their
-            // respective fields, they can be safely inverted
-            let memory_index_a = inverse_memory_index_a.invert_bijective_mapping();
-            let memory_index_b = inverse_memory_index_b.invert_bijective_mapping();
-
-            let outer_fields =
-                FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
-            (outer_fields, offsets_b, memory_index_b)
-        }
-        _ => bug!(),
-    };
-
-    let mut size = prefix.size;
-    let mut align = prefix.align;
-    let variants = info
-        .variant_fields
-        .iter_enumerated()
-        .map(|(index, variant_fields)| {
-            // Only include overlap-eligible fields when we compute our variant layout.
-            let variant_only_tys = variant_fields
-                .iter()
-                .filter(|local| match assignments[**local] {
-                    Unassigned => bug!(),
-                    Assigned(v) if v == index => true,
-                    Assigned(_) => bug!("assignment does not match variant"),
-                    Ineligible(_) => false,
-                })
-                .map(|local| {
-                    let field_ty = instantiate_field(info.field_tys[*local].ty);
-                    Ty::new_maybe_uninit(tcx, field_ty)
-                });
-
-            let mut variant = univariant_uninterned(
-                cx,
-                ty,
-                &variant_only_tys.map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
-                StructKind::Prefixed(prefix_size, prefix_align.abi),
-            )?;
-            variant.variants = Variants::Single { index };
-
-            let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else {
-                bug!();
-            };
-
-            // Now, stitch the promoted and variant-only fields back together in
-            // the order they are mentioned by our CoroutineLayout.
-            // Because we only use some subset (that can differ between variants)
-            // of the promoted fields, we can't just pick those elements of the
-            // `promoted_memory_index` (as we'd end up with gaps).
-            // So instead, we build an "inverse memory_index", as if all of the
-            // promoted fields were being used, but leave the elements not in the
-            // subset as `INVALID_FIELD_IDX`, which we can filter out later to
-            // obtain a valid (bijective) mapping.
-            const INVALID_FIELD_IDX: FieldIdx = FieldIdx::MAX;
-            debug_assert!(variant_fields.next_index() <= INVALID_FIELD_IDX);
-
-            let mut combined_inverse_memory_index = IndexVec::from_elem_n(
-                INVALID_FIELD_IDX,
-                promoted_memory_index.len() + memory_index.len(),
-            );
-            let mut offsets_and_memory_index = iter::zip(offsets, memory_index);
-            let combined_offsets = variant_fields
-                .iter_enumerated()
-                .map(|(i, local)| {
-                    let (offset, memory_index) = match assignments[*local] {
-                        Unassigned => bug!(),
-                        Assigned(_) => {
-                            let (offset, memory_index) = offsets_and_memory_index.next().unwrap();
-                            (offset, promoted_memory_index.len() as u32 + memory_index)
-                        }
-                        Ineligible(field_idx) => {
-                            let field_idx = field_idx.unwrap();
-                            (promoted_offsets[field_idx], promoted_memory_index[field_idx])
-                        }
-                    };
-                    combined_inverse_memory_index[memory_index] = i;
-                    offset
-                })
-                .collect();
-
-            // Remove the unused slots and invert the mapping to obtain the
-            // combined `memory_index` (also see previous comment).
-            combined_inverse_memory_index.raw.retain(|&i| i != INVALID_FIELD_IDX);
-            let combined_memory_index = combined_inverse_memory_index.invert_bijective_mapping();
-
-            variant.fields = FieldsShape::Arbitrary {
-                offsets: combined_offsets,
-                memory_index: combined_memory_index,
-            };
-
-            size = size.max(variant.size);
-            align = align.max(variant.align);
-            Ok(variant)
-        })
-        .try_collect::<IndexVec<VariantIdx, _>>()?;
-
-    size = size.align_to(align.abi);
-
-    let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited());
-    let abi = BackendRepr::Memory { sized: true };
-
-    // this is similar to how ReprOptions populates its field_shuffle_seed
-    let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash();
-
-    let layout = tcx.mk_layout(LayoutData {
-        variants: Variants::Multiple {
-            tag,
-            tag_encoding: TagEncoding::Direct,
-            tag_field: tag_index,
-            variants,
-        },
-        fields: outer_fields,
-        backend_repr: abi,
-        // Suppress niches inside coroutines. If the niche is inside a field that is aliased (due to
-        // self-referentiality), getting the discriminant can cause aliasing violations.
-        // `UnsafeCell` blocks niches for the same reason, but we don't yet have `UnsafePinned` that
-        // would do the same for us here.
-        // See <https://github.com/rust-lang/rust/issues/63818>, <https://github.com/rust-lang/miri/issues/3780>.
-        // FIXME: Remove when <https://github.com/rust-lang/rust/issues/125735> is implemented and aliased coroutine fields are wrapped in `UnsafePinned`.
-        largest_niche: None,
-        uninhabited,
-        size,
-        align,
-        max_repr_align: None,
-        unadjusted_abi_align: align.abi,
-        randomization_seed: def_hash,
-    });
-    debug!("coroutine layout ({:?}): {:#?}", ty, layout);
-    Ok(layout)
-}
-
 fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) {
     // Ignore layouts that are done with non-empty environments or
     // non-monomorphic layouts, as the user only wants to see the stuff
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 8be1611bb9a..35cc6f39856 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -16,7 +16,6 @@
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustdoc_internals)]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 8610c30ab70..bb61f4bee66 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -6,13 +6,11 @@ use rustc_index::bit_set::DenseBitSet;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::fold::fold_regions;
-use rustc_middle::ty::{
-    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
-};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast};
 use rustc_span::DUMMY_SP;
 use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
 use rustc_trait_selection::traits;
-use tracing::{debug, instrument};
+use tracing::instrument;
 
 #[instrument(level = "debug", skip(tcx), ret)]
 fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
@@ -260,57 +258,6 @@ fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty:
     typing_env.with_post_analysis_normalized(tcx).param_env
 }
 
-/// If the given trait impl enables exploiting the former order dependence of trait objects,
-/// returns its self type; otherwise, returns `None`.
-///
-/// See [`ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects`] for more details.
-#[instrument(level = "debug", skip(tcx))]
-fn self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(
-    tcx: TyCtxt<'_>,
-    def_id: DefId,
-) -> Option<EarlyBinder<'_, Ty<'_>>> {
-    let impl_ =
-        tcx.impl_trait_header(def_id).unwrap_or_else(|| bug!("called on inherent impl {def_id:?}"));
-
-    let trait_ref = impl_.trait_ref.skip_binder();
-    debug!(?trait_ref);
-
-    let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive
-        && tcx.associated_item_def_ids(trait_ref.def_id).is_empty();
-
-    // Check whether these impls would be ok for a marker trait.
-    if !is_marker_like {
-        debug!("not marker-like!");
-        return None;
-    }
-
-    // impl must be `impl Trait for dyn Marker1 + Marker2 + ...`
-    if trait_ref.args.len() != 1 {
-        debug!("impl has args!");
-        return None;
-    }
-
-    let predicates = tcx.predicates_of(def_id);
-    if predicates.parent.is_some() || !predicates.predicates.is_empty() {
-        debug!(?predicates, "impl has predicates!");
-        return None;
-    }
-
-    let self_ty = trait_ref.self_ty();
-    let self_ty_matches = match self_ty.kind() {
-        ty::Dynamic(data, re, _) if re.is_static() => data.principal().is_none(),
-        _ => false,
-    };
-
-    if self_ty_matches {
-        debug!("MATCHES!");
-        Some(EarlyBinder::bind(self_ty))
-    } else {
-        debug!("non-matching self type");
-        None
-    }
-}
-
 /// Check if a function is async.
 fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Asyncness {
     let node = tcx.hir_node_by_def_id(def_id);
@@ -370,7 +317,6 @@ pub(crate) fn provide(providers: &mut Providers) {
         adt_sized_constraint,
         param_env,
         param_env_normalized_for_post_analysis,
-        self_ty_of_trait_impl_enabling_order_dep_trait_object_hack,
         defaultness,
         unsizing_params_for_adt,
         ..*providers
diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml
index 7b2593b96e3..0381797d7e9 100644
--- a/compiler/rustc_type_ir/Cargo.toml
+++ b/compiler/rustc_type_ir/Cargo.toml
@@ -34,5 +34,5 @@ nightly = [
     "rustc_ast_ir/nightly",
 ]
 
-[lints.rust]
-unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] }
+[lints]
+workspace = true
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 15ef4e7d6c1..e2dfd9173fa 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -6,7 +6,6 @@
     feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
 )]
 #![cfg_attr(feature = "nightly", allow(internal_features))]
-#![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
 extern crate self as rustc_type_ir;
diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml
index 15a55575099..a3fa4623855 100644
--- a/compiler/rustc_type_ir_macros/Cargo.toml
+++ b/compiler/rustc_type_ir_macros/Cargo.toml
@@ -13,3 +13,6 @@ quote = "1"
 syn = { version = "2.0.9", features = ["full"] }
 synstructure = "0.13.0"
 # tidy-alphabetical-end
+
+[lints]
+workspace = true
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
index d691a0e4f22..358a3915402 100644
--- a/compiler/stable_mir/Cargo.toml
+++ b/compiler/stable_mir/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2024"
 [dependencies]
 scoped-tls = "1.0"
 serde = { version = "1.0.125", features = [ "derive" ] }
+
+[lints]
+workspace = true
diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs
index 7e0c4a479b8..023807b76ae 100644
--- a/compiler/stable_mir/src/mir/alloc.rs
+++ b/compiler/stable_mir/src/mir/alloc.rs
@@ -58,7 +58,7 @@ impl IndexedVal for AllocId {
 
 /// Utility function used to read an allocation data into a unassigned integer.
 pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
-    let mut buf = [0u8; std::mem::size_of::<u128>()];
+    let mut buf = [0u8; size_of::<u128>()];
     match MachineInfo::target_endianness() {
         Endian::Little => {
             bytes.read_exact(&mut buf[..bytes.len()])?;
@@ -73,7 +73,7 @@ pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
 
 /// Utility function used to read an allocation data into an assigned integer.
 pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
-    let mut buf = [0u8; std::mem::size_of::<i128>()];
+    let mut buf = [0u8; size_of::<i128>()];
     match MachineInfo::target_endianness() {
         Endian::Little => {
             bytes.read_exact(&mut buf[..bytes.len()])?;
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 2ba797ab2ad..9236f5cb8d1 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1043,7 +1043,8 @@ impl String {
     #[inline]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     pub const fn into_bytes(self) -> Vec<u8> {
         self.vec
     }
@@ -1061,7 +1062,7 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[rustc_diagnostic_item = "string_as_str"]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_str(&self) -> &str {
         // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
         // at construction.
@@ -1084,7 +1085,7 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[rustc_diagnostic_item = "string_as_mut_str"]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_mut_str(&mut self) -> &mut str {
         // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
         // at construction.
@@ -1158,7 +1159,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn capacity(&self) -> usize {
         self.vec.capacity()
     }
@@ -1424,7 +1425,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_bytes(&self) -> &[u8] {
         self.vec.as_slice()
     }
@@ -1778,7 +1779,7 @@ impl String {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
         &mut self.vec
     }
@@ -1800,7 +1801,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_confusables("length", "size")]
     pub const fn len(&self) -> usize {
         self.vec.len()
@@ -1820,7 +1821,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index ce668540598..da9a77154f9 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1254,7 +1254,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn capacity(&self) -> usize {
         self.buf.capacity()
     }
@@ -1569,7 +1569,7 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[rustc_diagnostic_item = "vec_as_slice"]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_slice(&self) -> &[T] {
         // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
         // `len` containing properly-initialized `T`s. Data must not be mutated for the returned
@@ -1601,7 +1601,7 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[rustc_diagnostic_item = "vec_as_mut_slice"]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_mut_slice(&mut self) -> &mut [T] {
         // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
         // size `len` containing properly-initialized `T`s. Data must not be accessed through any
@@ -1673,7 +1673,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_ptr`]: Vec::as_ptr
     /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_never_returns_null_ptr]
     #[rustc_as_ptr]
     #[inline]
@@ -1736,7 +1736,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_ptr`]: Vec::as_ptr
     /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_never_returns_null_ptr]
     #[rustc_as_ptr]
     #[inline]
@@ -2687,7 +2687,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_confusables("length", "size")]
     pub const fn len(&self) -> usize {
         let len = self.len;
@@ -2713,7 +2713,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_diagnostic_item = "vec_is_empty"]
-    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]
     pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index e8b6a577cea..70789fbbeeb 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -125,6 +125,7 @@ impl Step for Gcc {
         t!(stamp.remove());
         let _time = helpers::timeit(builder);
         t!(fs::create_dir_all(&out_dir));
+        t!(fs::create_dir_all(&install_dir));
 
         let libgccjit_path = libgccjit_built_path(&install_dir);
         if builder.config.dry_run() {
@@ -185,8 +186,16 @@ impl Step for Gcc {
         }
         configure_cmd.run(builder);
 
-        command("make").current_dir(&out_dir).arg(format!("-j{}", builder.jobs())).run(builder);
-        command("make").current_dir(&out_dir).arg("install").run(builder);
+        command("make")
+            .current_dir(&out_dir)
+            .arg("--silent")
+            .arg(format!("-j{}", builder.jobs()))
+            .run_capture_stdout(builder);
+        command("make")
+            .current_dir(&out_dir)
+            .arg("--silent")
+            .arg("install")
+            .run_capture_stdout(builder);
 
         let lib_alias = install_dir.join("lib/libgccjit.so.0");
         if !lib_alias.exists() {
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index fea8232296e..1ef86e674f0 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -367,3 +367,28 @@ impl Step for FeaturesStatusDump {
         cmd.run(builder);
     }
 }
+
+/// Dummy step that can be used to deliberately trigger bootstrap's step cycle
+/// detector, for automated and manual testing.
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct CyclicStep {
+    n: u32,
+}
+
+impl Step for CyclicStep {
+    type Output = ();
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("cyclic-step")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        // Start with n=2, so that we build up a few stack entries before panicking.
+        run.builder.ensure(CyclicStep { n: 2 })
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        // When n=0, the step will try to ensure itself, causing a step cycle.
+        builder.ensure(CyclicStep { n: self.n.saturating_sub(1) })
+    }
+}
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 12dd40d14e9..2cbf82ccda3 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -1072,12 +1072,17 @@ impl Builder<'_> {
         }
 
         if mode == Mode::Rustc {
+            // NOTE: rustc-specific lints are specified here. Normal rust lints
+            // are specified in the `[workspace.lints.rust]` section in the
+            // top-level `Cargo.toml`. If/when tool lints are supported by
+            // Cargo, these lints can be move to a `[workspace.lints.rustc]`
+            // section in the top-level `Cargo.toml`.
+            //
+            // NOTE: these flags are added to RUSTFLAGS, which is ignored when
+            // compiling proc macro crates such as `rustc_macros`,
+            // unfortunately.
             rustflags.arg("-Wrustc::internal");
             rustflags.arg("-Drustc::symbol_intern_string_literal");
-            // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
-            // of the individual lints are satisfied.
-            rustflags.arg("-Wkeyword_idents_2024");
-            rustflags.arg("-Wunsafe_op_in_unsafe_fn");
         }
 
         if self.config.rust_frame_pointers {
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index c24001b749f..8e1cecfcd18 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -50,7 +50,7 @@ pub struct Builder<'a> {
 
     /// A stack of [`Step`]s to run before we can run this builder. The output
     /// of steps is cached in [`Self::cache`].
-    stack: RefCell<Vec<Box<dyn Any>>>,
+    stack: RefCell<Vec<Box<dyn AnyDebug>>>,
 
     /// The total amount of time we spent running [`Step`]s in [`Self::stack`].
     time_spent_on_dependencies: Cell<Duration>,
@@ -69,6 +69,21 @@ impl Deref for Builder<'_> {
     }
 }
 
+/// This trait is similar to `Any`, except that it also exposes the underlying
+/// type's [`Debug`] implementation.
+///
+/// (Trying to debug-print `dyn Any` results in the unhelpful `"Any { .. }"`.)
+trait AnyDebug: Any + Debug {}
+impl<T: Any + Debug> AnyDebug for T {}
+impl dyn AnyDebug {
+    /// Equivalent to `<dyn Any>::downcast_ref`.
+    fn downcast_ref<T: Any>(&self) -> Option<&T> {
+        (self as &dyn Any).downcast_ref()
+    }
+
+    // Feel free to add other `dyn Any` methods as necessary.
+}
+
 pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
     /// Result type of `Step::run`.
     type Output: Clone;
@@ -1102,6 +1117,7 @@ impl<'a> Builder<'a> {
                 run::GenerateCompletions,
                 run::UnicodeTableGenerator,
                 run::FeaturesStatusDump,
+                run::CyclicStep,
             ),
             Kind::Setup => {
                 describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 63a1bbc24f1..e8820e3a828 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1,4 +1,4 @@
-use std::thread;
+use std::{panic, thread};
 
 use llvm::prebuilt_llvm_config;
 
@@ -1135,3 +1135,35 @@ fn test_get_tool_rustc_compiler() {
     let actual = tool::get_tool_rustc_compiler(&builder, compiler);
     assert_eq!(expected, actual);
 }
+
+/// When bootstrap detects a step dependency cycle (which is a bug), its panic
+/// message should show the actual steps on the stack, not just several copies
+/// of `Any { .. }`.
+#[test]
+fn step_cycle_debug() {
+    let cmd = ["run", "cyclic-step"].map(str::to_owned);
+    let config = configure_with_args(&cmd, &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
+
+    let err = panic::catch_unwind(|| run_build(&config.paths.clone(), config)).unwrap_err();
+    let err = err.downcast_ref::<String>().unwrap().as_str();
+
+    assert!(!err.contains("Any"));
+    assert!(err.contains("CyclicStep { n: 1 }"));
+}
+
+/// The `AnyDebug` trait should delegate to the underlying type's `Debug`, and
+/// should also allow downcasting as expected.
+#[test]
+fn any_debug() {
+    #[derive(Debug, PartialEq, Eq)]
+    struct MyStruct {
+        x: u32,
+    }
+
+    let x: &dyn AnyDebug = &MyStruct { x: 7 };
+
+    // Debug-formatting should delegate to the underlying type.
+    assert_eq!(format!("{x:?}"), format!("{:?}", MyStruct { x: 7 }));
+    // Downcasting to the underlying type should succeed.
+    assert_eq!(x.downcast_ref::<MyStruct>(), Some(&MyStruct { x: 7 }));
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
index 7af31dabe45..2ac1792ba86 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -6,16 +6,15 @@ use base_db::ra_salsa::Cycle;
 use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
 use hir_def::{
     layout::{
-        BackendRepr, FieldsShape, Float, Integer, LayoutCalculator, LayoutCalculatorError,
-        LayoutData, Primitive, ReprOptions, Scalar, Size, StructKind, TargetDataLayout,
+        Float, Integer, LayoutCalculator, LayoutCalculatorError,
+        LayoutData, Primitive, ReprOptions, Scalar, StructKind, TargetDataLayout,
         WrappingRange,
     },
     LocalFieldId, StructId,
 };
 use la_arena::{Idx, RawIdx};
 use rustc_abi::AddressSpace;
-use rustc_hashes::Hash64;
-use rustc_index::{IndexSlice, IndexVec};
+use rustc_index::IndexVec;
 
 use triomphe::Arc;
 
@@ -23,7 +22,6 @@ use crate::{
     consteval::try_const_usize,
     db::{HirDatabase, InternedClosure},
     infer::normalize,
-    layout::adt::struct_variant_idx,
     utils::ClosureSubst,
     Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
 };
@@ -125,10 +123,10 @@ impl<'a> LayoutCx<'a> {
     }
 }
 
-// FIXME: move this to the `rustc_abi`.
 fn layout_of_simd_ty(
     db: &dyn HirDatabase,
     id: StructId,
+    repr_packed: bool,
     subst: &Substitution,
     env: Arc<TraitEnvironment>,
     dl: &TargetDataLayout,
@@ -149,33 +147,10 @@ fn layout_of_simd_ty(
     };
 
     let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;
-
-    // Compute the ABI of the element type:
     let e_ly = db.layout_of_ty(e_ty, env)?;
-    let BackendRepr::Scalar(e_abi) = e_ly.backend_repr else {
-        return Err(LayoutError::Unknown);
-    };
 
-    // Compute the size and alignment of the vector:
-    let size = e_ly
-        .size
-        .checked_mul(e_len, dl)
-        .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
-    let align = dl.llvmlike_vector_align(size);
-    let size = size.align_to(align.abi);
-
-    Ok(Arc::new(Layout {
-        variants: Variants::Single { index: struct_variant_idx() },
-        fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() },
-        backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
-        largest_niche: e_ly.largest_niche,
-        uninhabited: false,
-        size,
-        align,
-        max_repr_align: None,
-        unadjusted_abi_align: align.abi,
-        randomization_seed: Hash64::ZERO,
-    }))
+    let cx = LayoutCx::new(dl);
+    Ok(Arc::new(cx.calc.simd_type(e_ly, e_len, repr_packed)?))
 }
 
 pub fn layout_of_ty_query(
@@ -190,13 +165,14 @@ pub fn layout_of_ty_query(
     let dl = &*target;
     let cx = LayoutCx::new(dl);
     let ty = normalize(db, trait_env.clone(), ty);
-    let result = match ty.kind(Interner) {
+    let kind = ty.kind(Interner);
+    let result = match kind {
         TyKind::Adt(AdtId(def), subst) => {
             if let hir_def::AdtId::StructId(s) = def {
                 let data = db.struct_data(*s);
                 let repr = data.repr.unwrap_or_default();
                 if repr.simd() {
-                    return layout_of_simd_ty(db, *s, subst, trait_env, &target);
+                    return layout_of_simd_ty(db, *s, repr.packed(), subst, trait_env, &target);
                 }
             };
             return db.layout_of_adt(*def, subst.clone(), trait_env);
@@ -216,7 +192,7 @@ pub fn layout_of_ty_query(
                     valid_range: WrappingRange { start: 0, end: 0x10FFFF },
                 },
             ),
-            chalk_ir::Scalar::Int(i) => scalar(
+            chalk_ir::Scalar::Int(i) => Layout::scalar(dl, scalar_unit(
                 dl,
                 Primitive::Int(
                     match i {
@@ -229,8 +205,8 @@ pub fn layout_of_ty_query(
                     },
                     true,
                 ),
-            ),
-            chalk_ir::Scalar::Uint(i) => scalar(
+            )),
+            chalk_ir::Scalar::Uint(i) => Layout::scalar(dl, scalar_unit(
                 dl,
                 Primitive::Int(
                     match i {
@@ -243,8 +219,8 @@ pub fn layout_of_ty_query(
                     },
                     false,
                 ),
-            ),
-            chalk_ir::Scalar::Float(f) => scalar(
+            )),
+            chalk_ir::Scalar::Float(f) => Layout::scalar(dl, scalar_unit(
                 dl,
                 Primitive::Float(match f {
                     FloatTy::F16 => Float::F16,
@@ -252,7 +228,7 @@ pub fn layout_of_ty_query(
                     FloatTy::F64 => Float::F64,
                     FloatTy::F128 => Float::F128,
                 }),
-            ),
+            )),
         },
         TyKind::Tuple(len, tys) => {
             let kind = if *len == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
@@ -268,56 +244,16 @@ pub fn layout_of_ty_query(
         TyKind::Array(element, count) => {
             let count = try_const_usize(db, count).ok_or(LayoutError::HasErrorConst)? as u64;
             let element = db.layout_of_ty(element.clone(), trait_env)?;
-            let size = element
-                .size
-                .checked_mul(count, dl)
-                .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?;
-
-            let backend_repr = BackendRepr::Memory { sized: true };
-
-            let largest_niche = if count != 0 { element.largest_niche } else { None };
-            let uninhabited = if count != 0 { element.uninhabited } else { false };
-
-            Layout {
-                variants: Variants::Single { index: struct_variant_idx() },
-                fields: FieldsShape::Array { stride: element.size, count },
-                backend_repr,
-                largest_niche,
-                uninhabited,
-                align: element.align,
-                size,
-                max_repr_align: None,
-                unadjusted_abi_align: element.align.abi,
-                randomization_seed: Hash64::ZERO,
-            }
+            cx.calc.array_like::<_, _, ()>(&element, Some(count))?
         }
         TyKind::Slice(element) => {
             let element = db.layout_of_ty(element.clone(), trait_env)?;
-            Layout {
-                variants: Variants::Single { index: struct_variant_idx() },
-                fields: FieldsShape::Array { stride: element.size, count: 0 },
-                backend_repr: BackendRepr::Memory { sized: false },
-                largest_niche: None,
-                uninhabited: false,
-                align: element.align,
-                size: Size::ZERO,
-                max_repr_align: None,
-                unadjusted_abi_align: element.align.abi,
-                randomization_seed: Hash64::ZERO,
-            }
+            cx.calc.array_like::<_, _, ()>(&element, None)?
+        }
+        TyKind::Str => {
+            let element = scalar_unit(dl, Primitive::Int(Integer::I8, false));
+            cx.calc.array_like::<_, _, ()>(&Layout::scalar(dl, element), None)?
         }
-        TyKind::Str => Layout {
-            variants: Variants::Single { index: struct_variant_idx() },
-            fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
-            backend_repr: BackendRepr::Memory { sized: false },
-            largest_niche: None,
-            uninhabited: false,
-            align: dl.i8_align,
-            size: Size::ZERO,
-            max_repr_align: None,
-            unadjusted_abi_align: dl.i8_align.abi,
-            randomization_seed: Hash64::ZERO,
-        },
         // Potentially-wide pointers.
         TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => {
             let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA));
@@ -355,17 +291,12 @@ pub fn layout_of_ty_query(
             };
 
             // Effectively a (ptr, meta) tuple.
-            cx.calc.scalar_pair(data_ptr, metadata)
+            LayoutData::scalar_pair(dl, data_ptr, metadata)
         }
-        TyKind::FnDef(_, _) => layout_of_unit(&cx)?,
-        TyKind::Never => cx.calc.layout_of_never_type(),
-        TyKind::Dyn(_) | TyKind::Foreign(_) => {
-            let mut unit = layout_of_unit(&cx)?;
-            match &mut unit.backend_repr {
-                BackendRepr::Memory { sized } => *sized = false,
-                _ => return Err(LayoutError::Unknown),
-            }
-            unit
+        TyKind::Never => LayoutData::never_type(dl),
+        TyKind::FnDef(..) | TyKind::Dyn(_) | TyKind::Foreign(_) => {
+            let sized = matches!(kind, TyKind::FnDef(..));
+            LayoutData::unit(dl, sized)
         }
         TyKind::Function(_) => {
             let mut ptr = scalar_unit(dl, Primitive::Pointer(dl.instruction_address_space));
@@ -434,16 +365,6 @@ pub fn layout_of_ty_recover(
     Err(LayoutError::RecursiveTypeWithoutIndirection)
 }
 
-fn layout_of_unit(cx: &LayoutCx<'_>) -> Result<Layout, LayoutError> {
-    cx.calc
-        .univariant::<RustcFieldIdx, RustcEnumVariantIdx, &&Layout>(
-            IndexSlice::empty(),
-            &ReprOptions::default(),
-            StructKind::AlwaysSized,
-        )
-        .map_err(Into::into)
-}
-
 fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
     match pointee.kind(Interner) {
         TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), subst) => {
@@ -474,9 +395,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
     Scalar::Initialized { value, valid_range: WrappingRange::full(value.size(dl)) }
 }
 
-fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
-    Layout::scalar(dl, scalar_unit(dl, value))
-}
-
 #[cfg(test)]
 mod tests;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index 0ba765bd75e..eb4729fab84 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -16,16 +16,12 @@ use triomphe::Arc;
 use crate::{
     db::HirDatabase,
     lang_items::is_unsafe_cell,
-    layout::{field_ty, Layout, LayoutError, RustcEnumVariantIdx},
+    layout::{field_ty, Layout, LayoutError},
     Substitution, TraitEnvironment,
 };
 
 use super::LayoutCx;
 
-pub(crate) fn struct_variant_idx() -> RustcEnumVariantIdx {
-    RustcEnumVariantIdx(0)
-}
-
 pub fn layout_of_adt_query(
     db: &dyn HirDatabase,
     def: AdtId,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 707c4377726..e0dcc01821e 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -12,9 +12,6 @@ extern crate ra_ap_rustc_index as rustc_index;
 #[cfg(feature = "in-rust-tree")]
 extern crate rustc_abi;
 
-#[cfg(feature = "in-rust-tree")]
-extern crate rustc_hashes;
-
 #[cfg(not(feature = "in-rust-tree"))]
 extern crate ra_ap_rustc_abi as rustc_abi;
 
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 9a4d0891b4a..dfdbc0878f2 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -17,6 +17,7 @@ termcolor = "1.1.3"
 rustc-hash = "2.0.0"
 fluent-syntax = "0.11.1"
 similar = "2.5.0"
+toml = "0.7.8"
 
 [features]
 build-metrics = ["dep:serde"]
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 9f6d563166e..66856f5247b 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -87,6 +87,7 @@ pub mod target_policy;
 pub mod target_specific_tests;
 pub mod tests_placement;
 pub mod tests_revision_unpaired_stdout_stderr;
+pub mod triagebot;
 pub mod ui_tests;
 pub mod unit_tests;
 pub mod unknown_revision;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 1d8514ef4c9..bc3519142dd 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -144,6 +144,8 @@ fn main() {
 
         check!(x_version, &root_path, &cargo);
 
+        check!(triagebot, &root_path);
+
         let collected = {
             drain_handles(&mut handles);
 
diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs
new file mode 100644
index 00000000000..7131c16ec30
--- /dev/null
+++ b/src/tools/tidy/src/triagebot.rs
@@ -0,0 +1,93 @@
+//! Tidy check to ensure paths mentioned in triagebot.toml exist in the project.
+
+use std::path::Path;
+
+use toml::Value;
+
+pub fn check(path: &Path, bad: &mut bool) {
+    let triagebot_path = path.join("triagebot.toml");
+    if !triagebot_path.exists() {
+        tidy_error!(bad, "triagebot.toml file not found");
+        return;
+    }
+
+    let contents = std::fs::read_to_string(&triagebot_path).unwrap();
+    let config: Value = toml::from_str(&contents).unwrap();
+
+    // Check [mentions."*"] sections, i.e. [mentions."compiler/rustc_const_eval/src/"]
+    if let Some(Value::Table(mentions)) = config.get("mentions") {
+        for path_str in mentions.keys() {
+            // Remove quotes from the path
+            let clean_path = path_str.trim_matches('"');
+            let full_path = path.join(clean_path);
+
+            if !full_path.exists() {
+                tidy_error!(
+                    bad,
+                    "triagebot.toml [mentions.*] contains path '{}' which doesn't exist",
+                    clean_path
+                );
+            }
+        }
+    } else {
+        tidy_error!(
+            bad,
+            "triagebot.toml missing [mentions.*] section, this wrong for rust-lang/rust repo."
+        );
+    }
+
+    // Check [assign.owners] sections, i.e.
+    // [assign.owners]
+    // "/.github/workflows" = ["infra-ci"]
+    if let Some(Value::Table(assign)) = config.get("assign") {
+        if let Some(Value::Table(owners)) = assign.get("owners") {
+            for path_str in owners.keys() {
+                // Remove quotes and leading slash from the path
+                let clean_path = path_str.trim_matches('"').trim_start_matches('/');
+                let full_path = path.join(clean_path);
+
+                if !full_path.exists() {
+                    tidy_error!(
+                        bad,
+                        "triagebot.toml [assign.owners] contains path '{}' which doesn't exist",
+                        clean_path
+                    );
+                }
+            }
+        } else {
+            tidy_error!(
+                bad,
+                "triagebot.toml missing [assign.owners] section, this wrong for rust-lang/rust repo."
+            );
+        }
+    }
+
+    // Verify that trigger_files in [autolabel."*"] exist in the project, i.e.
+    // [autolabel."A-rustdoc-search"]
+    // trigger_files = [
+    //    "src/librustdoc/html/static/js/search.js",
+    //    "tests/rustdoc-js",
+    //    "tests/rustdoc-js-std",
+    // ]
+    if let Some(Value::Table(autolabels)) = config.get("autolabel") {
+        for (label, content) in autolabels {
+            if let Some(trigger_files) = content.get("trigger_files").and_then(|v| v.as_array()) {
+                for file in trigger_files {
+                    if let Some(file_str) = file.as_str() {
+                        let full_path = path.join(file_str);
+
+                        // Handle both file and directory paths
+                        if !full_path.exists() {
+                            tidy_error!(
+                                bad,
+                                "triagebot.toml [autolabel.{}] contains trigger_files path '{}' which doesn't exist",
+                                label,
+                                file_str
+                            );
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/crashes/136138.rs b/tests/crashes/136138.rs
new file mode 100644
index 00000000000..c3893dc9c8e
--- /dev/null
+++ b/tests/crashes/136138.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #136138
+#![feature(min_generic_const_args)]
+struct U;
+struct S<const N: U>()
+where
+    S<{ U }>:;
+fn main() {}
diff --git a/tests/crashes/136175-2.rs b/tests/crashes/136175-2.rs
new file mode 100644
index 00000000000..28f8ff7fd1c
--- /dev/null
+++ b/tests/crashes/136175-2.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #136175
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+
+struct A<T>(T)
+where
+    [(); std::mem::offset_of!((T,), 0)]:;
+
+fn main() {
+    let x: A<dyn Trait>;
+}
diff --git a/tests/crashes/136175.rs b/tests/crashes/136175.rs
new file mode 100644
index 00000000000..0b5f2fdaa92
--- /dev/null
+++ b/tests/crashes/136175.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #136175
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+
+struct A<T>(T)
+where
+    [(); size_of::<T>()]:;
+
+fn main() {
+    let x: A<dyn Trait>;
+}
diff --git a/tests/crashes/136188.rs b/tests/crashes/136188.rs
new file mode 100644
index 00000000000..a701fc4c0b7
--- /dev/null
+++ b/tests/crashes/136188.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #136188
+//@ compile-flags: --crate-type=lib -Znext-solver
+#![feature(type_alias_impl_trait)]
+
+type Opaque = Box<impl Sized>;
+
+fn define() -> Opaque { Box::new(()) }
+
+impl Copy for Opaque {}
diff --git a/tests/crashes/136286.rs b/tests/crashes/136286.rs
new file mode 100644
index 00000000000..f0ea14bd167
--- /dev/null
+++ b/tests/crashes/136286.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #136286
+//@ compile-flags: --edition=2024
+
+#![feature(async_fn_in_dyn_trait)]
+trait A {
+    async fn b(self: A);
+}
diff --git a/tests/crashes/136379.rs b/tests/crashes/136379.rs
new file mode 100644
index 00000000000..077b373e3b5
--- /dev/null
+++ b/tests/crashes/136379.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #136379
+#![feature(min_generic_const_args)]
+pub struct S();
+
+impl S {
+    pub fn f() -> [u8; S] {
+        []
+    }
+}
+
+pub fn main() {}
diff --git a/tests/crashes/136381.rs b/tests/crashes/136381.rs
new file mode 100644
index 00000000000..13ccc14a2c5
--- /dev/null
+++ b/tests/crashes/136381.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #136381
+//@ compile-flags: -Zvalidate-mir -Zmir-enable-passes=+GVN
+#![feature(trait_upcasting)]
+
+trait A {}
+trait B: A {
+    fn c(&self);
+}
+impl B for i32 {
+    fn c(self) {
+        todo!();
+    }
+}
+
+fn main() {
+    let baz: &dyn B = &1;
+    let bar: &dyn A = baz;
+}
diff --git a/tests/crashes/136416.rs b/tests/crashes/136416.rs
new file mode 100644
index 00000000000..b233422af86
--- /dev/null
+++ b/tests/crashes/136416.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #136416
+#![feature(generic_const_exprs)]
+struct State<const S : usize = {}> where[(); S] :;
+
+struct Foo;
+struct State2<const S: usize = Foo> where [(); S]:;
diff --git a/tests/crashes/136442.rs b/tests/crashes/136442.rs
new file mode 100644
index 00000000000..0436debd565
--- /dev/null
+++ b/tests/crashes/136442.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #136442
+//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+Inline -Zmir-enable-passes=+JumpThreading --crate-type lib
+pub fn problem_thingy(items: &mut impl Iterator<Item = str>) {
+    let mut peeker = items.peekable();
+    match peeker.peek() {
+        Some(_) => (),
+        None => return (),
+    }
+}
diff --git a/tests/crashes/136661.rs b/tests/crashes/136661.rs
new file mode 100644
index 00000000000..76161a566f4
--- /dev/null
+++ b/tests/crashes/136661.rs
@@ -0,0 +1,25 @@
+//@ known-bug: #136661
+
+#![allow(unused)]
+
+trait Supertrait<T> {}
+
+trait Other {
+    fn method(&self) {}
+}
+
+impl WithAssoc for &'static () {
+    type As = ();
+}
+
+trait WithAssoc {
+    type As;
+}
+
+trait Trait<P: WithAssoc>: Supertrait<P::As> {
+    fn method(&self) {}
+}
+
+fn hrtb<T: for<'a> Trait<&'a ()>>() {}
+
+pub fn main() {}
diff --git a/tests/crashes/136666.rs b/tests/crashes/136666.rs
new file mode 100644
index 00000000000..5cfed65fdf9
--- /dev/null
+++ b/tests/crashes/136666.rs
@@ -0,0 +1,36 @@
+//@ known-bug: #136666
+// Needed so that rust can infer that the A in what() is &()
+trait IsRef<T> {}
+struct Dummy;
+impl<'a> IsRef<&'a ()> for Dummy {}
+
+trait WithLifetime {
+    type Output<'a>;
+}
+impl<'t> WithLifetime for &'t () {
+    type Output<'a> = &'a ();
+}
+
+// Needed to prevent the two Foo impls from overlapping
+struct Wrap<A>(A);
+
+trait Unimplemented {}
+
+trait Foo {}
+impl<T> Foo for T where T: Unimplemented {}
+impl<A> Foo for Wrap<A>
+where
+    Dummy: IsRef<A>,
+    for<'a> A: WithLifetime<Output<'a> = A>,
+{
+}
+
+fn what<A>()
+where
+    Wrap<A>: Foo,
+{
+}
+
+fn main() {
+    what();
+}
diff --git a/tests/crashes/136678.rs b/tests/crashes/136678.rs
new file mode 100644
index 00000000000..e7d7de23bfe
--- /dev/null
+++ b/tests/crashes/136678.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #136678
+#![feature(inherent_associated_types)]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct B<const A: usize>;
+
+struct Test<const A: usize>;
+
+impl<const A: usize> Test<A> {
+    type B = B<{ A }>;
+
+    fn test(a: Self::B) -> Self::B {
+        a
+    }
+}
+
+pub fn main() {}
diff --git a/tests/crashes/136766.rs b/tests/crashes/136766.rs
new file mode 100644
index 00000000000..01fa07a05ae
--- /dev/null
+++ b/tests/crashes/136766.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #136766
+#![feature(generic_const_exprs)]
+trait A<const B: bool>{}
+impl A<true> for () {}
+fn c<const D: usize>(E: [u8; D * D]) where() : A<D>{}
+fn main() { c }
diff --git a/tests/crashes/136859.rs b/tests/crashes/136859.rs
new file mode 100644
index 00000000000..2c926eea5e2
--- /dev/null
+++ b/tests/crashes/136859.rs
@@ -0,0 +1,27 @@
+//@ known-bug: #136859
+#![feature(generic_const_exprs)]
+
+trait If<const COND: bool> {}
+impl If<true> for () {}
+
+trait IsZero<const N: u8> {
+    type Answer;
+}
+
+struct True;
+struct False;
+
+impl<const N: u8> IsZero<N> for ()
+where (): If<{N == 0}> {
+    type Msg = True;
+}
+
+trait Foobar<const N: u8> {}
+
+impl<const N: u8> Foobar<N> for ()
+where (): IsZero<N, Answer = True> {}
+
+impl<const N: u8> Foobar<{{ N }}> for ()
+where (): IsZero<N, Answer = False> {}
+
+fn main() {}
diff --git a/tests/crashes/136894.rs b/tests/crashes/136894.rs
new file mode 100644
index 00000000000..26bbb78717e
--- /dev/null
+++ b/tests/crashes/136894.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #136894
+#![feature(generic_const_exprs)]
+#![crate_type = "lib"]
+#![allow(incomplete_features, dead_code)]
+
+struct X<T>([(); f::<T>()]) where [(); f::<T>()]:;
+
+const fn f<T>() -> usize { panic!() }
diff --git a/tests/crashes/137049.rs b/tests/crashes/137049.rs
new file mode 100644
index 00000000000..a7132e4fa17
--- /dev/null
+++ b/tests/crashes/137049.rs
@@ -0,0 +1,29 @@
+//@ known-bug: #137049
+//@ compile-flags: --crate-type=lib
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+trait Project1 {
+    type Assoc1;
+}
+
+impl<T> Project1 for T {
+    type Assoc1 = ();
+}
+
+trait Project2 {
+    type Assoc2;
+}
+
+impl<T: Project1<Assoc1 = ()>> Project2 for PhantomData<T> {
+    type Assoc2 = ();
+}
+
+type Alias<T> = impl Project2;
+
+fn constrain<T>() -> Alias<T> {
+    PhantomData::<T>
+}
+
+struct AdtConstructor<T: Project1>(<Alias<T> as Project2>::Assoc2);
diff --git a/tests/crashes/137084.rs b/tests/crashes/137084.rs
new file mode 100644
index 00000000000..0f248c21206
--- /dev/null
+++ b/tests/crashes/137084.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #137084
+#![feature(min_generic_const_args)]
+fn a<const b: i32>() {}
+fn d(e: &String) {
+    a::<d>
+}
diff --git a/tests/crashes/137187.rs b/tests/crashes/137187.rs
new file mode 100644
index 00000000000..05cfb2b10e1
--- /dev/null
+++ b/tests/crashes/137187.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #137187
+use std::ops::Add;
+trait A where
+    *const Self: Add,
+{
+    const fn b(c: *const Self) -> <*const Self as Add>::Output {
+        c + c
+    }
+}
diff --git a/tests/crashes/137188.rs b/tests/crashes/137188.rs
new file mode 100644
index 00000000000..fdd098d300f
--- /dev/null
+++ b/tests/crashes/137188.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #137188
+#![feature(min_generic_const_args)]
+trait Trait {}
+impl Trait for [(); N] {}
+fn N<T>() {}
+pub fn main() {}
diff --git a/tests/crashes/137190-1.rs b/tests/crashes/137190-1.rs
new file mode 100644
index 00000000000..bdfe883b712
--- /dev/null
+++ b/tests/crashes/137190-1.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #137190
+//@ compile-flags: -Zmir-opt-level=2 -Zvalidate-mir
+trait A {
+    fn b(&self);
+}
+trait C: A {}
+impl C for () {}
+fn main() {
+    (&() as &dyn C as &dyn A).b();
+}
diff --git a/tests/crashes/137190-2.rs b/tests/crashes/137190-2.rs
new file mode 100644
index 00000000000..0c68b5aa4a5
--- /dev/null
+++ b/tests/crashes/137190-2.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #137190
+trait Supertrait<T> {
+    fn method(&self) {}
+}
+
+trait Trait<P>: Supertrait<()> {}
+
+impl<P> Trait<P> for () {}
+
+const fn upcast<P>(x: &dyn Trait<P>) -> &dyn Supertrait<()> {
+    x
+}
+
+const fn foo() -> &'static dyn Supertrait<()> {
+    upcast::<()>(&())
+}
+
+const _: &'static dyn Supertrait<()> = foo();
diff --git a/tests/crashes/137190-3.rs b/tests/crashes/137190-3.rs
new file mode 100644
index 00000000000..88ae88e11bc
--- /dev/null
+++ b/tests/crashes/137190-3.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #137190
+trait Supertrait {
+    fn method(&self) {}
+}
+
+trait Trait: Supertrait {}
+
+impl Trait for () {}
+
+const _: &dyn Supertrait = &() as &dyn Trait as &dyn Supertrait;
diff --git a/tests/crashes/137260.rs b/tests/crashes/137260.rs
new file mode 100644
index 00000000000..f1fa8a660dc
--- /dev/null
+++ b/tests/crashes/137260.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #137260
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Iter<const N: usize = { 1 + true }> {}
+
+fn needs_iter<const N: usize, T: Iter<N>>() {}
+
+fn test() {
+    needs_iter::<1, dyn Iter<()>>();
+}
diff --git a/tests/crashes/137287.rs b/tests/crashes/137287.rs
new file mode 100644
index 00000000000..59fdf568d36
--- /dev/null
+++ b/tests/crashes/137287.rs
@@ -0,0 +1,29 @@
+//@ known-bug: #137287
+
+mod defining_scope {
+    use super::*;
+    pub type Alias<T> = impl Sized;
+
+    pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
+        x
+    }
+}
+
+struct Container<T: Trait<U>, U> {
+    x: <T as Trait<U>>::Assoc,
+}
+
+trait Trait<T> {
+    type Assoc;
+}
+
+impl<T> Trait<T> for T {
+    type Assoc = Box<u32>;
+}
+impl<T> Trait<T> for defining_scope::Alias<T> {
+    type Assoc = usize;
+}
+
+fn main() {
+    let x: Box<u32> = defining_scope::cast::<()>(Container { x: 0 }).x;
+}
diff --git a/tests/crashes/137467-1.rs b/tests/crashes/137467-1.rs
new file mode 100644
index 00000000000..1d62cba59a7
--- /dev/null
+++ b/tests/crashes/137467-1.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #137467
+//@ compile-flags: --edition=2021
+enum Camera {
+    Normal { base_transform: i32 },
+    Volume { transform: i32 },
+}
+
+fn draw_ui(camera: &mut Camera) {
+    || {
+        let (Camera::Normal {
+            base_transform: _transform,
+        }
+        | Camera::Volume {
+            transform: _transform,
+        }) = camera;
+    };
+}
diff --git a/tests/crashes/137467-2.rs b/tests/crashes/137467-2.rs
new file mode 100644
index 00000000000..151d6a0767f
--- /dev/null
+++ b/tests/crashes/137467-2.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #137467
+//@ compile-flags: --edition=2021
+
+enum Camera {
+    Normal { base_transform: i32 },
+    Volume { transform: i32 },
+}
+
+fn draw_ui(camera: &mut Camera) {
+    || {
+        let (Camera::Normal {
+            base_transform: _,
+        }
+        | Camera::Volume {
+            transform: _,
+        }) = camera;
+    };
+}
diff --git a/tests/crashes/137467-3.rs b/tests/crashes/137467-3.rs
new file mode 100644
index 00000000000..2140fe044a7
--- /dev/null
+++ b/tests/crashes/137467-3.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #137467
+//@ compile-flags: --edition=2021
+
+fn meow(x: (u32, u32, u32)) {
+    let f = || {
+        let ((0, a, _) | (_, _, a)) = x;
+    };
+}
diff --git a/tests/crashes/137468.rs b/tests/crashes/137468.rs
new file mode 100644
index 00000000000..cceb0502bd2
--- /dev/null
+++ b/tests/crashes/137468.rs
@@ -0,0 +1,16 @@
+//@ known-bug: #137468
+//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+GVN -Zvalidate-mir
+trait Supertrait<T> {}
+
+trait Identity {
+    type Selff;
+}
+
+trait Trait<P>: Supertrait<()> + Supertrait<<P as Identity>::Selff> {}
+
+impl<P> Trait<P> for () {}
+
+fn main() {
+    let x: &dyn Trait<()> = &();
+    let x: &dyn Supertrait<()> = x;
+}
diff --git a/tests/crashes/137514.rs b/tests/crashes/137514.rs
new file mode 100644
index 00000000000..7ae5f29e36e
--- /dev/null
+++ b/tests/crashes/137514.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #137514
+//@ needs-rustc-debug-assertions
+#![feature(generic_const_exprs)]
+
+trait Bar<const N: usize> {}
+
+trait BB = Bar<{ 1i32 + 1 }>;
+
+fn foo(x: &dyn BB) {}
diff --git a/tests/crashes/137580.rs b/tests/crashes/137580.rs
new file mode 100644
index 00000000000..246c80ef556
--- /dev/null
+++ b/tests/crashes/137580.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #137580
+fn main() {
+    println!("%65536$", 1);
+}
diff --git a/tests/crashes/137582.rs b/tests/crashes/137582.rs
new file mode 100644
index 00000000000..e21b6c9578b
--- /dev/null
+++ b/tests/crashes/137582.rs
@@ -0,0 +1,16 @@
+//@ known-bug: #137582
+#![feature(adt_const_params)]
+
+mod lib {
+    pub type Matrix = [&'static u32];
+
+    const EMPTY_MATRIX: Matrix = [[0; 4]; 4];
+
+    pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> {
+        _p: (),
+    }
+
+    impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {}
+}
+
+fn main() {}
diff --git a/tests/crashes/137706.rs b/tests/crashes/137706.rs
new file mode 100644
index 00000000000..0b46f9c237a
--- /dev/null
+++ b/tests/crashes/137706.rs
@@ -0,0 +1,7 @@
+//@ known-bug: #137706
+//@ needs-rustc-debug-assertions
+trait A {
+    fn b() -> impl IntoIterator<Item = ()>;
+}
+
+impl A<()> for dyn A {}
diff --git a/tests/crashes/137751.rs b/tests/crashes/137751.rs
new file mode 100644
index 00000000000..85ae3acd53d
--- /dev/null
+++ b/tests/crashes/137751.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #137751
+//@ compile-flags: --edition=2021 -Znext-solver=globally
+async fn test() {
+    Box::pin(test()).await;
+}
+fn main() {}
diff --git a/tests/crashes/137813.rs b/tests/crashes/137813.rs
new file mode 100644
index 00000000000..5d205ee5331
--- /dev/null
+++ b/tests/crashes/137813.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #137813
+trait AssocConst {
+    const A: u8;
+}
+
+impl<T> AssocConst for (T,) {
+    const A: u8 = 0;
+}
+
+trait Trait {}
+
+impl<U> Trait for () where (U,): AssocConst<A = { 0 }> {}
+
+fn foo()
+where
+    (): Trait,
+{
+}
diff --git a/tests/crashes/137865.rs b/tests/crashes/137865.rs
new file mode 100644
index 00000000000..7ecd8c734d3
--- /dev/null
+++ b/tests/crashes/137865.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #137865
+trait Foo {
+    type Assoc<const N: Self>;
+    fn foo() -> Self::Assoc<3>;
+}
diff --git a/tests/crashes/137874.rs b/tests/crashes/137874.rs
new file mode 100644
index 00000000000..44718809024
--- /dev/null
+++ b/tests/crashes/137874.rs
@@ -0,0 +1,4 @@
+//@ known-bug: #137874
+fn a() {
+    match b { deref !(0c) };
+}
diff --git a/tests/crashes/137888.rs b/tests/crashes/137888.rs
new file mode 100644
index 00000000000..6c13ae5fa91
--- /dev/null
+++ b/tests/crashes/137888.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #137888
+#![feature(generic_const_exprs)]
+macro_rules! empty {
+    () => ();
+}
+fn bar<const N: i32>() -> [(); {
+       empty! {};
+       N
+   }] {
+}
+fn main() {}
diff --git a/tests/crashes/137895.rs b/tests/crashes/137895.rs
new file mode 100644
index 00000000000..bb624d2e9fa
--- /dev/null
+++ b/tests/crashes/137895.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #137895
+trait A {
+    fn b() -> impl ?Sized + 'a;
+}
+
+impl A for dyn A {}
diff --git a/tests/crashes/137916.rs b/tests/crashes/137916.rs
new file mode 100644
index 00000000000..3d6b0e0fbab
--- /dev/null
+++ b/tests/crashes/137916.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #137916
+//@ compile-flags: --edition=2021
+use std::ptr::null;
+
+async fn a() -> Box<dyn Send> {
+    Box::new(async {
+        let non_send = null::<()>();
+        &non_send;
+        async {}.await
+    })
+}
+
+fn main() {}
diff --git a/tests/crashes/138008.rs b/tests/crashes/138008.rs
new file mode 100644
index 00000000000..4645b8c9d56
--- /dev/null
+++ b/tests/crashes/138008.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #138008
+//@compile-flags: --crate-type=lib -Copt-level=0
+#![feature(repr_simd)]
+const C: usize = 16;
+
+#[repr(simd)]
+pub struct Foo([u8; C]);
+pub unsafe fn foo(a: Foo) {}
diff --git a/tests/crashes/138009.rs b/tests/crashes/138009.rs
new file mode 100644
index 00000000000..a1b890823e7
--- /dev/null
+++ b/tests/crashes/138009.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #138009
+#![feature(min_generic_const_args)]
+#[repr(simd)]
+struct T([isize; N]);
+
+static X: T = T();
diff --git a/tests/crashes/138048.rs b/tests/crashes/138048.rs
new file mode 100644
index 00000000000..fd59f46c752
--- /dev/null
+++ b/tests/crashes/138048.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #138048
+struct Foo;
+
+impl<'b> Foo {
+    fn bar<const V: u8>() {
+        let V;
+    }
+}
diff --git a/tests/crashes/138088.rs b/tests/crashes/138088.rs
new file mode 100644
index 00000000000..25496d804fe
--- /dev/null
+++ b/tests/crashes/138088.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #138088
+#![feature(min_generic_const_args)]
+trait Bar {
+    fn x(&self) -> [i32; Bar::x];
+}
diff --git a/tests/crashes/138089.rs b/tests/crashes/138089.rs
new file mode 100644
index 00000000000..acf27072bdd
--- /dev/null
+++ b/tests/crashes/138089.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #138089
+#![feature(generic_const_exprs)]
+#![feature(min_generic_const_args)]
+#![feature(inherent_associated_types)]
+struct OnDiskDirEntry<'a> {}
+
+impl<'a> OnDiskDirEntry<'a> {
+    const LFN_FRAGMENT_LEN: i64 = 2;
+
+    fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] {
+        loop {}
+    }
+}
diff --git a/tests/crashes/138131.rs b/tests/crashes/138131.rs
new file mode 100644
index 00000000000..f400c02de8d
--- /dev/null
+++ b/tests/crashes/138131.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #138131
+#![feature(min_generic_const_args)]
+#![feature(inherent_associated_types)]
+struct Foo<'a> {
+    x: &'a (),
+}
+
+impl<'a> Foo<'a> {
+    fn foo(_: [u8; Foo::X]) {}
+}
+
+fn main() {}
diff --git a/tests/crashes/138132.rs b/tests/crashes/138132.rs
new file mode 100644
index 00000000000..3e31117c526
--- /dev/null
+++ b/tests/crashes/138132.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #138132
+#![feature(min_generic_const_args)]
+struct b(Box<[u8; c]>);
+impl b {
+    fn d(self) {
+        self.0.e()
+    }
+}
+struct c<'a>(&'a u8);
+fn main() {}
diff --git a/tests/crashes/138166.rs b/tests/crashes/138166.rs
new file mode 100644
index 00000000000..98003bd6dae
--- /dev/null
+++ b/tests/crashes/138166.rs
@@ -0,0 +1,8 @@
+//@ known-bug: #138166
+#![feature(min_generic_const_args)]
+#![feature(inherent_associated_types)]
+struct a(Box<[u8; Box::b]>);
+impl a {
+  fn c(self) { self.0.d() }
+}
+fn main() {}
diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.rs b/tests/ui-fulldeps/hash-stable-is-unstable.rs
index dc778695287..a4b8533eb04 100644
--- a/tests/ui-fulldeps/hash-stable-is-unstable.rs
+++ b/tests/ui-fulldeps/hash-stable-is-unstable.rs
@@ -1,4 +1,3 @@
-//@ ignore-stage1 FIXME: this line can be removed once these new error messages are in stage 0 rustc
 //@ compile-flags: -Zdeduplicate-diagnostics=yes
 extern crate rustc_data_structures;
 //~^ use of unstable library feature `rustc_private`
diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.stderr b/tests/ui-fulldeps/hash-stable-is-unstable.stderr
index 8d809175875..e7740d744b4 100644
--- a/tests/ui-fulldeps/hash-stable-is-unstable.stderr
+++ b/tests/ui-fulldeps/hash-stable-is-unstable.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/hash-stable-is-unstable.rs:3:1
+  --> $DIR/hash-stable-is-unstable.rs:2:1
    |
 LL | extern crate rustc_data_structures;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | extern crate rustc_data_structures;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/hash-stable-is-unstable.rs:7:1
+  --> $DIR/hash-stable-is-unstable.rs:6:1
    |
 LL | extern crate rustc_macros;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL | extern crate rustc_macros;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/hash-stable-is-unstable.rs:11:1
+  --> $DIR/hash-stable-is-unstable.rs:10:1
    |
 LL | extern crate rustc_query_system;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL | extern crate rustc_query_system;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/hash-stable-is-unstable.rs:16:5
+  --> $DIR/hash-stable-is-unstable.rs:15:5
    |
 LL | use rustc_macros::HashStable;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -39,7 +39,7 @@ LL | use rustc_macros::HashStable;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/hash-stable-is-unstable.rs:21:10
+  --> $DIR/hash-stable-is-unstable.rs:20:10
    |
 LL | #[derive(HashStable)]
    |          ^^^^^^^^^^
diff --git a/tests/ui-fulldeps/pathless-extern-unstable.rs b/tests/ui-fulldeps/pathless-extern-unstable.rs
index 27272135696..b5ba4082e9d 100644
--- a/tests/ui-fulldeps/pathless-extern-unstable.rs
+++ b/tests/ui-fulldeps/pathless-extern-unstable.rs
@@ -1,4 +1,3 @@
-//@ ignore-stage1 FIXME: this line can be removed once these new error messages are in stage 0 rustc
 //@ edition:2018
 //@ compile-flags:--extern rustc_middle
 
diff --git a/tests/ui-fulldeps/pathless-extern-unstable.stderr b/tests/ui-fulldeps/pathless-extern-unstable.stderr
index a78b69f4d20..779c3773a9b 100644
--- a/tests/ui-fulldeps/pathless-extern-unstable.stderr
+++ b/tests/ui-fulldeps/pathless-extern-unstable.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
-  --> $DIR/pathless-extern-unstable.rs:7:9
+  --> $DIR/pathless-extern-unstable.rs:6:9
    |
 LL | pub use rustc_middle;
    |         ^^^^^^^^^^^^
diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
index 4ca6ef89819..aa22a453744 100644
--- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
@@ -3,6 +3,9 @@ error[E0733]: recursion in an async fn requires boxing
    |
 LL |     async fn second(self) {
    |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |         self.first().await.second().await;
+   |         --------------------------------- recursive call here
    |
    = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future
 
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs
new file mode 100644
index 00000000000..cfc0a97989d
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.rs
@@ -0,0 +1,36 @@
+// Combination of `ptr-to-trait-obj-wrap.rs` and `ptr-to-trait-obj-add-auto.rs`.
+//
+// Checks that you *can't* add auto traits to trait object in pointer casts involving wrapping said
+// traits structures.
+
+trait A {}
+
+struct W<T: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap(a: *const W<dyn A>) -> *const (dyn A + Send) {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A + Send> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn rewrap(a: *const W<dyn A>) -> *const X<dyn A + Send> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A + Send>> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn wrap(a: *const dyn A) -> *const W<dyn A + Send> {
+    a as _
+    //~^ error: cannot add auto trait `Send` to dyn bound via pointer cast
+}
+
+fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr
new file mode 100644
index 00000000000..42cdbc34ee8
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-add-auto.stderr
@@ -0,0 +1,48 @@
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:12:5
+   |
+LL |     a as _
+   |     ^^^^^^ unsupported cast
+   |
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
+
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:17:5
+   |
+LL |     a as _
+   |     ^^^^^^ unsupported cast
+   |
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
+
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:22:5
+   |
+LL |     a as _
+   |     ^^^^^^ unsupported cast
+   |
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
+
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:27:5
+   |
+LL |     a as _
+   |     ^^^^^^ unsupported cast
+   |
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
+
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-wrap-add-auto.rs:32:5
+   |
+LL |     a as _
+   |     ^^^^^^ unsupported cast
+   |
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0804`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs
new file mode 100644
index 00000000000..ebe7a06a7a1
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.rs
@@ -0,0 +1,36 @@
+// Combination of `ptr-to-trait-obj-different-args.rs` and `ptr-to-trait-obj-wrap.rs`.
+//
+// Checks that you *can't* change type arguments of trait objects in pointer casts involving
+// wrapping said traits structures.
+
+trait A<T> {}
+
+struct W<T: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap<F, G>(a: *const W<dyn A<F>>) -> *const dyn A<G> {
+    a as _
+    //~^ error casting `*const W<(dyn A<F> + 'static)>` as `*const dyn A<G>` is invalid
+}
+
+fn unwrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<dyn A<G>> {
+    a as _
+    //~^ error casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<dyn A<G>>` is invalid
+}
+
+fn rewrap<F, G>(a: *const W<dyn A<F>>) -> *const X<dyn A<G>> {
+    a as _
+    //~^ error: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` is invalid
+}
+
+fn rewrap_nested<F, G>(a: *const W<W<dyn A<F>>>) -> *const W<X<dyn A<G>>> {
+    a as _
+    //~^ error: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` is invalid
+}
+
+fn wrap<F, G>(a: *const dyn A<F>) -> *const W<dyn A<G>> {
+    a as _
+    //~^ error: casting `*const (dyn A<F> + 'static)` as `*const W<dyn A<G>>` is invalid
+}
+
+fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr
new file mode 100644
index 00000000000..4f85b208d05
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-args.stderr
@@ -0,0 +1,43 @@
+error[E0606]: casting `*const W<(dyn A<F> + 'static)>` as `*const dyn A<G>` is invalid
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:12:5
+   |
+LL |     a as _
+   |     ^^^^^^
+   |
+   = note: the trait objects may have different vtables
+
+error[E0606]: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<dyn A<G>>` is invalid
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:17:5
+   |
+LL |     a as _
+   |     ^^^^^^
+   |
+   = note: the trait objects may have different vtables
+
+error[E0606]: casting `*const W<(dyn A<F> + 'static)>` as `*const X<dyn A<G>>` is invalid
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:22:5
+   |
+LL |     a as _
+   |     ^^^^^^
+   |
+   = note: the trait objects may have different vtables
+
+error[E0606]: casting `*const W<W<(dyn A<F> + 'static)>>` as `*const W<X<dyn A<G>>>` is invalid
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:27:5
+   |
+LL |     a as _
+   |     ^^^^^^
+   |
+   = note: the trait objects may have different vtables
+
+error[E0606]: casting `*const (dyn A<F> + 'static)` as `*const W<dyn A<G>>` is invalid
+  --> $DIR/ptr-to-trait-obj-wrap-different-args.rs:32:5
+   |
+LL |     a as _
+   |     ^^^^^^
+   |
+   = note: the trait objects may have different vtables
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs
new file mode 100644
index 00000000000..b0941277d01
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.rs
@@ -0,0 +1,41 @@
+// Combination of `ptr-to-trait-obj-different-regions-misc.rs` and `ptr-to-trait-obj-wrap.rs`.
+//
+// Checks that you *can't* change lifetime arguments of trait objects in pointer casts involving
+// wrapping said traits structures.
+
+trait A<'a> {}
+
+struct W<T: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
+    a as _
+    //~^ error
+    //~| error
+}
+
+fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
+    a as _
+    //~^ error: lifetime may not live long enough
+    //~| error: lifetime may not live long enough
+}
+
+fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+    a as _
+    //~^ error: lifetime may not live long enough
+    //~| error: lifetime may not live long enough
+}
+
+fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
+    a as _
+    //~^ error: lifetime may not live long enough
+    //~| error: lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr
new file mode 100644
index 00000000000..17a0ca3c34f
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap-different-regions.stderr
@@ -0,0 +1,140 @@
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5
+   |
+LL | fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:12:5
+   |
+LL | fn unwrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const dyn A<'b> {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5
+   |
+LL | fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:18:5
+   |
+LL | fn unwrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<dyn A<'b>> {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5
+   |
+LL | fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:24:5
+   |
+LL | fn rewrap<'a, 'b>(a: *const W<dyn A<'a>>) -> *const X<dyn A<'b>> {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5
+   |
+LL | fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:30:5
+   |
+LL | fn rewrap_nested<'a, 'b>(a: *const W<W<dyn A<'a>>>) -> *const W<X<dyn A<'b>>> {
+   |                  --  -- lifetime `'b` defined here
+   |                  |
+   |                  lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5
+   |
+LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
+   |         --  -- lifetime `'b` defined here
+   |         |
+   |         lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/ptr-to-trait-obj-wrap-different-regions.rs:36:5
+   |
+LL | fn wrap<'a, 'b>(a: *const dyn A<'a>) -> *const W<dyn A<'b>> {
+   |         --  -- lifetime `'b` defined here
+   |         |
+   |         lifetime `'a` defined here
+LL |     a as _
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs
new file mode 100644
index 00000000000..6f9f6bddb99
--- /dev/null
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap.rs
@@ -0,0 +1,33 @@
+// Checks that various casts of pointers to trait objects wrapped in structures
+// work. Note that the metadata doesn't change when a DST is wrapped in a
+// structure, so these casts *are* fine.
+//
+// `unwrap` and `unwrap_nested` currently don't work due to a compiler limitation.
+//@ check-pass
+
+trait A {}
+
+struct W<T: ?Sized>(T);
+struct X<T: ?Sized>(T);
+
+fn unwrap(a: *const W<dyn A>) -> *const dyn A {
+    a as _
+}
+
+fn unwrap_nested(a: *const W<W<dyn A>>) -> *const W<dyn A> {
+    a as _
+}
+
+fn rewrap(a: *const W<dyn A>) -> *const X<dyn A> {
+    a as _
+}
+
+fn rewrap_nested(a: *const W<W<dyn A>>) -> *const W<X<dyn A>> {
+    a as _
+}
+
+fn wrap(a: *const dyn A) -> *const W<dyn A> {
+    a as _
+}
+
+fn main() {}
diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs
index e1c6861c510..87c8b04452b 100644
--- a/tests/ui/consts/issue-94675.rs
+++ b/tests/ui/consts/issue-94675.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl, const_vec_string_slice)]
+#![feature(const_trait_impl)]
 
 struct Foo<'a> {
     bar: &'a mut Vec<usize>,
diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs
index 2daac12d7ac..c8a4a222cc6 100644
--- a/tests/ui/layout/post-mono-layout-cycle-2.rs
+++ b/tests/ui/layout/post-mono-layout-cycle-2.rs
@@ -1,4 +1,4 @@
-//@ build-fail
+//@ check-fail
 //@ edition: 2021
 
 use std::future::Future;
diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr
index d8c51deffe3..f04e01071d7 100644
--- a/tests/ui/layout/post-mono-layout-cycle-2.stderr
+++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr
@@ -12,12 +12,6 @@ LL |           Blah::iter(self, iterator).await
    |
    = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future
 
-note: the above error was encountered while instantiating `fn Wrap::<()>::ice`
-  --> $DIR/post-mono-layout-cycle-2.rs:54:9
-   |
-LL |         t.ice();
-   |         ^^^^^^^
-
 error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.rs b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs
index d53b5144760..d34e6658435 100644
--- a/tests/ui/lint/lint-incoherent-auto-trait-objects.rs
+++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.rs
@@ -4,16 +4,13 @@ impl Foo for dyn Send {}
 
 impl Foo for dyn Send + Send {}
 //~^ ERROR conflicting implementations
-//~| hard error
 
 impl Foo for dyn Send + Sync {}
 
 impl Foo for dyn Sync + Send {}
 //~^ ERROR conflicting implementations
-//~| hard error
 
 impl Foo for dyn Send + Sync + Send {}
 //~^ ERROR conflicting implementations
-//~| hard error
 
 fn main() {}
diff --git a/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr
index 553ab3869b3..28e8f74672d 100644
--- a/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr
+++ b/tests/ui/lint/lint-incoherent-auto-trait-objects.stderr
@@ -1,4 +1,4 @@
-error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
+error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`
   --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
    |
 LL | impl Foo for dyn Send {}
@@ -6,76 +6,25 @@ LL | impl Foo for dyn Send {}
 LL |
 LL | impl Foo for dyn Send + Send {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-   = note: `#[deny(order_dependent_trait_objects)]` on by default
 
-error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
+error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`
+  --> $DIR/lint-incoherent-auto-trait-objects.rs:10:1
    |
 LL | impl Foo for dyn Send + Sync {}
    | ---------------------------- first implementation here
 LL |
 LL | impl Foo for dyn Sync + Send {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
-error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
+error[E0119]: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`
+  --> $DIR/lint-incoherent-auto-trait-objects.rs:13:1
    |
-LL | impl Foo for dyn Sync + Send {}
+LL | impl Foo for dyn Send + Sync {}
    | ---------------------------- first implementation here
 ...
 LL | impl Foo for dyn Send + Sync + Send {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
 error: aborting due to 3 previous errors
 
-Future incompatibility report: Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
-  --> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
-   |
-LL | impl Foo for dyn Send {}
-   | --------------------- first implementation here
-LL |
-LL | impl Foo for dyn Send + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-   = note: `#[deny(order_dependent_trait_objects)]` on by default
-
-Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
-   |
-LL | impl Foo for dyn Send + Sync {}
-   | ---------------------------- first implementation here
-LL |
-LL | impl Foo for dyn Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-   = note: `#[deny(order_dependent_trait_objects)]` on by default
-
-Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
-   |
-LL | impl Foo for dyn Sync + Send {}
-   | ---------------------------- first implementation here
-...
-LL | impl Foo for dyn Send + Sync + Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-   = note: `#[deny(order_dependent_trait_objects)]` on by default
-
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/issue-33140-hack-boundaries.rs b/tests/ui/traits/issue-33140-hack-boundaries.rs
index d091162fced..06786dcc8fe 100644
--- a/tests/ui/traits/issue-33140-hack-boundaries.rs
+++ b/tests/ui/traits/issue-33140-hack-boundaries.rs
@@ -1,5 +1,4 @@
 #![feature(negative_impls)]
-#![allow(order_dependent_trait_objects)]
 
 // Check that the issue #33140 hack does not allow unintended things.
 
@@ -8,6 +7,7 @@ trait Trait0 {}
 
 impl Trait0 for dyn Send {}
 impl Trait0 for dyn Send {}
+//~^ ERROR: E0119
 
 // Problem 1: associated types
 trait Trait1 {
diff --git a/tests/ui/traits/issue-33140-hack-boundaries.stderr b/tests/ui/traits/issue-33140-hack-boundaries.stderr
index d9c4efbb721..ed3ae2b3167 100644
--- a/tests/ui/traits/issue-33140-hack-boundaries.stderr
+++ b/tests/ui/traits/issue-33140-hack-boundaries.stderr
@@ -1,3 +1,11 @@
+error[E0119]: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`
+  --> $DIR/issue-33140-hack-boundaries.rs:9:1
+   |
+LL | impl Trait0 for dyn Send {}
+   | ------------------------ first implementation here
+LL | impl Trait0 for dyn Send {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
+
 error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn Send + 'static)`
   --> $DIR/issue-33140-hack-boundaries.rs:18:1
    |
@@ -62,19 +70,7 @@ LL | impl Trait5 for dyn Send {}
 LL | impl Trait5 for dyn Send where u32: Copy {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0119, E0751.
 For more information about an error, try `rustc --explain E0119`.
-Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`: (E0119)
-  --> $DIR/issue-33140-hack-boundaries.rs:10:1
-   |
-LL | impl Trait0 for dyn Send {}
-   | ------------------------ first implementation here
-LL | impl Trait0 for dyn Send {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-
diff --git a/tests/ui/traits/object/issue-33140-traitobject-crate.rs b/tests/ui/traits/object/issue-33140-traitobject-crate.rs
index 00ef6430d63..ff7cd30644b 100644
--- a/tests/ui/traits/object/issue-33140-traitobject-crate.rs
+++ b/tests/ui/traits/object/issue-33140-traitobject-crate.rs
@@ -1,6 +1,3 @@
-//@ check-pass
-
-#![warn(order_dependent_trait_objects)]
 #![allow(dyn_drop)]
 
 // Check that traitobject 0.1.0 compiles
@@ -84,15 +81,12 @@ unsafe impl<T> Trait for dyn (::std::iter::Iterator<Item=T>) + Send + Sync { }
 unsafe impl Trait for dyn (::std::marker::Send) + Send { }
 unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
 unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-//~^ WARNING conflicting implementations of trait `Trait` for type
-//~| WARNING this was previously accepted by the compiler but is being phased out
+//~^ ERROR conflicting implementations of trait `Trait` for type
 unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
-//~^ WARNING conflicting implementations of trait `Trait` for type
-//~| WARNING this was previously accepted by the compiler but is being phased out
+//~^ ERROR conflicting implementations of trait `Trait` for type
 unsafe impl Trait for dyn (::std::marker::Sync) + Sync { }
 unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
-//~^ WARNING conflicting implementations of trait `Trait` for type
-//~| WARNING this was previously accepted by the compiler but is being phased out
+//~^ ERROR conflicting implementations of trait `Trait` for type
 unsafe impl Trait for dyn (::std::ops::Drop) + Send { }
 unsafe impl Trait for dyn (::std::ops::Drop) + Sync { }
 unsafe impl Trait for dyn (::std::ops::Drop) + Send + Sync { }
diff --git a/tests/ui/traits/object/issue-33140-traitobject-crate.stderr b/tests/ui/traits/object/issue-33140-traitobject-crate.stderr
index 525401f9d69..a01c7990db3 100644
--- a/tests/ui/traits/object/issue-33140-traitobject-crate.stderr
+++ b/tests/ui/traits/object/issue-33140-traitobject-crate.stderr
@@ -1,95 +1,29 @@
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:86:1
+error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
+  --> $DIR/issue-33140-traitobject-crate.rs:83:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
    | ------------------------------------------------------ first implementation here
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-note: the lint level is defined here
-  --> $DIR/issue-33140-traitobject-crate.rs:3:9
-   |
-LL | #![warn(order_dependent_trait_objects)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:89:1
-   |
-LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-   | ------------------------------------------------------------- first implementation here
-...
-LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:93:1
-   |
-LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
-   | ------------------------------------------------------ first implementation here
-...
-LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-
-warning: 3 warnings emitted
 
-Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:86:1
+error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
+  --> $DIR/issue-33140-traitobject-crate.rs:85:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
    | ------------------------------------------------------ first implementation here
-LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-note: the lint level is defined here
-  --> $DIR/issue-33140-traitobject-crate.rs:3:9
-   |
-LL | #![warn(order_dependent_trait_objects)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:89:1
-   |
-LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
-   | ------------------------------------------------------------- first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-note: the lint level is defined here
-  --> $DIR/issue-33140-traitobject-crate.rs:3:9
-   |
-LL | #![warn(order_dependent_trait_objects)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:93:1
+error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
+  --> $DIR/issue-33140-traitobject-crate.rs:88:1
    |
-LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
+LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
    | ------------------------------------------------------ first implementation here
 ...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-note: the lint level is defined here
-  --> $DIR/issue-33140-traitobject-crate.rs:3:9
-   |
-LL | #![warn(order_dependent_trait_objects)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/triagebot.toml b/triagebot.toml
index 305b99ad5ec..e4231b2966b 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -253,7 +253,6 @@ trigger_files = [
     "compiler/rustc_passes/src/check_attr.rs",
     "compiler/rustc_attr_parsing",
     "compiler/rustc_attr_data_structures",
-    "compiler/rustc_attr_validation",
 ]
 
 [autolabel."T-rustdoc-frontend"]
@@ -317,7 +316,6 @@ trigger_files = [
     "library/panic_unwind",
     "library/std",
     "library/stdarch",
-    "library/term",
     "library/test",
 ]
 exclude_labels = [
@@ -332,7 +330,7 @@ trigger_files = [
 [autolabel."O-apple"]
 trigger_files = [
     "library/std/src/os/darwin",
-    "library/std/src/sys/pal/unix/thread_parking/darwin.rs",
+    "library/std/src/sys/sync/thread_parking/darwin.rs",
     "compiler/rustc_target/src/spec/base/apple",
 ]
 
@@ -409,7 +407,8 @@ trigger_files = [
 [autolabel."O-wasm"]
 trigger_files = [
     "library/std/src/sys/pal/wasm",
-    "library/std/src/os/wasm"
+    "library/std/src/os/wasi",
+    "library/std/src/os/wasip2"
 ]
 
 [autolabel."O-windows"]
@@ -500,7 +499,6 @@ trigger_files = [
     "CONTRIBUTING.md",
     "INSTALL.md",
     "REUSE.toml",
-    ".reuse",
     ".mailmap",
     ".git-blame-ignore-revs",
     ".editorconfig"
@@ -525,7 +523,6 @@ exclude_labels = [
 
 [autolabel."WG-trait-system-refactor"]
 trigger_files = [
-    "compiler/rustc_middle/src/traits/solve",
     "compiler/rustc_next_trait_solver",
     "compiler/rustc_trait_selection/src/solve",
     "compiler/rustc_type_ir/src/solve",
@@ -795,7 +792,7 @@ cc = ["@Nadrieril"]
 message = "Some changes occurred in cfg and check-cfg configuration"
 cc = ["@Urgau"]
 
-[mentions."compiler/rustc_lint/src/context/diagnostics/check_cfg.rs"]
+[mentions."compiler/rustc_lint/src/early/diagnostics/check_cfg.rs"]
 message = "Some changes occurred in check-cfg diagnostics"
 cc = ["@Urgau"]
 
@@ -961,7 +958,7 @@ If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/util
 [mentions."src/bootstrap/src/core/build_steps/llvm.rs"]
 message = "This PR changes how LLVM is built. Consider updating src/bootstrap/download-ci-llvm-stamp."
 
-[mentions."test/crashes"]
+[mentions."tests/crashes"]
 message = "This PR changes a file inside `tests/crashes`. If a crash was fixed, please move into the corresponding `ui` subdir and add 'Fixes #<issueNr>' to the PR description to autoclose the issue upon merge."
 
 [mentions."tests/rustdoc-json"]
@@ -1075,8 +1072,6 @@ cc = ["@jdonszelmann"]
 cc = ["@jdonszelmann"]
 [mentions."compiler/rustc_attr_data_structures"]
 cc = ["@jdonszelmann"]
-[mentions."compiler/rustc_attr_validation"]
-cc = ["@jdonszelmann"]
 
 [assign]
 warn_non_default_branch.enable = true
@@ -1265,7 +1260,6 @@ project-exploit-mitigations = [
 "/compiler/rustc_middle/src/traits" =                    ["compiler", "types"]
 "/compiler/rustc_middle/src/ty" =                        ["compiler", "types"]
 "/compiler/rustc_const_eval/src/interpret" =             ["compiler", "mir"]
-"/compiler/rustc_const_eval/src/transform" =             ["compiler", "mir-opt"]
 "/compiler/rustc_mir_build/src/builder" =                ["compiler", "mir"]
 "/compiler/rustc_mir_transform" =                        ["compiler", "mir", "mir-opt"]
 "/compiler/rustc_smir" =                                 ["project-stable-mir"]