about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock210
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs28
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs67
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs65
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch4
-rw-r--r--compiler/rustc_codegen_cranelift/src/codegen_i128.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/compiler_builtins.rs2
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/ci.yml7
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/failures.yml7
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml3
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/m68k.yml5
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/release.yml10
-rw-r--r--compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml5
-rw-r--r--compiler/rustc_codegen_gcc/.rustfmt.toml4
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.lock154
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.toml5
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/test.rs86
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core.rs10
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs4
-rw-r--r--compiler/rustc_codegen_gcc/example/mod_bench.rs2
-rw-r--r--compiler/rustc_codegen_gcc/example/std_example.rs2
-rw-r--r--compiler/rustc_codegen_gcc/libgccjit.version2
-rw-r--r--compiler/rustc_codegen_gcc/patches/0022-core-Disable-not-compiling-tests.patch13
-rw-r--r--compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch3
-rw-r--r--compiler/rustc_codegen_gcc/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_gcc/src/allocator.rs26
-rw-r--r--compiler/rustc_codegen_gcc/src/back/lto.rs37
-rw-r--r--compiler/rustc_codegen_gcc/src/back/write.rs157
-rw-r--r--compiler/rustc_codegen_gcc/src/base.rs48
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs72
-rw-r--r--compiler/rustc_codegen_gcc/src/callee.rs143
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs3
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/gcc_util.rs44
-rw-r--r--compiler/rustc_codegen_gcc/src/int.rs127
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs29
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs3
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs38
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-non-lto-tests.txt11
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt32
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt1
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock14
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml8
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock5
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml9
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs4
-rw-r--r--compiler/rustc_codegen_gcc/tests/lang_tests_common.rs32
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/array.rs206
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/closure.rs184
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/condition.rs288
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs196
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/operations.rs4
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs196
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/return-tuple.rs28
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/slice.rs101
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/volatile2.rs113
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs12
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs26
-rw-r--r--compiler/rustc_hir/src/hir.rs36
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs42
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--compiler/rustc_metadata/src/creader.rs105
-rw-r--r--compiler/rustc_metadata/src/locator.rs12
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs3
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs89
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs11
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs9
-rw-r--r--compiler/rustc_middle/src/ty/util.rs5
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs34
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs23
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs10
-rw-r--r--compiler/rustc_passes/src/stability.rs36
-rw-r--r--compiler/rustc_resolve/src/late.rs7
-rw-r--r--compiler/rustc_resolve/src/macros.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs68
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs12
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs15
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs32
-rw-r--r--compiler/rustc_type_ir/src/binder.rs2
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/core/src/ffi/c_str.rs52
-rw-r--r--library/core/src/intrinsics/fallback.rs1
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--library/core/src/ops/arith.rs1
-rw-r--r--library/core/src/ops/deref.rs2
-rw-r--r--library/core/src/ops/drop.rs1
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/sys/pal/unix/fs.rs36
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs14
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs12
-rw-r--r--src/bootstrap/src/utils/helpers.rs25
-rw-r--r--src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile5
-rwxr-xr-xsrc/ci/docker/scripts/build-gccjit.sh2
-rw-r--r--src/ci/docker/scripts/emscripten.sh24
-rw-r--r--src/librustdoc/clean/cfg.rs6
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/types.rs19
-rw-r--r--src/librustdoc/clean/utils.rs2
-rw-r--r--src/librustdoc/config.rs6
-rw-r--r--src/librustdoc/html/format.rs9
-rw-r--r--src/librustdoc/html/highlight.rs15
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/librustdoc/html/render/span_map.rs33
-rw-r--r--src/librustdoc/html/render/write_shared.rs10
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css2
-rw-r--r--src/librustdoc/html/static/js/search.js46
-rw-r--r--src/librustdoc/json/conversions.rs2
-rw-r--r--src/librustdoc/lib.rs9
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/missing_headers.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs2
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.rs1
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.stderr4
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed1
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs1
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr16
-rw-r--r--src/tools/lint-docs/src/lib.rs75
-rw-r--r--src/tools/opt-dist/src/bolt.rs13
-rw-r--r--src/tools/opt-dist/src/main.rs28
-rw-r--r--src/tools/rustbook/Cargo.lock183
-rw-r--r--tests/codegen-units/item-collection/closures.rs6
-rw-r--r--tests/codegen-units/item-collection/drop-glue-eager.rs56
-rw-r--r--tests/run-make/rustdoc-default-output/output-default.stdout3
-rw-r--r--tests/rustdoc-js-std/return-based-sort.js30
-rw-r--r--tests/rustdoc-json/return_private.rs2
-rw-r--r--tests/rustdoc/jump-to-def-pats.rs52
-rw-r--r--tests/ui/associated-types/issue-91231.rs2
-rw-r--r--tests/ui/async-await/async-closures/fn-exception-target-features.stderr5
-rw-r--r--tests/ui/attributes/key-value-expansion.rs2
-rw-r--r--tests/ui/borrowck/issue-92157.rs2
-rw-r--r--tests/ui/closures/binder/nested-closures-regions.stderr4
-rw-r--r--tests/ui/coherence/coherence-negative-impls-copy.rs2
-rw-r--r--tests/ui/conditional-compilation/cfg_accessible-not_sure.rs2
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr45
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr45
-rw-r--r--tests/ui/const-generics/type-mismatch-in-nested-goal.rs17
-rw-r--r--tests/ui/consts/const-eval/validation-ice-extern-type-field.rs2
-rw-r--r--tests/ui/consts/promoted-const-drop.rs2
-rw-r--r--tests/ui/consts/promoted_const_call.rs16
-rw-r--r--tests/ui/consts/promoted_const_call.stderr37
-rw-r--r--tests/ui/delegation/glob-non-impl.rs2
-rw-r--r--tests/ui/enum-discriminant/eval-error.rs37
-rw-r--r--tests/ui/enum-discriminant/eval-error.stderr51
-rw-r--r--tests/ui/extern/extern-type-diag-not-similar.rs4
-rw-r--r--tests/ui/extern/issue-10025.rs2
-rw-r--r--tests/ui/extern/issue-95829.rs2
-rw-r--r--tests/ui/extern/issue-95829.stderr8
-rw-r--r--tests/ui/extern/not-in-block.rs1
-rw-r--r--tests/ui/extern/not-in-block.stderr4
-rw-r--r--tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs2
-rw-r--r--tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr4
-rw-r--r--tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs2
-rw-r--r--tests/ui/invalid_dispatch_from_dyn_impls.stderr4
-rw-r--r--tests/ui/issues/issue-25901.rs2
-rw-r--r--tests/ui/issues/issue-25901.stderr13
-rw-r--r--tests/ui/layout/base-layout-is-sized-ice-123078.rs1
-rw-r--r--tests/ui/layout/base-layout-is-sized-ice-123078.stderr14
-rw-r--r--tests/ui/layout/debug.stderr2
-rw-r--r--tests/ui/link-native-libs/issue-109144.rs2
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-1.stderr10
-rw-r--r--tests/ui/link-native-libs/suggest-libname-only-2.stderr10
-rw-r--r--tests/ui/lint/function-item-references.rs2
-rw-r--r--tests/ui/lint/lint-ctypes.rs2
-rw-r--r--tests/ui/lint/lint-ctypes.stderr4
-rw-r--r--tests/ui/macros/issue-68060.rs2
-rw-r--r--tests/ui/macros/issue-68060.stderr10
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.rs2
-rw-r--r--tests/ui/parser/bad-fn-ptr-qualifier.fixed8
-rw-r--r--tests/ui/parser/bad-fn-ptr-qualifier.rs8
-rw-r--r--tests/ui/parser/bad-fn-ptr-qualifier.stderr32
-rw-r--r--tests/ui/parser/bad-lit-suffixes.rs4
-rw-r--r--tests/ui/parser/bad-lit-suffixes.stderr16
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs1
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr2
-rw-r--r--tests/ui/parser/item-kw-case-mismatch.fixed2
-rw-r--r--tests/ui/parser/item-kw-case-mismatch.rs2
-rw-r--r--tests/ui/parser/item-kw-case-mismatch.stderr8
-rw-r--r--tests/ui/parser/lit-err-in-macro.rs2
-rw-r--r--tests/ui/parser/lit-err-in-macro.stderr14
-rw-r--r--tests/ui/parser/recover/recover-const-async-fn-ptr.rs8
-rw-r--r--tests/ui/parser/recover/recover-const-async-fn-ptr.stderr32
-rw-r--r--tests/ui/parser/recover/recover-fn-ptr-with-generics.rs2
-rw-r--r--tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr16
-rw-r--r--tests/ui/parser/recover/recover-missing-semi-before-item.fixed2
-rw-r--r--tests/ui/parser/recover/recover-missing-semi-before-item.rs2
-rw-r--r--tests/ui/parser/recover/recover-missing-semi-before-item.stderr2
-rw-r--r--tests/ui/privacy/sysroot-private.default.stderr39
-rw-r--r--tests/ui/privacy/sysroot-private.rs42
-rw-r--r--tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr39
-rw-r--r--tests/ui/proc-macro/inner-attrs.stderr10
-rw-r--r--tests/ui/proc-macro/issue-66286.rs2
-rw-r--r--tests/ui/proc-macro/issue-66286.stderr10
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr7
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs6
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr24
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs1
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr19
-rw-r--r--tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs2
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed10
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs10
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.stderr9
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs25
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr16
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.rs34
-rw-r--r--tests/ui/self/dispatch-from-dyn-zst-transmute.stderr16
-rw-r--r--tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs25
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs2
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs1
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.stderr14
-rw-r--r--tests/ui/statics/uninhabited-static.rs2
-rw-r--r--tests/ui/target-feature/invalid-attribute.rs4
-rw-r--r--tests/ui/target-feature/invalid-attribute.stderr24
-rw-r--r--tests/ui/traits/const-traits/auxiliary/staged-api.rs1
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.rs2
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.rs2
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stocknc.stderr8
-rw-r--r--tests/ui/traits/const-traits/generic-bound.rs2
-rw-r--r--tests/ui/traits/const-traits/syntactical-unstable.rs34
-rw-r--r--tests/ui/traits/const-traits/syntactical-unstable.stderr67
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.rs1
-rw-r--r--tests/ui/traits/const-traits/trait-default-body-stability.stderr4
-rw-r--r--tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs13
-rw-r--r--tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs39
-rw-r--r--tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs40
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs8
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout8
260 files changed, 3201 insertions, 2413 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 117f1475e00..85e5e6c9710 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -254,9 +254,9 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
 
 [[package]]
 name = "blake3"
@@ -407,7 +407,7 @@ dependencies = [
  "semver",
  "serde",
  "serde_json",
- "thiserror 2.0.9",
+ "thiserror 2.0.11",
 ]
 
 [[package]]
@@ -481,9 +481,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.23"
+version = "4.5.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
+checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -501,9 +501,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.23"
+version = "4.5.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
+checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
 dependencies = [
  "anstream",
  "anstyle",
@@ -514,23 +514,23 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.40"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac2e663e3e3bed2d32d065a8404024dad306e699a04263ec59919529f803aee9"
+checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.5.18"
+version = "4.5.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
 dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -561,7 +561,7 @@ dependencies = [
  "rustc_tools_util",
  "serde",
  "serde_json",
- "syn 2.0.94",
+ "syn 2.0.96",
  "tempfile",
  "termize",
  "tokio",
@@ -671,7 +671,7 @@ dependencies = [
  "nom",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -896,7 +896,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -907,7 +907,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -944,7 +944,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -965,7 +965,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -975,7 +975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -987,7 +987,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -1065,7 +1065,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -1362,7 +1362,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -1502,17 +1502,18 @@ dependencies = [
 
 [[package]]
 name = "handlebars"
-version = "6.2.0"
+version = "6.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315"
+checksum = "3d6b224b95c1e668ac0270325ad563b2eef1469fbbb8959bc7c692c844b813d9"
 dependencies = [
+ "derive_builder",
  "log",
  "num-order",
  "pest",
  "pest_derive",
  "serde",
  "serde_json",
- "thiserror 1.0.69",
+ "thiserror 2.0.11",
 ]
 
 [[package]]
@@ -1596,7 +1597,7 @@ dependencies = [
  "markup5ever",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -1785,7 +1786,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -2085,9 +2086,9 @@ dependencies = [
 
 [[package]]
 name = "libz-sys"
-version = "1.1.20"
+version = "1.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472"
+checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa"
 dependencies = [
  "cc",
  "libc",
@@ -2114,9 +2115,9 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
 
 [[package]]
 name = "litemap"
@@ -2717,7 +2718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
 dependencies = [
  "memchr",
- "thiserror 2.0.9",
+ "thiserror 2.0.11",
  "ucd-trie",
 ]
 
@@ -2741,7 +2742,7 @@ dependencies = [
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -2757,21 +2758,21 @@ dependencies = [
 
 [[package]]
 name = "phf"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
 dependencies = [
- "phf_shared 0.11.2",
+ "phf_shared 0.11.3",
 ]
 
 [[package]]
 name = "phf_codegen"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
 dependencies = [
- "phf_generator 0.11.2",
- "phf_shared 0.11.2",
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
 ]
 
 [[package]]
@@ -2786,11 +2787,11 @@ dependencies = [
 
 [[package]]
 name = "phf_generator"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
- "phf_shared 0.11.2",
+ "phf_shared 0.11.3",
  "rand",
 ]
 
@@ -2800,23 +2801,23 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
 dependencies = [
- "siphasher",
+ "siphasher 0.3.11",
 ]
 
 [[package]]
 name = "phf_shared"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
 dependencies = [
- "siphasher",
+ "siphasher 1.0.1",
 ]
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
 
 [[package]]
 name = "pin-utils"
@@ -2886,9 +2887,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
 dependencies = [
  "unicode-ident",
 ]
@@ -3151,7 +3152,7 @@ dependencies = [
  "rinja_parser",
  "rustc-hash 2.1.0",
  "serde",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -3792,7 +3793,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "unic-langid",
 ]
 
@@ -3927,7 +3928,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -4075,7 +4076,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "synstructure",
 ]
 
@@ -4663,7 +4664,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "synstructure",
 ]
 
@@ -4752,7 +4753,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -4786,9 +4787,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.42"
+version = "0.38.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
+checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
 dependencies = [
  "bitflags",
  "errno",
@@ -4889,14 +4890,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.134"
+version = "1.0.135"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
+checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
 dependencies = [
  "indexmap",
  "itoa",
@@ -4970,6 +4971,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
 
 [[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
 name = "slab"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5147,9 +5154,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.94"
+version = "2.0.96"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5164,7 +5171,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -5292,11 +5299,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.9"
+version = "2.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc"
+checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
 dependencies = [
- "thiserror-impl 2.0.9",
+ "thiserror-impl 2.0.11",
 ]
 
 [[package]]
@@ -5307,18 +5314,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.9"
+version = "2.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4"
+checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -5441,9 +5448,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.42.0"
+version = "1.43.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
+checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
 dependencies = [
  "backtrace",
  "bytes",
@@ -5519,7 +5526,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -5690,7 +5697,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "unic-langid-impl",
 ]
 
@@ -5828,9 +5835,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "uuid"
-version = "1.11.0"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
+checksum = "b913a3b5fe84142e269d63cc62b64319ccaf89b748fc31fe025177f767a756c4"
 dependencies = [
  "getrandom",
 ]
@@ -5896,7 +5903,7 @@ dependencies = [
  "log",
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "wasm-bindgen-shared",
 ]
 
@@ -5918,7 +5925,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -5968,12 +5975,12 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.222.0"
+version = "0.223.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3432682105d7e994565ef928ccf5856cf6af4ba3dddebedb737f61caed70f956"
+checksum = "7e636076193fa68103e937ac951b5f2f587624097017d764b8984d9c0f149464"
 dependencies = [
  "leb128",
- "wasmparser 0.222.0",
+ "wasmparser 0.223.0",
 ]
 
 [[package]]
@@ -6013,28 +6020,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4adf50fde1b1a49c1add6a80d47aea500c88db70551805853aa8b88f3ea27ab5"
 dependencies = [
  "bitflags",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.223.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5a99faceb1a5a84dd6084ec4bfa4b2ab153b5793b43fd8f58b89232634afc35"
+dependencies = [
+ "bitflags",
  "indexmap",
  "semver",
 ]
 
 [[package]]
 name = "wast"
-version = "222.0.0"
+version = "223.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce7191f4b7da0dd300cc32476abae6457154e4625d9b1bc26890828a9a26f6e"
+checksum = "d59b2ba8a2ff9f06194b7be9524f92e45e70149f4dacc0d0c7ad92b59ac875e4"
 dependencies = [
  "bumpalo",
  "leb128",
  "memchr",
  "unicode-width 0.2.0",
- "wasm-encoder 0.222.0",
+ "wasm-encoder 0.223.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.222.0"
+version = "1.223.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fde61b4b52f9a84ae31b5e8902a2cd3162ea45d8bf564c729c3288fe52f4334"
+checksum = "662786915c427e4918ff01eabb3c4756d4d947cd8f635761526b4cc9da2eaaad"
 dependencies = [
  "wast",
 ]
@@ -6100,7 +6116,7 @@ dependencies = [
  "rayon",
  "serde",
  "serde_json",
- "syn 2.0.94",
+ "syn 2.0.96",
  "windows-metadata",
 ]
 
@@ -6133,7 +6149,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -6144,7 +6160,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -6376,9 +6392,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
 
 [[package]]
 name = "xattr"
-version = "1.3.1"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
+checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909"
 dependencies = [
  "libc",
  "linux-raw-sys",
@@ -6423,7 +6439,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "synstructure",
 ]
 
@@ -6445,7 +6461,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
 
 [[package]]
@@ -6465,7 +6481,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
  "synstructure",
 ]
 
@@ -6488,5 +6504,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.94",
+ "syn 2.0.96",
 ]
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 758f1dc1c35..266e77c0e02 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -188,7 +188,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
     ) -> hir::FnSig<'hir> {
         let header = if let Some(local_sig_id) = sig_id.as_local() {
             match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
-                Some(sig) => self.lower_fn_header(sig.header, hir::Safety::Safe),
+                Some(sig) => self.lower_fn_header(
+                    sig.header,
+                    // HACK: we override the default safety instead of generating attributes from the ether.
+                    // We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
+                    // and here we need the hir attributes.
+                    if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe },
+                    &[],
+                ),
                 None => self.generate_header_error(),
             }
         } else {
@@ -198,7 +205,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 Asyncness::No => hir::IsAsync::NotAsync,
             };
             hir::FnHeader {
-                safety: sig.safety,
+                safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
+                    hir::HeaderSafety::SafeTargetFeatures
+                } else {
+                    hir::HeaderSafety::Normal(sig.safety)
+                },
                 constness: self.tcx.constness(sig_id),
                 asyncness,
                 abi: sig.abi,
@@ -384,7 +395,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn generate_header_error(&self) -> hir::FnHeader {
         hir::FnHeader {
-            safety: hir::Safety::Safe,
+            safety: hir::Safety::Safe.into(),
             constness: hir::Constness::NotConst,
             asyncness: hir::IsAsync::NotAsync,
             abi: abi::Abi::Rust,
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 6fce9116938..61d7da429f8 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -231,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     });
                     let sig = hir::FnSig {
                         decl,
-                        header: this.lower_fn_header(*header, hir::Safety::Safe),
+                        header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
                         span: this.lower_span(*fn_sig_span),
                     };
                     hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
@@ -610,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
         let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
         let owner_id = hir_id.expect_owner();
-        self.lower_attrs(hir_id, &i.attrs);
+        let attrs = self.lower_attrs(hir_id, &i.attrs);
         let item = hir::ForeignItem {
             owner_id,
             ident: self.lower_ident(i.ident),
@@ -634,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         });
 
                     // Unmarked safety in unsafe block defaults to unsafe.
-                    let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe);
+                    let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
 
                     hir::ForeignItemKind::Fn(
                         hir::FnSig { header, decl, span: self.lower_span(sig.span) },
@@ -776,6 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     FnDeclKind::Trait,
                     sig.header.coroutine_kind,
+                    attrs,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
             }
@@ -795,6 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     FnDeclKind::Trait,
                     sig.header.coroutine_kind,
+                    attrs,
                 );
                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
             }
@@ -911,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     i.id,
                     if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
                     sig.header.coroutine_kind,
+                    attrs,
                 );
 
                 (generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -1339,8 +1342,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         id: NodeId,
         kind: FnDeclKind,
         coroutine_kind: Option<CoroutineKind>,
+        attrs: &[hir::Attribute],
     ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
-        let header = self.lower_fn_header(sig.header, hir::Safety::Safe);
+        let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
         let itctx = ImplTraitContext::Universal;
         let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
             this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
@@ -1352,14 +1356,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
         &mut self,
         h: FnHeader,
         default_safety: hir::Safety,
+        attrs: &[hir::Attribute],
     ) -> hir::FnHeader {
         let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
             hir::IsAsync::Async(span)
         } else {
             hir::IsAsync::NotAsync
         };
+
+        let safety = self.lower_safety(h.safety, default_safety);
+
+        // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
+        let safety = if attrs.iter().any(|attr| attr.has_name(sym::target_feature))
+            && safety.is_safe()
+            && !self.tcx.sess.target.is_like_wasm
+        {
+            hir::HeaderSafety::SafeTargetFeatures
+        } else {
+            safety.into()
+        };
+
         hir::FnHeader {
-            safety: self.lower_safety(h.safety, default_safety),
+            safety,
             asyncness,
             constness: self.lower_constness(h.constness),
             abi: self.lower_extern(h.ext),
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index d83d6ade203..e355d2b415b 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -34,7 +34,6 @@ pub(crate) enum RegionCtxt {
     Location(Location),
     TyContext(TyContext),
     Free(Symbol),
-    Bound(Symbol),
     LateBound(Symbol),
     Existential(Option<Symbol>),
     Placeholder(Symbol),
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index ea965eb6545..edf612f4e97 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -5,13 +5,14 @@ use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::{InferCtxt, outlives};
+use rustc_infer::traits::ScrubbedTraitError;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::traits::query::OutlivesBound;
 use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, Span};
-use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
-use rustc_trait_selection::solve::deeply_normalize;
+use rustc_trait_selection::solve::NoSolution;
+use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use tracing::{debug, instrument};
 use type_op::TypeOpOutput;
@@ -229,24 +230,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         let mut constraints = vec![];
         let mut known_type_outlives_obligations = vec![];
         for bound in param_env.caller_bounds() {
-            let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
-
-            // In the new solver, normalize the type-outlives obligation assumptions.
-            if self.infcx.next_trait_solver() {
-                match deeply_normalize(
-                    self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), param_env),
+            if let Some(outlives) = bound.as_type_outlives_clause() {
+                self.normalize_and_push_type_outlives_obligation(
                     outlives,
-                ) {
-                    Ok(normalized_outlives) => {
-                        outlives = normalized_outlives;
-                    }
-                    Err(e) => {
-                        self.infcx.err_ctxt().report_fulfillment_errors(e);
-                    }
-                }
-            }
-
-            known_type_outlives_obligations.push(outlives);
+                    span,
+                    &mut known_type_outlives_obligations,
+                    &mut constraints,
+                );
+            };
         }
 
         let unnormalized_input_output_tys = self
@@ -356,6 +347,44 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         }
     }
 
+    fn normalize_and_push_type_outlives_obligation(
+        &self,
+        mut outlives: ty::PolyTypeOutlivesPredicate<'tcx>,
+        span: Span,
+        known_type_outlives_obligations: &mut Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
+        constraints: &mut Vec<&QueryRegionConstraints<'tcx>>,
+    ) {
+        // In the new solver, normalize the type-outlives obligation assumptions.
+        if self.infcx.next_trait_solver() {
+            let Ok(TypeOpOutput {
+                output: normalized_outlives,
+                constraints: constraints_normalize,
+                error_info: _,
+            }) = CustomTypeOp::new(
+                |ocx| {
+                    ocx.deeply_normalize(
+                        &ObligationCause::dummy_with_span(span),
+                        self.param_env,
+                        outlives,
+                    )
+                    .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
+                },
+                "normalize type outlives obligation",
+            )
+            .fully_perform(self.infcx, span)
+            else {
+                self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
+                return;
+            };
+            outlives = normalized_outlives;
+            if let Some(c) = constraints_normalize {
+                constraints.push(c);
+            }
+        }
+
+        known_type_outlives_obligations.push(outlives);
+    }
+
     /// Update the type of a single local, which should represent
     /// either the return type of the MIR or one of its arguments. At
     /// the same time, compute and add any implied bounds that come
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 3dc4569c57b..26af86c0cdd 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -467,15 +467,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 self.infcx.tcx.local_parent(self.mir_def),
                 |r| {
                     debug!(?r);
-                    if !indices.indices.contains_key(&r) {
-                        let region_vid = {
-                            let name = r.get_name_or_anon();
-                            self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
-                        };
-
-                        debug!(?region_vid);
-                        indices.insert_late_bound_region(r, region_vid.as_var());
-                    }
+                    let region_vid = {
+                        let name = r.get_name_or_anon();
+                        self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
+                    };
+
+                    debug!(?region_vid);
+                    indices.insert_late_bound_region(r, region_vid.as_var());
                 },
             );
 
@@ -484,21 +482,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             self.infcx.num_region_vars()
         };
 
-        // "Liberate" the late-bound regions. These correspond to
-        // "local" free regions.
+        // Converse of above, if this is a function/closure then the late-bound regions declared
+        // on its signature are local.
+        //
+        // We manually loop over `bound_inputs_and_output` instead of using
+        // `for_each_late_bound_region_in_item` as we may need to add the otherwise
+        // implicit `ClosureEnv` region.
         let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
-
-        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
-            FR,
-            self.mir_def,
-            bound_inputs_and_output,
-            &mut indices,
-        );
-        // Converse of above, if this is a function/closure then the late-bound regions declared on its
-        // signature are local.
-        for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| {
-            debug!(?r);
-            if !indices.indices.contains_key(&r) {
+        for (idx, bound_var) in bound_inputs_and_output.bound_vars().iter().enumerate() {
+            if let ty::BoundVariableKind::Region(kind) = bound_var {
+                let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
+                let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind);
                 let region_vid = {
                     let name = r.get_name_or_anon();
                     self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
@@ -507,7 +501,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 debug!(?region_vid);
                 indices.insert_late_bound_region(r, region_vid.as_var());
             }
-        });
+        }
+        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
+            self.mir_def,
+            bound_inputs_and_output,
+            &indices,
+        );
 
         let (unnormalized_output_ty, mut unnormalized_input_tys) =
             inputs_and_output.split_last().unwrap();
@@ -832,10 +831,9 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self, indices))]
     fn replace_bound_regions_with_nll_infer_vars<T>(
         &self,
-        origin: NllRegionVariableOrigin,
         all_outlive_scope: LocalDefId,
         value: ty::Binder<'tcx, T>,
-        indices: &mut UniversalRegionIndices<'tcx>,
+        indices: &UniversalRegionIndices<'tcx>,
     ) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
@@ -845,18 +843,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
             let kind = ty::LateParamRegionKind::from_bound(br.var, br.kind);
             let liberated_region =
                 ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), kind);
-            let region_vid = {
-                let name = match br.kind.get_name() {
-                    Some(name) => name,
-                    _ => sym::anon,
-                };
-
-                self.next_nll_region_var(origin, || RegionCtxt::Bound(name))
-            };
-
-            indices.insert_late_bound_region(liberated_region, region_vid.as_var());
-            debug!(?liberated_region, ?region_vid);
-            region_vid
+            ty::Region::new_var(self.tcx, indices.to_region_vid(liberated_region))
         });
         value
     }
@@ -870,7 +857,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// well. These are used for error reporting.
     fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
         debug!("insert_late_bound_region({:?}, {:?})", r, vid);
-        self.indices.insert(r, vid);
+        assert_eq!(self.indices.insert(r, vid), None);
     }
 
     /// Converts `r` into a local inference variable: `r` can either
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
index bf07e455a75..bf58e485158 100644
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
@@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
  
  [dependencies]
  core = { path = "../core" }
--compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std', 'no-f16-f128'] }
+-compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std', 'no-f16-f128'] }
  
  [dev-dependencies]
  rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
index 025667e66b2..dcfd7ddabbc 100644
--- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
+++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
@@ -76,20 +76,22 @@ pub(crate) fn maybe_codegen_mul_checked<'tcx>(
     }
 
     let is_signed = type_sign(lhs.layout().ty);
-
-    let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
-    let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
+    let oflow_out_place = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
     let param_types = vec![
-        AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
         AbiParam::new(types::I128),
         AbiParam::new(types::I128),
+        AbiParam::special(fx.pointer_type, ArgumentPurpose::Normal),
     ];
-    let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
-    fx.lib_call(
+    let args = [lhs.load_scalar(fx), rhs.load_scalar(fx), oflow_out_place.to_ptr().get_addr(fx)];
+    let ret = fx.lib_call(
         if is_signed { "__rust_i128_mulo" } else { "__rust_u128_mulo" },
         param_types,
-        vec![],
+        vec![AbiParam::new(types::I128)],
         &args,
     );
-    Some(out_place.to_cvalue(fx))
+    let mul = ret[0];
+    let oflow = oflow_out_place.to_cvalue(fx).load_scalar(fx);
+    let oflow = clif_intcast(fx, oflow, types::I8, false);
+    let layout = fx.layout_of(Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]));
+    Some(CValue::by_val_pair(mul, oflow, layout))
 }
diff --git a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
index f8e3a034421..2484c10848e 100644
--- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
+++ b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs
@@ -43,7 +43,7 @@ builtin_functions! {
     fn __divti3(n: i128, d: i128) -> i128;
     fn __umodti3(n: u128, d: u128) -> u128;
     fn __modti3(n: i128, d: i128) -> i128;
-    fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool);
+    fn __rust_u128_mulo(a: u128, b: u128, oflow: &mut i32) -> u128;
 
     // floats
     fn __floattisf(i: i128) -> f32;
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
index 704d7b9c2fd..73ec6b84a15 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml
@@ -22,7 +22,6 @@ jobs:
           - { gcc: "gcc-13.deb" }
           - { gcc: "gcc-13-without-int128.deb" }
         commands: [
-          "--mini-tests",
           "--std-tests",
           # FIXME: re-enable asm tests when GCC can emit in the right syntax.
           # "--asm-tests",
@@ -79,6 +78,7 @@ jobs:
       run: |
         ./y.sh prepare --only-libcore
         ./y.sh build --sysroot
+        ./y.sh test --mini-tests
         cargo test
 
     - name: Run y.sh cargo build
@@ -87,7 +87,7 @@ jobs:
 
     - name: Clean
       run: |
-        ./y.sh clean all      
+        ./y.sh clean all
 
     - name: Prepare dependencies
       run: |
@@ -95,9 +95,6 @@ jobs:
         git config --global user.name "User"
         ./y.sh prepare
 
-    - name: Add more failing tests because the sysroot is not compiled with LTO
-      run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt
-
     - name: Run tests
       run: |
         ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }}
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
index 2c1ed9ad429..f33d9fcc582 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml
@@ -90,15 +90,12 @@ jobs:
       if: matrix.libgccjit_version.gcc != 'libgccjit12.so'
       run: ./y.sh prepare
 
-    - name: Add more failing tests because the sysroot is not compiled with LTO
-      run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt
-
     - name: Run tests
       # TODO: re-enable those tests for libgccjit 12.
       if: matrix.libgccjit_version.gcc != 'libgccjit12.so'
       id: tests
       run: |
-        ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} | tee output_log
+        ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} 2>&1 | tee output_log
         rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY
 
     - name: Run failing ui pattern tests for ICE
@@ -106,7 +103,7 @@ jobs:
       if: matrix.libgccjit_version.gcc != 'libgccjit12.so'
       id: ui-tests
       run: |
-        ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} | tee output_log_ui
+        ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} 2>&1 | tee output_log_ui
         if grep -q "the compiler unexpectedly panicked" output_log_ui; then
           echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!"
           exit 1
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml b/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
index 7dcad21a02e..4c2ce91e86e 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/gcc12.yml
@@ -82,9 +82,6 @@ jobs:
     #- name: Add more failing tests for GCC 12
       #run: cat tests/failing-ui-tests12.txt >> tests/failing-ui-tests.txt
 
-    #- name: Add more failing tests because the sysroot is not compiled with LTO
-      #run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt
-
     #- name: Run tests
       #run: |
         #./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
index 1c864e04413..07bb372b360 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml
@@ -23,7 +23,6 @@ jobs:
       fail-fast: false
       matrix:
         commands: [
-          "--mini-tests",
           "--std-tests",
           # TODO(antoyo): fix those on m68k.
           #"--test-libcore",
@@ -93,6 +92,7 @@ jobs:
       run: |
         ./y.sh prepare --only-libcore --cross
         ./y.sh build --sysroot --features compiler_builtins/no-f16-f128 --target-triple m68k-unknown-linux-gnu
+        ./y.sh test --mini-tests
         CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test
         ./y.sh clean all
 
@@ -102,9 +102,6 @@ jobs:
         git config --global user.name "User"
         ./y.sh prepare --cross
 
-    - name: Add more failing tests because the sysroot is not compiled with LTO
-      run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt
-
     - name: Run tests
       run: |
         ./y.sh test --release --clean --build-sysroot --sysroot-features compiler_builtins/no-f16-f128 ${{ matrix.commands }}
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/release.yml b/compiler/rustc_codegen_gcc/.github/workflows/release.yml
index d5c06a836db..60e0943c87d 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/release.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/release.yml
@@ -13,7 +13,7 @@ env:
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     strategy:
       fail-fast: false
@@ -54,6 +54,7 @@ jobs:
       run: |
         ./y.sh prepare --only-libcore
         EMBED_LTO_BITCODE=1 ./y.sh build --sysroot --release --release-sysroot
+        ./y.sh test --mini-tests
         cargo test
         ./y.sh clean all
 
@@ -70,4 +71,9 @@ jobs:
       run: |
         # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros.
         echo -n 'lto = "fat"' >> build_system/build_sysroot/Cargo.toml
-        EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }}
+        EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot --keep-lto-tests ${{ matrix.commands }}
+
+    - name: Run y.sh cargo build
+      run: |
+        EMBED_LTO_BITCODE=1 CHANNEL="release" ./y.sh cargo build --release --manifest-path tests/hello-world/Cargo.toml
+        # TODO: grep the asm output for "call my_func" and fail if it is found.
diff --git a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml
index d8818eefa96..d5ae6144496 100644
--- a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml
+++ b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml
@@ -73,10 +73,6 @@ jobs:
         echo "LD_LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV
         echo "LIBRARY_PATH="$(./y.sh info | grep -v Using) >> $GITHUB_ENV
 
-    - name: Build (part 2)
-      run: |
-        cargo test
-
     - name: Clean
       if: ${{ !matrix.cargo_runner }}
       run: |
@@ -92,6 +88,7 @@ jobs:
       if: ${{ !matrix.cargo_runner }}
       run: |
         ./y.sh test --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore
+        cargo test
 
     - name: Run stdarch tests
       if: ${{ !matrix.cargo_runner }}
diff --git a/compiler/rustc_codegen_gcc/.rustfmt.toml b/compiler/rustc_codegen_gcc/.rustfmt.toml
index 725aec25a07..a11bc41680d 100644
--- a/compiler/rustc_codegen_gcc/.rustfmt.toml
+++ b/compiler/rustc_codegen_gcc/.rustfmt.toml
@@ -1,3 +1,5 @@
-version = "Two"
+style_edition = "2024"
 use_small_heuristics = "Max"
 merge_derives = false
+group_imports = "StdExternalCrate"
+imports_granularity = "Module"
diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock
index 6b06e7d7f27..636e75b94a3 100644
--- a/compiler/rustc_codegen_gcc/Cargo.lock
+++ b/compiler/rustc_codegen_gcc/Cargo.lock
@@ -1,6 +1,6 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "aho-corasick"
@@ -12,12 +12,40 @@ dependencies = [
 ]
 
 [[package]]
+name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
 name = "boml"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "85fdb93f04c73bff54305fa437ffea5449c41edcaadfe882f35836206b166ac5"
 
 [[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "errno"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
 name = "fm"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -28,18 +56,18 @@ dependencies = [
 
 [[package]]
 name = "gccjit"
-version = "2.2.0"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb376e98c82d9284c3a17fc1d6bf9bc921055418950238d7a553c27a7e1f6ab"
+checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8"
 dependencies = [
  "gccjit_sys",
 ]
 
 [[package]]
 name = "gccjit_sys"
-version = "0.3.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93b4b1be553b5df790bf25ca2a1d6add81727dc29f8d5c8742468ed306d621d1"
+checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d"
 dependencies = [
  "libc",
 ]
@@ -77,9 +105,15 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.150"
+version = "0.2.168"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
 
 [[package]]
 name = "memchr"
@@ -98,6 +132,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "once_cell"
+version = "1.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+[[package]]
 name = "regex"
 version = "1.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -121,6 +161,20 @@ dependencies = [
  "boml",
  "gccjit",
  "lang_tester",
+ "tempfile",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
 ]
 
 [[package]]
@@ -133,6 +187,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "tempfile"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "once_cell",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
 name = "termcolor"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -205,3 +272,76 @@ name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml
index 4828b7ddb16..63d37358561 100644
--- a/compiler/rustc_codegen_gcc/Cargo.toml
+++ b/compiler/rustc_codegen_gcc/Cargo.toml
@@ -22,15 +22,16 @@ master = ["gccjit/master"]
 default = ["master"]
 
 [dependencies]
-gccjit = "2.2"
+gccjit = "2.4"
 #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" }
 
 # Local copy.
 #gccjit = { path = "../gccjit.rs" }
 
 [dev-dependencies]
-lang_tester = "0.8.0"
 boml = "0.3.1"
+lang_tester = "0.8.0"
+tempfile = "3.7.1"
 
 [profile.dev]
 # By compiling dependencies with optimizations, performing tests gets much faster.
diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs
index c69e240c01d..7cc7336612c 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/test.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs
@@ -93,6 +93,7 @@ struct TestArg {
     sysroot_panic_abort: bool,
     config_info: ConfigInfo,
     sysroot_features: Vec<String>,
+    keep_lto_tests: bool,
 }
 
 impl TestArg {
@@ -128,6 +129,9 @@ impl TestArg {
                 "--sysroot-panic-abort" => {
                     test_arg.sysroot_panic_abort = true;
                 }
+                "--keep-lto-tests" => {
+                    test_arg.keep_lto_tests = true;
+                }
                 "--sysroot-features" => match args.next() {
                     Some(feature) if !feature.is_empty() => {
                         test_arg.sysroot_features.push(feature);
@@ -194,7 +198,7 @@ fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> {
 }
 
 fn clean(_env: &Env, args: &TestArg) -> Result<(), String> {
-    let _ = std::fs::remove_dir_all(&args.config_info.cargo_target_dir);
+    let _ = remove_dir_all(&args.config_info.cargo_target_dir);
     let path = Path::new(&args.config_info.cargo_target_dir).join("gccjit");
     create_dir(&path)
 }
@@ -641,7 +645,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> {
         //failing test is fixed upstream.
         //"https://github.com/marshallpierce/rust-base64", // FIXME: one test is OOM-killed.
         // TODO: ignore the base64 test that is OOM-killed.
-        "https://github.com/time-rs/time",
+        //"https://github.com/time-rs/time", // FIXME: one test fails (https://github.com/time-rs/time/issues/719).
         "https://github.com/rust-lang/log",
         "https://github.com/bitflags/bitflags",
         //"https://github.com/serde-rs/serde", // FIXME: one test fails.
@@ -835,8 +839,7 @@ fn valid_ui_error_pattern_test(file: &str) -> bool {
     .any(|to_ignore| file.ends_with(to_ignore))
 }
 
-#[rustfmt::skip]
-fn contains_ui_error_patterns(file_path: &Path) -> Result<bool, String> {
+fn contains_ui_error_patterns(file_path: &Path, keep_lto_tests: bool) -> Result<bool, String> {
     // Tests generating errors.
     let file = File::open(file_path)
         .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?;
@@ -849,22 +852,38 @@ fn contains_ui_error_patterns(file_path: &Path) -> Result<bool, String> {
             "//@ error-pattern:",
             "//@ build-fail",
             "//@ run-fail",
+            "//@ known-bug",
             "-Cllvm-args",
             "//~",
             "thread",
         ]
-            .iter()
-            .any(|check| line.contains(check))
+        .iter()
+        .any(|check| line.contains(check))
+        {
+            return Ok(true);
+        }
+
+        if !keep_lto_tests
+            && (line.contains("-Clto")
+                || line.contains("-C lto")
+                || line.contains("compile-flags: -Clinker-plugin-lto"))
+            && !line.contains("-Clto=thin")
         {
             return Ok(true);
         }
+
         if line.contains("//[") && line.contains("]~") {
             return Ok(true);
         }
     }
-    if file_path.display().to_string().contains("ambiguous-4-extern.rs") {
+    let file_path = file_path.display().to_string();
+    if file_path.contains("ambiguous-4-extern.rs") {
         eprintln!("nothing found for {file_path:?}");
     }
+    // The files in this directory contain errors.
+    if file_path.contains("/error-emitter/") {
+        return Ok(true);
+    }
     Ok(false)
 }
 
@@ -903,7 +922,7 @@ where
                 rust_path.join("tests/ui"),
                 &mut |_dir| Ok(()),
                 &mut |file_path| {
-                    if contains_ui_error_patterns(file_path)? {
+                    if contains_ui_error_patterns(file_path, args.keep_lto_tests)? {
                         Ok(())
                     } else {
                         remove_file(file_path).map_err(|e| e.to_string())
@@ -928,7 +947,7 @@ where
                     .iter()
                     .any(|name| *name == dir_name)
                     {
-                        std::fs::remove_dir_all(dir).map_err(|error| {
+                        remove_dir_all(dir).map_err(|error| {
                             format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
                         })?;
                     }
@@ -940,27 +959,42 @@ where
 
             // These two functions are used to remove files that are known to not be working currently
             // with the GCC backend to reduce noise.
-            fn dir_handling(dir: &Path) -> Result<(), String> {
-                if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
-                    return Ok(());
-                }
+            fn dir_handling(keep_lto_tests: bool) -> impl Fn(&Path) -> Result<(), String> {
+                move |dir| {
+                    if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
+                        return Ok(());
+                    }
 
-                walk_dir(dir, &mut dir_handling, &mut file_handling, false)
-            }
-            fn file_handling(file_path: &Path) -> Result<(), String> {
-                if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
-                    return Ok(());
+                    walk_dir(
+                        dir,
+                        &mut dir_handling(keep_lto_tests),
+                        &mut file_handling(keep_lto_tests),
+                        false,
+                    )
                 }
-                let path_str = file_path.display().to_string().replace("\\", "/");
-                if valid_ui_error_pattern_test(&path_str) {
-                    return Ok(());
-                } else if contains_ui_error_patterns(file_path)? {
-                    return remove_file(&file_path);
+            }
+
+            fn file_handling(keep_lto_tests: bool) -> impl Fn(&Path) -> Result<(), String> {
+                move |file_path| {
+                    if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
+                        return Ok(());
+                    }
+                    let path_str = file_path.display().to_string().replace("\\", "/");
+                    if valid_ui_error_pattern_test(&path_str) {
+                        return Ok(());
+                    } else if contains_ui_error_patterns(file_path, keep_lto_tests)? {
+                        return remove_file(&file_path);
+                    }
+                    Ok(())
                 }
-                Ok(())
             }
 
-            walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?;
+            walk_dir(
+                rust_path.join("tests/ui"),
+                &mut dir_handling(args.keep_lto_tests),
+                &mut file_handling(args.keep_lto_tests),
+                false,
+            )?;
         }
         let nb_parts = args.nb_parts.unwrap_or(0);
         if nb_parts > 0 {
@@ -1173,7 +1207,7 @@ fn remove_files_callback<'a>(
                     files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty())
                 {
                     let path = rust_path.join(file);
-                    if let Err(e) = std::fs::remove_dir_all(&path) {
+                    if let Err(e) = remove_dir_all(&path) {
                         println!("Failed to remove directory `{}`: {}", path.display(), e);
                     }
                 }
diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs
index cdd151613df..5a4ee0a198c 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core.rs
@@ -170,6 +170,14 @@ impl Add for usize {
     }
 }
 
+impl Add for isize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
 #[lang = "sub"]
 pub trait Sub<RHS = Self> {
     type Output;
@@ -681,7 +689,7 @@ impl<T> Index<usize> for [T] {
     }
 }
 
-extern {
+extern "C" {
     type VaListImpl;
 }
 
diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
index dcfa34cb729..1d51e0a1856 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
@@ -258,13 +258,13 @@ fn main() {
 
     assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
 
-    extern {
+    extern "C" {
         #[linkage = "weak"]
         static ABC: *const u8;
     }
 
     {
-        extern {
+        extern "C" {
             #[linkage = "weak"]
             static ABC: *const u8;
         }
diff --git a/compiler/rustc_codegen_gcc/example/mod_bench.rs b/compiler/rustc_codegen_gcc/example/mod_bench.rs
index cae911c1073..e8a9cade747 100644
--- a/compiler/rustc_codegen_gcc/example/mod_bench.rs
+++ b/compiler/rustc_codegen_gcc/example/mod_bench.rs
@@ -3,7 +3,7 @@
 #![allow(internal_features)]
 
 #[link(name = "c")]
-extern {}
+extern "C" {}
 
 #[panic_handler]
 fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
diff --git a/compiler/rustc_codegen_gcc/example/std_example.rs b/compiler/rustc_codegen_gcc/example/std_example.rs
index 9e43b4635f0..5fa1e0afb06 100644
--- a/compiler/rustc_codegen_gcc/example/std_example.rs
+++ b/compiler/rustc_codegen_gcc/example/std_example.rs
@@ -7,7 +7,7 @@ use std::arch::x86_64::*;
 use std::io::Write;
 use std::ops::Coroutine;
 
-extern {
+extern "C" {
     pub fn printf(format: *const i8, ...) -> i32;
 }
 
diff --git a/compiler/rustc_codegen_gcc/libgccjit.version b/compiler/rustc_codegen_gcc/libgccjit.version
index b9bbbd324c3..ff58accec1d 100644
--- a/compiler/rustc_codegen_gcc/libgccjit.version
+++ b/compiler/rustc_codegen_gcc/libgccjit.version
@@ -1 +1 @@
-e744a9459d33864067214741daf5c5bc2a7b88c6
+45648c2edd4ecd862d9f08196d3d6c6ccba79f07
diff --git a/compiler/rustc_codegen_gcc/patches/0022-core-Disable-not-compiling-tests.patch b/compiler/rustc_codegen_gcc/patches/0022-core-Disable-not-compiling-tests.patch
index b2ab05691ec..70e3e2ba7fe 100644
--- a/compiler/rustc_codegen_gcc/patches/0022-core-Disable-not-compiling-tests.patch
+++ b/compiler/rustc_codegen_gcc/patches/0022-core-Disable-not-compiling-tests.patch
@@ -1,7 +1,7 @@
-From 18793c6109890493ceb3ff36549849a36e3d8022 Mon Sep 17 00:00:00 2001
+From af0e237f056fa838c77463381a19b0dc993c0a35 Mon Sep 17 00:00:00 2001
 From: None <none@example.com>
 Date: Sun, 1 Sep 2024 11:42:17 -0400
-Subject: [PATCH] [core] Disable not compiling tests
+Subject: [PATCH] Disable not compiling tests
 
 ---
  library/core/tests/Cargo.toml | 14 ++++++++++++++
@@ -30,14 +30,15 @@ index 0000000..ca326ac
 +rand = { version = "0.8.5", default-features = false }
 +rand_xorshift = { version = "0.3.0", default-features = false }
 diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
-index 1e336bf..5800ebb 100644
+index a4a7946..ecfe43f 100644
 --- a/library/core/tests/lib.rs
 +++ b/library/core/tests/lib.rs
 @@ -1,4 +1,5 @@
  // tidy-alphabetical-start
 +#![cfg(test)]
- #![cfg_attr(bootstrap, feature(offset_of_nested))]
  #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
  #![cfg_attr(test, feature(cfg_match))]
---
-2.46.0
+ #![feature(alloc_layout_extra)]
+-- 
+2.47.1
+
diff --git a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
index 01461987ffb..9ef5e0e4f46 100644
--- a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
+++ b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
@@ -27,5 +27,4 @@ index b71786c..cf484d5 100644
  mod slice;
  mod str;
  mod str_lossy;
--- 
-2.45.2
+-- 2.45.2
diff --git a/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain
index dca3b0c22e4..940b3de9f74 100644
--- a/compiler/rustc_codegen_gcc/rust-toolchain
+++ b/compiler/rustc_codegen_gcc/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-08-11"
+channel = "nightly-2025-01-12"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs
index f13a75648ae..416f3231a13 100644
--- a/compiler/rustc_codegen_gcc/src/allocator.rs
+++ b/compiler/rustc_codegen_gcc/src/allocator.rs
@@ -1,6 +1,6 @@
-#[cfg(feature = "master")]
-use gccjit::FnAttribute;
 use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
+#[cfg(feature = "master")]
+use gccjit::{FnAttribute, VarAttribute};
 use rustc_ast::expand::allocator::{
     ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
     alloc_error_handler_name, default_fn_name, global_fn_name,
@@ -10,6 +10,8 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::config::OomStrategy;
 
 use crate::GccContext;
+#[cfg(feature = "master")]
+use crate::base::symbol_visibility_to_gcc;
 
 pub(crate) unsafe fn codegen(
     tcx: TyCtxt<'_>,
@@ -70,12 +72,20 @@ pub(crate) unsafe fn codegen(
 
     let name = OomStrategy::SYMBOL.to_string();
     let global = context.new_global(None, GlobalKind::Exported, i8, name);
+    #[cfg(feature = "master")]
+    global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
+        tcx.sess.default_visibility(),
+    )));
     let value = tcx.sess.opts.unstable_opts.oom.should_panic();
     let value = context.new_rvalue_from_int(i8, value as i32);
     global.global_set_initializer_rvalue(value);
 
     let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
     let global = context.new_global(None, GlobalKind::Exported, i8, name);
+    #[cfg(feature = "master")]
+    global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
+        tcx.sess.default_visibility(),
+    )));
     let value = context.new_rvalue_from_int(i8, 0);
     global.global_set_initializer_rvalue(value);
 }
@@ -105,15 +115,9 @@ fn create_wrapper_function(
     );
 
     #[cfg(feature = "master")]
-    match tcx.sess.default_visibility() {
-        rustc_target::spec::SymbolVisibility::Hidden => {
-            func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden))
-        }
-        rustc_target::spec::SymbolVisibility::Protected => {
-            func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected))
-        }
-        rustc_target::spec::SymbolVisibility::Interposable => {}
-    }
+    func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
+        tcx.sess.default_visibility(),
+    )));
 
     if tcx.sess.must_emit_unwind_tables() {
         // TODO(antoyo): emit unwind tables.
diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs
index f7173d4d2ff..e419bd18099 100644
--- a/compiler/rustc_codegen_gcc/src/back/lto.rs
+++ b/compiler/rustc_codegen_gcc/src/back/lto.rs
@@ -35,16 +35,13 @@ use rustc_middle::bug;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
 use rustc_session::config::{CrateType, Lto};
+use rustc_target::spec::RelocModel;
 use tempfile::{TempDir, tempdir};
 
 use crate::back::write::save_temp_bitcode;
 use crate::errors::{DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib};
 use crate::{GccCodegenBackend, GccContext, SyncContext, to_gcc_opt_level};
 
-/// We keep track of the computed LTO cache keys from the previous
-/// session to determine which CGUs we can reuse.
-//pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
-
 pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
     match crate_type {
         CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true,
@@ -54,7 +51,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
 
 struct LtoData {
     // TODO(antoyo): use symbols_below_threshold.
-    //symbols_below_threshold: Vec<CString>,
+    //symbols_below_threshold: Vec<String>,
     upstream_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
 }
@@ -83,7 +80,7 @@ fn prepare_lto(
 
     let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
         if info.level.is_below_threshold(export_threshold) || info.used {
-            Some(CString::new(name.as_str()).unwrap())
+            Some(name.clone())
         } else {
             None
         }
@@ -91,7 +88,7 @@ fn prepare_lto(
     let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO");
     let mut symbols_below_threshold = {
         let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold");
-        exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<CString>>()
+        exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<String>>()
     };
     info!("{} symbols to preserve in this crate", symbols_below_threshold.len());
 
@@ -159,11 +156,7 @@ fn prepare_lto(
         }
     }
 
-    Ok(LtoData {
-        //symbols_below_threshold,
-        upstream_modules,
-        tmp_path,
-    })
+    Ok(LtoData { upstream_modules, tmp_path })
 }
 
 fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> {
@@ -191,7 +184,7 @@ pub(crate) fn run_fat(
         cached_modules,
         lto_data.upstream_modules,
         lto_data.tmp_path,
-        //&symbols_below_threshold,
+        //&lto_data.symbols_below_threshold,
     )
 }
 
@@ -202,7 +195,7 @@ fn fat_lto(
     cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
     mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
-    //symbols_below_threshold: &[*const libc::c_char],
+    //symbols_below_threshold: &[String],
 ) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
     let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module");
     info!("going for a fat lto");
@@ -327,6 +320,7 @@ fn fat_lto(
             ptr as *const *const libc::c_char,
             symbols_below_threshold.len() as libc::size_t,
         );*/
+
         save_temp_bitcode(cgcx, &module, "lto.after-restriction");
         //}
     }
@@ -363,8 +357,6 @@ pub(crate) fn run_thin(
     let dcx = cgcx.create_dcx();
     let dcx = dcx.handle();
     let lto_data = prepare_lto(cgcx, dcx)?;
-    /*let symbols_below_threshold =
-    symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
     if cgcx.opts.cg.linker_plugin_lto.enabled() {
         unreachable!(
             "We should never reach this case if the LTO step \
@@ -377,7 +369,8 @@ pub(crate) fn run_thin(
         modules,
         lto_data.upstream_modules,
         lto_data.tmp_path,
-        cached_modules, /*, &symbols_below_threshold*/
+        cached_modules,
+        //&lto_data.symbols_below_threshold,
     )
 }
 
@@ -428,7 +421,7 @@ fn thin_lto(
     serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
     cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-    //symbols_below_threshold: &[*const libc::c_char],
+    //_symbols_below_threshold: &[String],
 ) -> Result<(Vec<LtoModuleCodegen<GccCodegenBackend>>, Vec<WorkProduct>), FatalError> {
     let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis");
     info!("going for that thin, thin LTO");
@@ -640,7 +633,13 @@ pub unsafe fn optimize_thin_module(
         }
     };
     let module = ModuleCodegen {
-        module_llvm: GccContext { context, should_combine_object_files, temp_dir: None },
+        module_llvm: GccContext {
+            context,
+            should_combine_object_files,
+            // TODO(antoyo): use the correct relocation model here.
+            relocation_model: RelocModel::Pic,
+            temp_dir: None,
+        },
         name: thin_module.name().to_string(),
         kind: ModuleKind::Regular,
     };
diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs
index 802968979c7..51c5ba73e32 100644
--- a/compiler/rustc_codegen_gcc/src/back/write.rs
+++ b/compiler/rustc_codegen_gcc/src/back/write.rs
@@ -1,6 +1,6 @@
 use std::{env, fs};
 
-use gccjit::OutputKind;
+use gccjit::{Context, OutputKind};
 use rustc_codegen_ssa::back::link::ensure_removed;
 use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
@@ -10,6 +10,7 @@ use rustc_session::config::OutputType;
 use rustc_span::fatal_error::FatalError;
 use rustc_target::spec::SplitDebuginfo;
 
+use crate::base::add_pic_option;
 use crate::errors::CopyBitcode;
 use crate::{GccCodegenBackend, GccContext};
 
@@ -31,51 +32,87 @@ pub(crate) unsafe fn codegen(
 
         // NOTE: Only generate object files with GIMPLE when this environment variable is set for
         // now because this requires a particular setup (same gcc/lto1/lto-wrapper commit as libgccjit).
-        // TODO: remove this environment variable.
+        // TODO(antoyo): remove this environment variable.
         let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1");
 
         let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
         let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
 
-        if config.bitcode_needed() && fat_lto {
-            let _timer = cgcx
-                .prof
-                .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name);
-
-            // TODO(antoyo)
-            /*if let Some(bitcode_filename) = bc_out.file_name() {
-                cgcx.prof.artifact_size(
-                    "llvm_bitcode",
-                    bitcode_filename.to_string_lossy(),
-                    data.len() as u64,
-                );
-            }*/
-
-            if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
+        if config.bitcode_needed() {
+            if fat_lto {
                 let _timer = cgcx
                     .prof
-                    .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name);
-                context.add_command_line_option("-flto=auto");
-                context.add_command_line_option("-flto-partition=one");
-                // TODO: remove since we don't want fat objects when it is for Bitcode only.
-                context.add_command_line_option("-ffat-lto-objects");
-                context
-                    .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str"));
-            }
+                    .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name);
 
-            if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
-                let _timer = cgcx
-                    .prof
-                    .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name);
-                // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes?
-                //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
-
-                context.add_command_line_option("-flto=auto");
-                context.add_command_line_option("-flto-partition=one");
-                context.add_command_line_option("-ffat-lto-objects");
-                // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument).
-                context
-                    .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str"));
+                // TODO(antoyo)
+                /*if let Some(bitcode_filename) = bc_out.file_name() {
+                    cgcx.prof.artifact_size(
+                        "llvm_bitcode",
+                        bitcode_filename.to_string_lossy(),
+                        data.len() as u64,
+                    );
+                }*/
+
+                if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "GCC_module_codegen_emit_bitcode",
+                        &*module.name,
+                    );
+                    context.add_command_line_option("-flto=auto");
+                    context.add_command_line_option("-flto-partition=one");
+                    // TODO(antoyo): remove since we don't want fat objects when it is for Bitcode only.
+                    context.add_command_line_option("-ffat-lto-objects");
+                    context.compile_to_file(
+                        OutputKind::ObjectFile,
+                        bc_out.to_str().expect("path to str"),
+                    );
+                }
+
+                if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "GCC_module_codegen_embed_bitcode",
+                        &*module.name,
+                    );
+                    // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes?
+                    //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
+
+                    context.add_command_line_option("-flto=auto");
+                    context.add_command_line_option("-flto-partition=one");
+                    context.add_command_line_option("-ffat-lto-objects");
+                    // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument).
+                    context.compile_to_file(
+                        OutputKind::ObjectFile,
+                        bc_out.to_str().expect("path to str"),
+                    );
+                }
+            } else {
+                if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "GCC_module_codegen_emit_bitcode",
+                        &*module.name,
+                    );
+                    context.compile_to_file(
+                        OutputKind::ObjectFile,
+                        bc_out.to_str().expect("path to str"),
+                    );
+                }
+
+                if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
+                    // TODO(antoyo): we might want to emit to emit an error here, saying to set the
+                    // environment variable EMBED_LTO_BITCODE.
+                    let _timer = cgcx.prof.generic_activity_with_arg(
+                        "GCC_module_codegen_embed_bitcode",
+                        &*module.name,
+                    );
+                    // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes?
+                    //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
+
+                    // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument).
+                    context.compile_to_file(
+                        OutputKind::ObjectFile,
+                        bc_out.to_str().expect("path to str"),
+                    );
+                }
             }
         }
 
@@ -123,6 +160,8 @@ pub(crate) unsafe fn codegen(
 
                         // NOTE: without -fuse-linker-plugin, we get the following error:
                         // lto1: internal compiler error: decompressed stream: Destination buffer is too small
+                        // TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps
+                        // the following flag is not necessary anymore.
                         context.add_driver_option("-fuse-linker-plugin");
                     }
 
@@ -131,11 +170,43 @@ pub(crate) unsafe fn codegen(
                     // /usr/bin/ld: cannot find -lgcc_s: No such file or directory
                     context.add_driver_option("-nostdlib");
 
-                    // NOTE: this doesn't actually generate an executable. With the above flags, it combines the .o files together in another .o.
-                    context.compile_to_file(
-                        OutputKind::Executable,
-                        obj_out.to_str().expect("path to str"),
-                    );
+                    let path = obj_out.to_str().expect("path to str");
+
+                    if fat_lto {
+                        let lto_path = format!("{}.lto", path);
+                        // FIXME(antoyo): The LTO frontend generates the following warning:
+                        // ../build_sysroot/sysroot_src/library/core/src/num/dec2flt/lemire.rs:150:15: warning: type of ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ does not match original declaration [-Wlto-type-mismatch]
+                        // 150 |     let (lo5, hi5) = POWER_OF_FIVE_128[index];
+                        //     |               ^
+                        // lto1: note: ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ was previously declared here
+                        //
+                        // This option is to mute it to make the UI tests pass with LTO enabled.
+                        context.add_driver_option("-Wno-lto-type-mismatch");
+                        // NOTE: this doesn't actually generate an executable. With the above
+                        // flags, it combines the .o files together in another .o.
+                        context.compile_to_file(OutputKind::Executable, &lto_path);
+
+                        let context = Context::default();
+                        if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" {
+                            // NOTE: it seems we need to use add_driver_option instead of
+                            // add_command_line_option here because we use the LTO frontend via gcc.
+                            context.add_driver_option("-masm=intel");
+                        }
+
+                        // NOTE: these two options are needed to invoke LTO to produce an object file.
+                        // We need to initiate a second compilation because the arguments "-x lto"
+                        // needs to be at the very beginning.
+                        context.add_driver_option("-x");
+                        context.add_driver_option("lto");
+                        add_pic_option(&context, module.module_llvm.relocation_model);
+                        context.add_driver_option(lto_path);
+
+                        context.compile_to_file(OutputKind::ObjectFile, path);
+                    } else {
+                        // NOTE: this doesn't actually generate an executable. With the above
+                        // flags, it combines the .o files together in another .o.
+                        context.compile_to_file(OutputKind::Executable, path);
+                    }
                 } else {
                     context.compile_to_file(
                         OutputKind::ObjectFile,
diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs
index 18aa32754e1..c9701fb9885 100644
--- a/compiler/rustc_codegen_gcc/src/base.rs
+++ b/compiler/rustc_codegen_gcc/src/base.rs
@@ -3,7 +3,7 @@ use std::env;
 use std::sync::Arc;
 use std::time::Instant;
 
-use gccjit::{CType, FunctionType, GlobalKind};
+use gccjit::{CType, Context, FunctionType, GlobalKind};
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::DebugInfoCodegenMethods;
@@ -15,21 +15,32 @@ use rustc_middle::mir::mono::Visibility;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::DebugInfo;
 use rustc_span::Symbol;
-use rustc_target::spec::PanicStrategy;
+#[cfg(feature = "master")]
+use rustc_target::spec::SymbolVisibility;
+use rustc_target::spec::{PanicStrategy, RelocModel};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
 use crate::{GccContext, LockedTargetInfo, SyncContext, gcc_util, new_context};
 
 #[cfg(feature = "master")]
-pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility {
-    match linkage {
+pub fn visibility_to_gcc(visibility: Visibility) -> gccjit::Visibility {
+    match visibility {
         Visibility::Default => gccjit::Visibility::Default,
         Visibility::Hidden => gccjit::Visibility::Hidden,
         Visibility::Protected => gccjit::Visibility::Protected,
     }
 }
 
+#[cfg(feature = "master")]
+pub fn symbol_visibility_to_gcc(visibility: SymbolVisibility) -> gccjit::Visibility {
+    match visibility {
+        SymbolVisibility::Hidden => gccjit::Visibility::Hidden,
+        SymbolVisibility::Protected => gccjit::Visibility::Protected,
+        SymbolVisibility::Interposable => gccjit::Visibility::Default,
+    }
+}
+
 pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
     match linkage {
         Linkage::External => GlobalKind::Imported,
@@ -140,9 +151,7 @@ pub fn compile_codegen_unit(
             });
         }
 
-        if tcx.sess.relocation_model() == rustc_target::spec::RelocModel::Static {
-            context.add_command_line_option("-fno-pie");
-        }
+        add_pic_option(&context, tcx.sess.relocation_model());
 
         let target_cpu = gcc_util::target_cpu(tcx.sess);
         if target_cpu != "generic" {
@@ -199,12 +208,13 @@ pub fn compile_codegen_unit(
             let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32);
             let f64_type_supported = target_info.supports_target_dependent_type(CType::Float64);
             let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128);
+            let u128_type_supported = target_info.supports_target_dependent_type(CType::UInt128t);
             // TODO: improve this to avoid passing that many arguments.
             let cx = CodegenCx::new(
                 &context,
                 cgu,
                 tcx,
-                target_info.supports_128bit_int(),
+                u128_type_supported,
                 f16_type_supported,
                 f32_type_supported,
                 f64_type_supported,
@@ -235,6 +245,7 @@ pub fn compile_codegen_unit(
             name: cgu_name.to_string(),
             module_llvm: GccContext {
                 context: Arc::new(SyncContext::new(context)),
+                relocation_model: tcx.sess.relocation_model(),
                 should_combine_object_files: false,
                 temp_dir: None,
             },
@@ -244,3 +255,24 @@ pub fn compile_codegen_unit(
 
     (module, cost)
 }
+
+pub fn add_pic_option<'gcc>(context: &Context<'gcc>, relocation_model: RelocModel) {
+    match relocation_model {
+        rustc_target::spec::RelocModel::Static => {
+            context.add_command_line_option("-fno-pie");
+            context.add_driver_option("-fno-pie");
+        }
+        rustc_target::spec::RelocModel::Pic => {
+            context.add_command_line_option("-fPIC");
+            // NOTE: we use both add_command_line_option and add_driver_option because the usage in
+            // this module (compile_codegen_unit) requires add_command_line_option while the usage
+            // in the back::write module (codegen) requires add_driver_option.
+            context.add_driver_option("-fPIC");
+        }
+        rustc_target::spec::RelocModel::Pie => {
+            context.add_command_line_option("-fPIE");
+            context.add_driver_option("-fPIE");
+        }
+        model => eprintln!("Unsupported relocation model: {:?}", model),
+    }
+}
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 9a142326ad1..89e5cf1b8c6 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1102,18 +1102,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         val: RValue<'gcc>,
         ptr: RValue<'gcc>,
         align: Align,
-        _flags: MemFlags,
+        flags: MemFlags,
     ) -> RValue<'gcc> {
         let ptr = self.check_store(val, ptr);
         let destination = ptr.dereference(self.location);
         // NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast
         // to type so it gets the proper alignment.
         let destination_type = destination.to_rvalue().get_type().unqualified();
-        let aligned_type = destination_type.get_aligned(align.bytes()).make_pointer();
-        let aligned_destination = self.cx.context.new_bitcast(self.location, ptr, aligned_type);
-        let aligned_destination = aligned_destination.dereference(self.location);
-        self.llbb().add_assignment(self.location, aligned_destination, val);
-        // TODO(antoyo): handle align and flags.
+        let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() };
+        let mut modified_destination_type = destination_type.get_aligned(align);
+        if flags.contains(MemFlags::VOLATILE) {
+            modified_destination_type = modified_destination_type.make_volatile();
+        }
+
+        let modified_ptr =
+            self.cx.context.new_cast(self.location, ptr, modified_destination_type.make_pointer());
+        let modified_destination = modified_ptr.dereference(self.location);
+        self.llbb().add_assignment(self.location, modified_destination, val);
+        // TODO(antoyo): handle `MemFlags::NONTEMPORAL`.
         // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here?
         // When adding support for NONTEMPORAL, make sure to not just emit MOVNT on x86; see the
         // LLVM backend for details.
@@ -1236,13 +1242,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
     }
 
     fn ptrtoint(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
-        let usize_value = self.cx.const_bitcast(value, self.cx.type_isize());
+        let usize_value = self.cx.context.new_cast(None, value, self.cx.type_isize());
         self.intcast(usize_value, dest_ty, false)
     }
 
     fn inttoptr(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
         let usize_value = self.intcast(value, self.cx.type_isize(), false);
-        self.cx.const_bitcast(usize_value, dest_ty)
+        self.cx.context.new_cast(None, usize_value, dest_ty)
     }
 
     fn bitcast(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
@@ -1901,6 +1907,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         v2: RValue<'gcc>,
         mask: RValue<'gcc>,
     ) -> RValue<'gcc> {
+        // NOTE: if the `mask` is a constant value, the following code will copy it in many places,
+        // which will make GCC create a lot (+4000) local variables in some cases.
+        // So we assign it to an explicit local variable once to avoid this.
+        let func = self.current_func();
+        let mask_var = func.new_local(self.location, mask.get_type(), "mask");
+        let block = self.block;
+        block.add_assignment(self.location, mask_var, mask);
+        let mask = mask_var.to_rvalue();
+
         // TODO(antoyo): use a recursive unqualified() here.
         let vector_type = v1.get_type().unqualified().dyncast_vector().expect("vector type");
         let element_type = vector_type.get_element_type();
@@ -1917,18 +1932,35 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
             self.int_type
         };
 
-        let vector_type =
-            mask.get_type().dyncast_vector().expect("simd_shuffle mask should be of vector type");
-        let mask_num_units = vector_type.get_num_units();
-        let mut mask_elements = vec![];
-        for i in 0..mask_num_units {
-            let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
-            mask_elements.push(self.context.new_cast(
-                self.location,
-                self.extract_element(mask, index).to_rvalue(),
-                mask_element_type,
-            ));
-        }
+        // NOTE: this condition is needed because we call shuffle_vector in the implementation of
+        // simd_gather.
+        let mut mask_elements = if let Some(vector_type) = mask.get_type().dyncast_vector() {
+            let mask_num_units = vector_type.get_num_units();
+            let mut mask_elements = vec![];
+            for i in 0..mask_num_units {
+                let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
+                mask_elements.push(self.context.new_cast(
+                    self.location,
+                    self.extract_element(mask, index).to_rvalue(),
+                    mask_element_type,
+                ));
+            }
+            mask_elements
+        } else {
+            let struct_type = mask.get_type().is_struct().expect("mask should be of struct type");
+            let mask_num_units = struct_type.get_field_count();
+            let mut mask_elements = vec![];
+            for i in 0..mask_num_units {
+                let field = struct_type.get_field(i as i32);
+                mask_elements.push(self.context.new_cast(
+                    self.location,
+                    mask.access_field(self.location, field).to_rvalue(),
+                    mask_element_type,
+                ));
+            }
+            mask_elements
+        };
+        let mask_num_units = mask_elements.len();
 
         // NOTE: the mask needs to be the same length as the input vectors, so add the missing
         // elements in the mask if needed.
diff --git a/compiler/rustc_codegen_gcc/src/callee.rs b/compiler/rustc_codegen_gcc/src/callee.rs
index 65972a03e83..c133ae4fcdd 100644
--- a/compiler/rustc_codegen_gcc/src/callee.rs
+++ b/compiler/rustc_codegen_gcc/src/callee.rs
@@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
 
         attributes::from_fn_attrs(cx, func, instance);
 
-        let instance_def_id = instance.def_id();
-
-        // TODO(antoyo): set linkage and attributes.
-
-        // Apply an appropriate linkage/visibility value to our item that we
-        // just declared.
-        //
-        // This is sort of subtle. Inside our codegen unit we started off
-        // compilation by predefining all our own `MonoItem` instances. That
-        // is, everything we're codegenning ourselves is already defined. That
-        // means that anything we're actually codegenning in this codegen unit
-        // will have hit the above branch in `get_declared_value`. As a result,
-        // we're guaranteed here that we're declaring a symbol that won't get
-        // defined, or in other words we're referencing a value from another
-        // codegen unit or even another crate.
-        //
-        // So because this is a foreign value we blanket apply an external
-        // linkage directive because it's coming from a different object file.
-        // The visibility here is where it gets tricky. This symbol could be
-        // referencing some foreign crate or foreign library (an `extern`
-        // block) in which case we want to leave the default visibility. We may
-        // also, though, have multiple codegen units. It could be a
-        // monomorphization, in which case its expected visibility depends on
-        // whether we are sharing generics or not. The important thing here is
-        // that the visibility we apply to the declaration is the same one that
-        // has been applied to the definition (wherever that definition may be).
-        let is_generic = instance.args.non_erasable_generics().next().is_some();
-
-        if is_generic {
-            // This is a monomorphization. Its expected visibility depends
-            // on whether we are in share-generics mode.
-
-            if cx.tcx.sess.opts.share_generics() {
-                // We are in share_generics mode.
-
-                if let Some(instance_def_id) = instance_def_id.as_local() {
-                    // This is a definition from the current crate. If the
-                    // definition is unreachable for downstream crates or
-                    // the current crate does not re-export generics, the
-                    // definition of the instance will have been declared
-                    // as `hidden`.
-                    if cx.tcx.is_unreachable_local_definition(instance_def_id)
+        #[cfg(feature = "master")]
+        {
+            let instance_def_id = instance.def_id();
+
+            // TODO(antoyo): set linkage and attributes.
+
+            // Apply an appropriate linkage/visibility value to our item that we
+            // just declared.
+            //
+            // This is sort of subtle. Inside our codegen unit we started off
+            // compilation by predefining all our own `MonoItem` instances. That
+            // is, everything we're codegenning ourselves is already defined. That
+            // means that anything we're actually codegenning in this codegen unit
+            // will have hit the above branch in `get_declared_value`. As a result,
+            // we're guaranteed here that we're declaring a symbol that won't get
+            // defined, or in other words we're referencing a value from another
+            // codegen unit or even another crate.
+            //
+            // So because this is a foreign value we blanket apply an external
+            // linkage directive because it's coming from a different object file.
+            // The visibility here is where it gets tricky. This symbol could be
+            // referencing some foreign crate or foreign library (an `extern`
+            // block) in which case we want to leave the default visibility. We may
+            // also, though, have multiple codegen units. It could be a
+            // monomorphization, in which case its expected visibility depends on
+            // whether we are sharing generics or not. The important thing here is
+            // that the visibility we apply to the declaration is the same one that
+            // has been applied to the definition (wherever that definition may be).
+            let is_generic = instance.args.non_erasable_generics().next().is_some();
+
+            let is_hidden = if is_generic {
+                // This is a monomorphization of a generic function.
+                if !(cx.tcx.sess.opts.share_generics()
+                    || tcx.codegen_fn_attrs(instance_def_id).inline
+                        == rustc_attr_parsing::InlineAttr::Never)
+                {
+                    // When not sharing generics, all instances are in the same
+                    // crate and have hidden visibility.
+                    true
+                } else if let Some(instance_def_id) = instance_def_id.as_local() {
+                    // This is a monomorphization of a generic function
+                    // defined in the current crate. It is hidden if:
+                    // - the definition is unreachable for downstream
+                    //   crates, or
+                    // - the current crate does not re-export generics
+                    //   (because the crate is a C library or executable)
+                    cx.tcx.is_unreachable_local_definition(instance_def_id)
                         || !cx.tcx.local_crate_exports_generics()
-                    {
-                        #[cfg(feature = "master")]
-                        func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                    }
                 } else {
                     // This is a monomorphization of a generic function
-                    // defined in an upstream crate.
-                    if instance.upstream_monomorphization(tcx).is_some() {
-                        // This is instantiated in another crate. It cannot
-                        // be `hidden`.
-                    } else {
-                        // This is a local instantiation of an upstream definition.
-                        // If the current crate does not re-export it
-                        // (because it is a C library or an executable), it
-                        // will have been declared `hidden`.
-                        if !cx.tcx.local_crate_exports_generics() {
-                            #[cfg(feature = "master")]
-                            func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                        }
-                    }
+                    // defined in an upstream crate. It is hidden if:
+                    // - it is instantiated in this crate, and
+                    // - the current crate does not re-export generics
+                    instance.upstream_monomorphization(tcx).is_none()
+                        && !cx.tcx.local_crate_exports_generics()
                 }
             } else {
-                // When not sharing generics, all instances are in the same
-                // crate and have hidden visibility
-                #[cfg(feature = "master")]
+                // This is a non-generic function. It is hidden if:
+                // - it is instantiated in the local crate, and
+                //   - it is defined an upstream crate (non-local), or
+                //   - it is not reachable
+                cx.tcx.is_codegened_item(instance_def_id)
+                    && (!instance_def_id.is_local()
+                        || !cx.tcx.is_reachable_non_generic(instance_def_id))
+            };
+            if is_hidden {
                 func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
             }
-        } else {
-            // This is a non-generic function
-            if cx.tcx.is_codegened_item(instance_def_id) {
-                // This is a function that is instantiated in the local crate
-
-                if instance_def_id.is_local() {
-                    // This is function that is defined in the local crate.
-                    // If it is not reachable, it is hidden.
-                    if !cx.tcx.is_reachable_non_generic(instance_def_id) {
-                        #[cfg(feature = "master")]
-                        func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                    }
-                } else {
-                    // This is a function from an upstream crate that has
-                    // been instantiated here. These are always hidden.
-                    #[cfg(feature = "master")]
-                    func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                }
-            }
         }
 
         func
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index 0d3e7083d56..f43743fc2a4 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -240,14 +240,14 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                     }
                 };
                 let ptr_type = base_addr.get_type();
-                let base_addr = self.const_bitcast(base_addr, self.usize_type);
+                let base_addr = self.context.new_cast(None, base_addr, self.usize_type);
                 let offset =
                     self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
-                let ptr = self.const_bitcast(base_addr + offset, ptr_type);
+                let ptr = self.context.new_cast(None, base_addr + offset, ptr_type);
                 if !matches!(layout.primitive(), Pointer(_)) {
                     self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
                 } else {
-                    self.const_bitcast(ptr, ty)
+                    self.context.new_cast(None, ptr, ty)
                 }
             }
         }
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 6dc2f4ed668..1631ecfeecf 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -252,7 +252,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
             let global = self.declare_global(
                 sym,
                 gcc_type,
-                GlobalKind::Exported,
+                GlobalKind::Imported,
                 is_tls,
                 fn_attrs.link_section,
             );
@@ -404,7 +404,6 @@ fn check_and_apply_linkage<'gcc, 'tcx>(
         // TODO(antoyo): set linkage.
         let value = cx.const_ptrcast(global1.get_address(None), gcc_type);
         global2.global_set_initializer_rvalue(value);
-        // TODO(antoyo): use global_set_initializer() when it will work.
         global2
     } else {
         // Generate an external declaration.
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index f67dcf0cb11..c81c53359fd 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -386,6 +386,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
 impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
     type Value = RValue<'gcc>;
     type Metadata = RValue<'gcc>;
+    // TODO(antoyo): change to Function<'gcc>.
     type Function = RValue<'gcc>;
 
     type BasicBlock = Block<'gcc>;
diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs
index c896246866b..1b59b9ac169 100644
--- a/compiler/rustc_codegen_gcc/src/errors.rs
+++ b/compiler/rustc_codegen_gcc/src/errors.rs
@@ -41,10 +41,6 @@ pub(crate) enum PossibleFeature<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_gcc_lto_not_supported)]
-pub(crate) struct LTONotSupported;
-
-#[derive(Diagnostic)]
 #[diag(codegen_gcc_unwinding_inline_asm)]
 pub(crate) struct UnwindingInlineAsm {
     #[primary_span]
diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs
index 1994a2a3c53..560aff43d65 100644
--- a/compiler/rustc_codegen_gcc/src/gcc_util.rs
+++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs
@@ -66,16 +66,14 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
             // We do the equivalent above in `target_features_cfg`.
             // See <https://github.com/rust-lang/rust/issues/134792>.
             all_rust_features.push((false, feature));
-        } else if !feature.is_empty() {
-            if diagnostics {
-                sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature });
-            }
+        } else if !feature.is_empty() && diagnostics {
+            sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature });
         }
     }
     // Remove features that are meant for rustc, not codegen.
-    all_rust_features.retain(|(_, feature)| {
+    all_rust_features.retain(|&(_, feature)| {
         // Retain if it is not a rustc feature
-        !RUSTC_SPECIFIC_FEATURES.contains(feature)
+        !RUSTC_SPECIFIC_FEATURES.contains(&feature)
     });
 
     // Check feature validity.
@@ -103,7 +101,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
                     };
                     sess.dcx().emit_warn(unknown_feature);
                 }
-                Some((_, stability, _)) => {
+                Some(&(_, stability, _)) => {
                     if let Err(reason) = stability.toggle_allowed() {
                         sess.dcx().emit_warn(ForbiddenCTargetFeature {
                             feature,
@@ -165,29 +163,25 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
     );
 
     // Translate this into GCC features.
-    let feats = all_rust_features
-        .iter()
-        .filter_map(|&(enable, feature)| {
+    let feats =
+        all_rust_features.iter().flat_map(|&(enable, feature)| {
             let enable_disable = if enable { '+' } else { '-' };
             // We run through `to_gcc_features` when
             // passing requests down to GCC. This means that all in-language
             // features also work on the command line instead of having two
             // different names when the GCC name and the Rust name differ.
-            Some(
-                to_gcc_features(sess, feature)
-                    .iter()
-                    .flat_map(|feat| to_gcc_features(sess, feat).into_iter())
-                    .map(|feature| {
-                        if enable_disable == '-' {
-                            format!("-{}", feature)
-                        } else {
-                            feature.to_string()
-                        }
-                    })
-                    .collect::<Vec<_>>(),
-            )
-        })
-        .flatten();
+            to_gcc_features(sess, feature)
+                .iter()
+                .flat_map(|feat| to_gcc_features(sess, feat).into_iter())
+                .map(|feature| {
+                    if enable_disable == '-' {
+                        format!("-{}", feature)
+                    } else {
+                        feature.to_string()
+                    }
+                })
+                .collect::<Vec<_>>()
+        });
     features.extend(feats);
 
     if diagnostics {
diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs
index 02b760dc733..fe6a65bed03 100644
--- a/compiler/rustc_codegen_gcc/src/int.rs
+++ b/compiler/rustc_codegen_gcc/src/int.rs
@@ -90,7 +90,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                     }
                 }
             }
-        } else if a_type.is_vector() && a_type.is_vector() {
+        } else if a_type.is_vector() && b_type.is_vector() {
             a >> b
         } else if a_native && !b_native {
             self.gcc_lshr(a, self.gcc_int_cast(b, a_type))
@@ -322,36 +322,26 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                 },
             }
         } else {
-            match new_kind {
-                Int(I128) | Uint(U128) => {
-                    let func_name = match oop {
-                        OverflowOp::Add => match new_kind {
-                            Int(I128) => "__rust_i128_addo",
-                            Uint(U128) => "__rust_u128_addo",
-                            _ => unreachable!(),
-                        },
-                        OverflowOp::Sub => match new_kind {
-                            Int(I128) => "__rust_i128_subo",
-                            Uint(U128) => "__rust_u128_subo",
-                            _ => unreachable!(),
-                        },
-                        OverflowOp::Mul => match new_kind {
-                            Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead?
-                            Uint(U128) => "__rust_u128_mulo",
-                            _ => unreachable!(),
-                        },
-                    };
-                    return self.operation_with_overflow(func_name, lhs, rhs);
-                }
-                _ => match oop {
-                    OverflowOp::Mul => match new_kind {
-                        Int(I32) => "__mulosi4",
-                        Int(I64) => "__mulodi4",
-                        _ => unreachable!(),
-                    },
-                    _ => unimplemented!("overflow operation for {:?}", new_kind),
+            let (func_name, width) = match oop {
+                OverflowOp::Add => match new_kind {
+                    Int(I128) => ("__rust_i128_addo", 128),
+                    Uint(U128) => ("__rust_u128_addo", 128),
+                    _ => unreachable!(),
                 },
-            }
+                OverflowOp::Sub => match new_kind {
+                    Int(I128) => ("__rust_i128_subo", 128),
+                    Uint(U128) => ("__rust_u128_subo", 128),
+                    _ => unreachable!(),
+                },
+                OverflowOp::Mul => match new_kind {
+                    Int(I32) => ("__mulosi4", 32),
+                    Int(I64) => ("__mulodi4", 64),
+                    Int(I128) => ("__rust_i128_mulo", 128), // TODO(antoyo): use __muloti4d instead?
+                    Uint(U128) => ("__rust_u128_mulo", 128),
+                    _ => unreachable!(),
+                },
+            };
+            return self.operation_with_overflow(func_name, lhs, rhs, width);
         };
 
         let intrinsic = self.context.get_builtin_function(name);
@@ -364,80 +354,87 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         (res.dereference(self.location).to_rvalue(), overflow)
     }
 
+    /// Non-`__builtin_*` overflow operations with a `fn(T, T, &mut i32) -> T` signature.
     pub fn operation_with_overflow(
         &self,
         func_name: &str,
         lhs: RValue<'gcc>,
         rhs: RValue<'gcc>,
+        width: u64,
     ) -> (RValue<'gcc>, RValue<'gcc>) {
         let a_type = lhs.get_type();
         let b_type = rhs.get_type();
         debug_assert!(a_type.dyncast_array().is_some());
         debug_assert!(b_type.dyncast_array().is_some());
+        let overflow_type = self.i32_type;
+        let overflow_param_type = overflow_type.make_pointer();
+        let res_type = a_type;
+
+        let overflow_value =
+            self.current_func().new_local(self.location, overflow_type, "overflow");
+        let overflow_addr = overflow_value.get_address(self.location);
+
         let param_a = self.context.new_parameter(self.location, a_type, "a");
         let param_b = self.context.new_parameter(self.location, b_type, "b");
-        let result_field = self.context.new_field(self.location, a_type, "result");
-        let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow");
-
-        let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]);
+        let param_overflow =
+            self.context.new_parameter(self.location, overflow_param_type, "overflow");
+
+        let a_elem_type = a_type.dyncast_array().expect("non-array a value");
+        debug_assert!(a_elem_type.is_integral());
+        let res_ty = match width {
+            32 => self.tcx.types.i32,
+            64 => self.tcx.types.i64,
+            128 => self.tcx.types.i128,
+            _ => unreachable!("unexpected integer size"),
+        };
         let layout = self
             .tcx
-            .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ret_ty))
+            .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(res_ty))
             .unwrap();
 
         let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
         let mut fn_abi = FnAbi {
-            args: vec![arg_abi.clone(), arg_abi.clone()].into_boxed_slice(),
+            args: vec![arg_abi.clone(), arg_abi.clone(), arg_abi.clone()].into_boxed_slice(),
             ret: arg_abi,
             c_variadic: false,
-            fixed_count: 2,
+            fixed_count: 3,
             conv: Conv::C,
             can_unwind: false,
         };
         fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { unwind: false }).unwrap();
 
-        let indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
-
-        let return_type = self
-            .context
-            .new_struct_type(self.location, "result_overflow", &[result_field, overflow_field]);
-        let result = if indirect {
-            let return_value =
-                self.current_func().new_local(self.location, return_type.as_type(), "return_value");
-            let return_param_type = return_type.as_type().make_pointer();
-            let return_param =
-                self.context.new_parameter(self.location, return_param_type, "return_value");
+        let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. });
+
+        let result = if ret_indirect {
+            let res_value = self.current_func().new_local(self.location, res_type, "result_value");
+            let res_addr = res_value.get_address(self.location);
+            let res_param_type = res_type.make_pointer();
+            let param_res = self.context.new_parameter(self.location, res_param_type, "result");
+
             let func = self.context.new_function(
                 self.location,
                 FunctionType::Extern,
                 self.type_void(),
-                &[return_param, param_a, param_b],
+                &[param_res, param_a, param_b, param_overflow],
                 func_name,
                 false,
             );
-            self.llbb().add_eval(
-                self.location,
-                self.context.new_call(self.location, func, &[
-                    return_value.get_address(self.location),
-                    lhs,
-                    rhs,
-                ]),
-            );
-            return_value.to_rvalue()
+            let _void =
+                self.context.new_call(self.location, func, &[res_addr, lhs, rhs, overflow_addr]);
+            res_value.to_rvalue()
         } else {
             let func = self.context.new_function(
                 self.location,
                 FunctionType::Extern,
-                return_type.as_type(),
-                &[param_a, param_b],
+                res_type,
+                &[param_a, param_b, param_overflow],
                 func_name,
                 false,
             );
-            self.context.new_call(self.location, func, &[lhs, rhs])
+            self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr])
         };
-        let overflow = result.access_field(self.location, overflow_field);
-        let int_result = result.access_field(self.location, result_field);
-        (int_result, overflow)
+
+        (result, self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue())
     }
 
     pub fn gcc_icmp(
@@ -660,7 +657,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                     }
                 }
             }
-        } else if a_type.is_vector() && a_type.is_vector() {
+        } else if a_type.is_vector() && b_type.is_vector() {
             a << b
         } else if a_native && !b_native {
             self.gcc_shl(a, self.gcc_int_cast(b, a_type))
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
index 0a448ded6b1..231307def29 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs
@@ -421,7 +421,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
             | "__builtin_ia32_xsaveopt64" => {
                 let new_args = args.to_vec();
                 let thirty_two = builder.context.new_rvalue_from_int(new_args[1].get_type(), 32);
-                let arg2 = new_args[1] << thirty_two | new_args[2];
+                let arg2 = (new_args[1] << thirty_two) | new_args[2];
                 let arg2_type = gcc_func.get_param_type(1);
                 let arg2 = builder.context.new_cast(None, arg2, arg2_type);
                 args = vec![new_args[0], arg2].into();
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 78ec9741f57..48606f5f91c 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -13,15 +13,16 @@ use rustc_codegen_ssa::common::IntPredicate;
 use rustc_codegen_ssa::errors::InvalidMonomorphization;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
+#[cfg(feature = "master")]
+use rustc_codegen_ssa::traits::MiscCodegenMethods;
 use rustc_codegen_ssa::traits::{
-    ArgAbiBuilderMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods,
+    ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
+    IntrinsicCallBuilderMethods,
 };
-#[cfg(feature = "master")]
-use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods};
 use rustc_middle::bug;
-use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature = "master")]
-use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv};
+use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
+use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{Span, Symbol, sym};
 use rustc_target::abi::HasDataLayout;
@@ -139,6 +140,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
                     &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
                 )
             }
+            sym::fmaf16 => {
+                // TODO(antoyo): use the correct builtin for f16.
+                let func = self.cx.context.get_builtin_function("fmaf");
+                let args: Vec<_> = args
+                    .iter()
+                    .map(|arg| {
+                        self.cx.context.new_cast(self.location, arg.immediate(), self.cx.type_f32())
+                    })
+                    .collect();
+                let result = self.cx.context.new_call(self.location, func, &args);
+                self.cx.context.new_cast(self.location, result, self.cx.type_f16())
+            }
             sym::is_val_statically_known => {
                 let a = args[0].immediate();
                 let builtin = self.context.get_builtin_function("__builtin_constant_p");
@@ -988,7 +1001,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                     128 => "__rust_i128_addo",
                     _ => unreachable!(),
                 };
-                let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs);
+                let (int_result, overflow) =
+                    self.operation_with_overflow(func_name, lhs, rhs, width);
                 self.llbb().add_assignment(self.location, res, int_result);
                 overflow
             };
@@ -1058,7 +1072,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
                     128 => "__rust_i128_subo",
                     _ => unreachable!(),
                 };
-                let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs);
+                let (int_result, overflow) =
+                    self.operation_with_overflow(func_name, lhs, rhs, width);
                 self.llbb().add_assignment(self.location, res, int_result);
                 overflow
             };
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 79d1a06dd46..1be452e5d05 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -379,7 +379,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
         // Make sure this is actually a SIMD vector.
         let idx_ty = args[2].layout.ty;
         let n: u64 = if idx_ty.is_simd()
-            && matches!(idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
+            && matches!(*idx_ty.simd_size_and_type(bx.cx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
         {
             idx_ty.simd_size_and_type(bx.cx.tcx).0
         } else {
@@ -829,6 +829,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
             | sym::simd_flog
             | sym::simd_floor
             | sym::simd_fma
+            | sym::simd_relaxed_fma
             | sym::simd_fpow
             | sym::simd_fpowi
             | sym::simd_fsin
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 7329080ce1f..f6ad0c79de5 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -27,6 +27,8 @@
 // Some "regular" crates we want to share with rustc
 extern crate object;
 extern crate smallvec;
+// FIXME(antoyo): clippy bug: remove the #[allow] when it's fixed.
+#[allow(unused_extern_crates)]
 extern crate tempfile;
 #[macro_use]
 extern crate tracing;
@@ -88,7 +90,6 @@ use std::sync::atomic::Ordering;
 use std::sync::{Arc, Mutex};
 
 use back::lto::{ThinBuffer, ThinData};
-use errors::LTONotSupported;
 use gccjit::{CType, Context, OptimizationLevel};
 #[cfg(feature = "master")]
 use gccjit::{TargetInfo, Version};
@@ -109,9 +110,10 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::ty::TyCtxt;
 use rustc_middle::util::Providers;
 use rustc_session::Session;
-use rustc_session::config::{Lto, OptLevel, OutputFilenames};
+use rustc_session::config::{OptLevel, OutputFilenames};
 use rustc_span::Symbol;
 use rustc_span::fatal_error::FatalError;
+use rustc_target::spec::RelocModel;
 use tempfile::TempDir;
 
 use crate::back::lto::ModuleBuffer;
@@ -141,11 +143,15 @@ impl TargetInfo {
         false
     }
 
-    fn supports_128bit_int(&self) -> bool {
-        self.supports_128bit_integers.load(Ordering::SeqCst)
-    }
-
-    fn supports_target_dependent_type(&self, _typ: CType) -> bool {
+    fn supports_target_dependent_type(&self, typ: CType) -> bool {
+        match typ {
+            CType::UInt128t | CType::Int128t => {
+                if self.supports_128bit_integers.load(Ordering::SeqCst) {
+                    return true;
+                }
+            }
+            _ => (),
+        }
         false
     }
 }
@@ -166,10 +172,6 @@ impl LockedTargetInfo {
         self.info.lock().expect("lock").cpu_supports(feature)
     }
 
-    fn supports_128bit_int(&self) -> bool {
-        self.info.lock().expect("lock").supports_128bit_int()
-    }
-
     fn supports_target_dependent_type(&self, typ: CType) -> bool {
         self.info.lock().expect("lock").supports_target_dependent_type(typ)
     }
@@ -202,10 +204,6 @@ impl CodegenBackend for GccCodegenBackend {
         #[cfg(feature = "master")]
         gccjit::set_global_personality_function_name(b"rust_eh_personality\0");
 
-        if sess.lto() == Lto::Thin {
-            sess.dcx().emit_warn(LTONotSupported {});
-        }
-
         #[cfg(not(feature = "master"))]
         {
             let temp_dir = TempDir::new().expect("cannot create temporary directory");
@@ -297,6 +295,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
     ) -> Self::Module {
         let mut mods = GccContext {
             context: Arc::new(SyncContext::new(new_context(tcx))),
+            relocation_model: tcx.sess.relocation_model(),
             should_combine_object_files: false,
             temp_dir: None,
         };
@@ -328,6 +327,9 @@ impl ExtraBackendMethods for GccCodegenBackend {
 
 pub struct GccContext {
     context: Arc<SyncContext>,
+    /// This field is needed in order to be able to set the flag -fPIC when necessary when doing
+    /// LTO.
+    relocation_model: RelocModel,
     should_combine_object_files: bool,
     // Temporary directory used by LTO. We keep it here so that it's not removed before linking.
     temp_dir: Option<TempDir>,
@@ -492,10 +494,10 @@ fn target_features_cfg(
     sess.target
         .rust_target_features()
         .iter()
-        .filter(|(_, gate, _)| gate.in_cfg())
-        .filter_map(|(feature, gate, _)| {
+        .filter(|&&(_, gate, _)| gate.in_cfg())
+        .filter_map(|&(feature, gate, _)| {
             if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() {
-                Some(*feature)
+                Some(feature)
             } else {
                 None
             }
diff --git a/compiler/rustc_codegen_gcc/tests/failing-non-lto-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-non-lto-tests.txt
deleted file mode 100644
index 384dfdc26fb..00000000000
--- a/compiler/rustc_codegen_gcc/tests/failing-non-lto-tests.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-tests/ui/issues/issue-44056.rs
-tests/ui/lto/fat-lto.rs
-tests/ui/lto/debuginfo-lto.rs
-tests/ui/lto/lto-many-codegen-units.rs
-tests/ui/lto/issue-100772.rs
-tests/ui/lto/lto-rustc-loads-linker-plugin.rs
-tests/ui/panic-runtime/lto-unwind.rs
-tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
-tests/ui/sepcomp/sepcomp-lib-lto.rs
-tests/ui/lto/lto-opt-level-s.rs
-tests/ui/lto/lto-opt-level-z.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
index 457072b1a5b..082958bfe1f 100644
--- a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
+++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
@@ -69,20 +69,22 @@ tests/ui/mir/mir_heavy_promoted.rs
 tests/ui/consts/const_cmp_type_id.rs
 tests/ui/consts/issue-73976-monomorphic.rs
 tests/ui/consts/issue-94675.rs
-tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs
-tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs
+tests/ui/traits/const-traits/const-drop-fail.rs
+tests/ui/traits/const-traits/const-drop.rs
 tests/ui/runtime/on-broken-pipe/child-processes.rs
-tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs
-tests/ui/sanitizer/cfi-async-closures.rs
-tests/ui/sanitizer/cfi-closures.rs
-tests/ui/sanitizer/cfi-complex-receiver.rs
-tests/ui/sanitizer/cfi-coroutine.rs
-tests/ui/sanitizer/cfi-drop-in-place.rs
-tests/ui/sanitizer/cfi-drop-no-principal.rs
-tests/ui/sanitizer/cfi-fn-ptr.rs
-tests/ui/sanitizer/cfi-self-ref.rs
-tests/ui/sanitizer/cfi-supertraits.rs
-tests/ui/sanitizer/cfi-virtual-auto.rs
+tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
+tests/ui/sanitizer/cfi/async-closures.rs
+tests/ui/sanitizer/cfi/closures.rs
+tests/ui/sanitizer/cfi/complex-receiver.rs
+tests/ui/sanitizer/cfi/coroutine.rs
+tests/ui/sanitizer/cfi/drop-in-place.rs
+tests/ui/sanitizer/cfi/drop-no-principal.rs
+tests/ui/sanitizer/cfi/fn-ptr.rs
+tests/ui/sanitizer/cfi/self-ref.rs
+tests/ui/sanitizer/cfi/supertraits.rs
+tests/ui/sanitizer/cfi/virtual-auto.rs
+tests/ui/sanitizer/cfi/sized-associated-ty.rs
+tests/ui/sanitizer/cfi/can-reveal-opaques.rs
 tests/ui/sanitizer/kcfi-mangling.rs
 tests/ui/statics/const_generics.rs
 tests/ui/backtrace/dylib-dep.rs
@@ -91,6 +93,7 @@ tests/ui/delegation/fn-header.rs
 tests/ui/consts/zst_no_llvm_alloc.rs
 tests/ui/consts/const-eval/parse_ints.rs
 tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/simd/intrinsic/generic-as.rs
 tests/ui/backtrace/backtrace.rs
 tests/ui/lifetimes/tail-expr-lock-poisoning.rs
 tests/ui/runtime/rt-explody-panic-payloads.rs
@@ -118,5 +121,4 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
 tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
 tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
 tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
-tests/ui/sanitizer/cfi-sized-associated-ty.rs
-tests/ui/sanitizer/cfi-can-reveal-opaques.rs
+tests/ui/simd/simd-bitmask-notpow2.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt
index 1d9bdaa552c..b10d4bc82aa 100644
--- a/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt
+++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt
@@ -11,7 +11,6 @@ tests/ui/simd/array-type.rs
 tests/ui/simd/intrinsic/float-minmax-pass.rs
 tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
 tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
-tests/ui/simd/intrinsic/generic-as.rs
 tests/ui/simd/intrinsic/generic-cast-pass.rs
 tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
 tests/ui/simd/intrinsic/generic-comparison-pass.rs
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock
new file mode 100644
index 00000000000..fe252db4425
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock
@@ -0,0 +1,14 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "hello_world"
+version = "0.0.0"
+dependencies = [
+ "mylib",
+]
+
+[[package]]
+name = "mylib"
+version = "0.1.0"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml
index 0b8cdc63fbe..c6e22f642f6 100644
--- a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml
@@ -1,4 +1,12 @@
 [package]
 name = "hello_world"
+edition = "2024"
 
 [dependencies]
+mylib = { path = "mylib" }
+
+[profile.dev]
+lto = "thin"
+
+[profile.release]
+lto = "fat"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock
new file mode 100644
index 00000000000..c8a0bfc6354
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock
@@ -0,0 +1,5 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "mylib"
+version = "0.1.0"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml
new file mode 100644
index 00000000000..d15f62bfb6d
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "mylib"
+version = "0.1.0"
+authors = ["Antoni Boucher <bouanto@zoho.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs
new file mode 100644
index 00000000000..8d3d111bd19
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs
@@ -0,0 +1,7 @@
+pub fn my_func(a: i32, b: i32) -> i32 {
+    let mut res = a;
+    for i in a..b {
+        res += i;
+    }
+    res
+}
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs
index e7a11a969c0..71c78d364ac 100644
--- a/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs
@@ -1,3 +1,5 @@
+use mylib::my_func;
+
 fn main() {
-    println!("Hello, world!");
+    println!("{}", my_func(5, 10));
 }
diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs
index aecea37ab5a..64c932a2658 100644
--- a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs
+++ b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs
@@ -1,10 +1,8 @@
 //! The common code for `tests/lang_tests_*.rs`
 
-use std::{
-    env::{self, current_dir},
-    path::{Path, PathBuf},
-    process::Command,
-};
+use std::env::{self, current_dir};
+use std::path::{Path, PathBuf};
+use std::process::Command;
 
 use boml::Toml;
 use lang_tester::LangTester;
@@ -22,14 +20,20 @@ pub fn main_inner(profile: Profile) {
     let tempdir = TempDir::new().expect("temp dir");
     let current_dir = current_dir().expect("current dir");
     let current_dir = current_dir.to_str().expect("current dir").to_string();
-    let toml = Toml::parse(include_str!("../config.toml")).expect("Failed to parse `config.toml`");
-    let gcc_path = if let Ok(gcc_path) = toml.get_string("gcc-path") {
-        PathBuf::from(gcc_path.to_string())
-    } else {
-        // then we try to retrieve it from the `target` folder.
-        let commit = include_str!("../libgccjit.version").trim();
-        Path::new("build/libgccjit").join(commit)
-    };
+
+    let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
+
+    let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml"))
+        .ok()
+        .and_then(|v| {
+            let toml = Toml::parse(&v).expect("Failed to parse `config.toml`");
+            toml.get_string("gcc-path").map(PathBuf::from).ok()
+        })
+        .unwrap_or_else(|| {
+            // then we try to retrieve it from the `target` folder.
+            let commit = include_str!("../libgccjit.version").trim();
+            Path::new("build/libgccjit").join(commit)
+        });
 
     let gcc_path = Path::new(&gcc_path)
         .canonicalize()
@@ -83,6 +87,8 @@ pub fn main_inner(profile: Profile) {
                 &format!("{}/build/build_sysroot/sysroot/", current_dir),
                 "-C",
                 "link-arg=-lc",
+                "--extern",
+                "mini_core=target/out/libmini_core.rlib",
                 "-o",
                 exe.to_str().expect("to_str"),
                 path.to_str().expect("to_str"),
diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs
index d8de9f28d4c..c3c08c29c6d 100644
--- a/compiler/rustc_codegen_gcc/tests/run/array.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/array.rs
@@ -7,38 +7,12 @@
 //     5
 //     10
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for i32 {}
-impl Copy for u8 {}
-impl Copy for i8 {}
-impl Copy for i16 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
@@ -48,182 +22,6 @@ mod libc {
     }
 }
 
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic"]
-#[track_caller]
-#[no_mangle]
-pub fn panic(_msg: &'static str) -> ! {
-    unsafe {
-        libc::puts("Panicking\0" as *const str as *const u8);
-        intrinsics::abort();
-    }
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-#[lang = "add"]
-trait Add<RHS = Self> {
-    type Output;
-
-    fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i32 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for usize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for isize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-#[lang = "sub"]
-pub trait Sub<RHS = Self> {
-    type Output;
-
-    fn sub(self, rhs: RHS) -> Self::Output;
-}
-
-impl Sub for usize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for isize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for u8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for i8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for i16 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-#[track_caller]
-#[lang = "panic_const_add_overflow"]
-pub fn panic_const_add_overflow() -> ! {
-    panic("attempt to add with overflow");
-}
-
-#[track_caller]
-#[lang = "panic_const_sub_overflow"]
-pub fn panic_const_sub_overflow() -> ! {
-    panic("attempt to subtract with overflow");
-}
-
-/*
- * Code
- */
-
 static mut ONE: usize = 1;
 
 fn make_array() -> [u8; 3] {
diff --git a/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs
index b0d0ca4ee8d..46c47bc54ed 100644
--- a/compiler/rustc_codegen_gcc/tests/run/closure.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs
@@ -8,200 +8,20 @@
 //     Int argument: 2
 //     Both args: 11
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics,
-    unboxed_closures, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for i32 {}
-impl Copy for u32 {}
-impl Copy for u8 {}
-impl Copy for i8 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
     extern "C" {
-        pub fn puts(s: *const u8) -> i32;
         pub fn printf(format: *const i8, ...) -> i32;
     }
 }
 
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-#[lang = "tuple_trait"]
-pub trait Tuple {}
-
-#[lang = "unsize"]
-pub trait Unsize<T: ?Sized> {}
-
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
-impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
-
-#[lang = "fn_once"]
-#[rustc_paren_sugar]
-pub trait FnOnce<Args: Tuple> {
-    #[lang = "fn_once_output"]
-    type Output;
-
-    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-}
-
-#[lang = "fn_mut"]
-#[rustc_paren_sugar]
-pub trait FnMut<Args: Tuple>: FnOnce<Args> {
-    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
-}
-
-#[lang = "add"]
-trait Add<RHS = Self> {
-    type Output;
-
-    fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i32 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for usize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for isize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-#[lang = "panic"]
-#[track_caller]
-#[no_mangle]
-pub fn panic(_msg: &'static str) -> ! {
-    unsafe {
-        libc::puts("Panicking\0" as *const str as *const u8);
-        intrinsics::abort();
-    }
-}
-
-#[track_caller]
-#[lang = "panic_const_add_overflow"]
-pub fn panic_const_add_overflow() -> ! {
-    panic("attempt to add with overflow");
-}
-
-/*
- * Code
- */
-
 #[start]
 fn main(mut argc: isize, _argv: *const *const u8) -> isize {
     let string = "Arg: %d\n\0";
diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs
index 770b18a89e3..039ef94eaa7 100644
--- a/compiler/rustc_codegen_gcc/tests/run/condition.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs
@@ -5,304 +5,20 @@
 //   stdout: true
 //     1
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for u64 {}
-impl Copy for i32 {}
-impl Copy for u32 {}
-impl Copy for bool {}
-impl Copy for u16 {}
-impl Copy for i16 {}
-impl Copy for char {}
-impl Copy for i8 {}
-impl Copy for u8 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
     extern "C" {
         pub fn printf(format: *const i8, ...) -> i32;
-        pub fn puts(s: *const u8) -> i32;
-    }
-}
-
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic"]
-#[track_caller]
-#[no_mangle]
-pub fn panic(_msg: &'static str) -> ! {
-    unsafe {
-        libc::puts("Panicking\0" as *const str as *const u8);
-        intrinsics::abort();
-    }
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-#[lang = "add"]
-trait Add<RHS = Self> {
-    type Output;
-
-    fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i32 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for usize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for isize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-#[lang = "sub"]
-pub trait Sub<RHS = Self> {
-    type Output;
-
-    fn sub(self, rhs: RHS) -> Self::Output;
-}
-
-impl Sub for usize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for isize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for u8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for i8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
     }
 }
 
-impl Sub for i16 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-#[lang = "eq"]
-pub trait PartialEq<Rhs: ?Sized = Self> {
-    fn eq(&self, other: &Rhs) -> bool;
-    fn ne(&self, other: &Rhs) -> bool;
-}
-
-impl PartialEq for u8 {
-    fn eq(&self, other: &u8) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &u8) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for u16 {
-    fn eq(&self, other: &u16) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &u16) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for u32 {
-    fn eq(&self, other: &u32) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &u32) -> bool {
-        (*self) != (*other)
-    }
-}
-
-
-impl PartialEq for u64 {
-    fn eq(&self, other: &u64) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &u64) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for usize {
-    fn eq(&self, other: &usize) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &usize) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for i8 {
-    fn eq(&self, other: &i8) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &i8) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for i32 {
-    fn eq(&self, other: &i32) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &i32) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for isize {
-    fn eq(&self, other: &isize) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &isize) -> bool {
-        (*self) != (*other)
-    }
-}
-
-impl PartialEq for char {
-    fn eq(&self, other: &char) -> bool {
-        (*self) == (*other)
-    }
-    fn ne(&self, other: &char) -> bool {
-        (*self) != (*other)
-    }
-}
-
-/*
- * Code
- */
-
 #[start]
 fn main(argc: isize, _argv: *const *const u8) -> isize {
     unsafe {
diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
index 523544ee6bb..ed1bf72bb27 100644
--- a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
@@ -4,212 +4,20 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for i32 {}
-impl Copy for u8 {}
-impl Copy for i8 {}
-impl Copy for i16 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
     extern "C" {
         pub fn printf(format: *const i8, ...) -> i32;
-        pub fn puts(s: *const u8) -> i32;
-    }
-}
-
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic"]
-#[track_caller]
-#[no_mangle]
-pub fn panic(_msg: &'static str) -> ! {
-    unsafe {
-        libc::puts("Panicking\0" as *const str as *const u8);
-        intrinsics::abort();
-    }
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-#[lang = "add"]
-trait Add<RHS = Self> {
-    type Output;
-
-    fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i32 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for usize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for isize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-#[lang = "sub"]
-pub trait Sub<RHS = Self> {
-    type Output;
-
-    fn sub(self, rhs: RHS) -> Self::Output;
-}
-
-impl Sub for usize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for isize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for u8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
     }
 }
 
-impl Sub for i8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for i16 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-
-/*
- * Code
- */
-
 fn i16_as_i8(a: i16) -> i8 {
     a as i8
 }
diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs
index 2e3c021d5f7..0e44fc580b8 100644
--- a/compiler/rustc_codegen_gcc/tests/run/operations.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs
@@ -38,8 +38,8 @@ pub trait Deref {
     fn deref(&self) -> &Self::Target;
 }
 
-#[lang = "receiver"]
-trait Receiver {
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {
 }
 
 #[lang = "freeze"]
diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
index c7510d16449..2b8812ad51c 100644
--- a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
@@ -4,212 +4,20 @@
 //   status: 0
 //   stdout: 1
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for i32 {}
-impl Copy for u8 {}
-impl Copy for i8 {}
-impl Copy for i16 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
     extern "C" {
         pub fn printf(format: *const i8, ...) -> i32;
-        pub fn puts(s: *const u8) -> i32;
-    }
-}
-
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic"]
-#[track_caller]
-#[no_mangle]
-pub fn panic(_msg: &'static str) -> ! {
-    unsafe {
-        libc::puts("Panicking\0" as *const str as *const u8);
-        intrinsics::abort();
-    }
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-#[lang = "add"]
-trait Add<RHS = Self> {
-    type Output;
-
-    fn add(self, rhs: RHS) -> Self::Output;
-}
-
-impl Add for u8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i8 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for i32 {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for usize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-impl Add for isize {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self {
-        self + rhs
-    }
-}
-
-#[lang = "sub"]
-pub trait Sub<RHS = Self> {
-    type Output;
-
-    fn sub(self, rhs: RHS) -> Self::Output;
-}
-
-impl Sub for usize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for isize {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for u8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
     }
 }
 
-impl Sub for i8 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-impl Sub for i16 {
-    type Output = Self;
-
-    fn sub(self, rhs: Self) -> Self {
-        self - rhs
-    }
-}
-
-
-/*
- * Code
- */
-
 static mut ONE: usize = 1;
 
 fn make_array() -> [u8; 3] {
diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
index 8d40deb8c85..f2a5a2e4384 100644
--- a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
@@ -15,18 +15,18 @@
 #[lang = "copy"]
 pub unsafe trait Copy {}
 
-unsafe impl Copy for bool {}
-unsafe impl Copy for u8 {}
-unsafe impl Copy for u16 {}
-unsafe impl Copy for u32 {}
-unsafe impl Copy for u64 {}
-unsafe impl Copy for usize {}
-unsafe impl Copy for i8 {}
-unsafe impl Copy for i16 {}
-unsafe impl Copy for i32 {}
-unsafe impl Copy for isize {}
-unsafe impl Copy for f32 {}
-unsafe impl Copy for char {}
+impl Copy for bool {}
+impl Copy for u8 {}
+impl Copy for u16 {}
+impl Copy for u32 {}
+impl Copy for u64 {}
+impl Copy for usize {}
+impl Copy for i8 {}
+impl Copy for i16 {}
+impl Copy for i32 {}
+impl Copy for isize {}
+impl Copy for f32 {}
+impl Copy for char {}
 
 mod libc {
     #[link(name = "c")]
@@ -43,8 +43,8 @@ mod libc {
 #[lang = "sized"]
 pub trait Sized {}
 
-#[lang = "receiver"]
-trait Receiver {
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {
 }
 
 #[lang = "freeze"]
diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs
index 35ad594ecde..fba93fc1554 100644
--- a/compiler/rustc_codegen_gcc/tests/run/slice.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs
@@ -4,36 +4,12 @@
 //   status: 0
 //   stdout: 5
 
-#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
-#![allow(internal_features)]
+#![feature(no_core, start)]
 
 #![no_std]
 #![no_core]
 
-/*
- * Core
- */
-
-// Because we don't have core yet.
-#[lang = "sized"]
-pub trait Sized {}
-
-#[lang = "copy"]
-trait Copy {
-}
-
-impl Copy for isize {}
-impl Copy for usize {}
-impl Copy for i32 {}
-impl Copy for u32 {}
-impl<T: ?Sized> Copy for *mut T {}
-
-#[lang = "receiver"]
-trait Receiver {
-}
-
-#[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+extern crate mini_core;
 
 mod libc {
     #[link(name = "c")]
@@ -42,79 +18,6 @@ mod libc {
     }
 }
 
-#[lang = "index"]
-pub trait Index<Idx: ?Sized> {
-    type Output: ?Sized;
-    fn index(&self, index: Idx) -> &Self::Output;
-}
-
-impl<T> Index<usize> for [T; 3] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-impl<T> Index<usize> for [T] {
-    type Output = T;
-
-    fn index(&self, index: usize) -> &Self::Output {
-        &self[index]
-    }
-}
-
-#[lang = "unsize"]
-pub trait Unsize<T: ?Sized> {}
-
-#[lang = "coerce_unsized"]
-pub trait CoerceUnsized<T> {}
-
-impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
-impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
-
-#[lang = "drop_in_place"]
-#[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-    // Code here does not matter - this is replaced by the
-    // real drop glue by the compiler.
-    drop_in_place(to_drop);
-}
-
-#[lang = "panic_location"]
-struct PanicLocation {
-    file: &'static str,
-    line: u32,
-    column: u32,
-}
-
-#[lang = "panic_bounds_check"]
-#[track_caller]
-#[no_mangle]
-fn panic_bounds_check(index: usize, len: usize) -> ! {
-    unsafe {
-        libc::printf("index out of bounds: the len is %d but the index is %d\n\0" as *const str as *const i8, len, index);
-        intrinsics::abort();
-    }
-}
-
-mod intrinsics {
-    use super::Sized;
-
-    #[rustc_nounwind]
-    #[rustc_intrinsic]
-    #[rustc_intrinsic_must_be_overridden]
-    pub fn abort() -> ! {
-        loop {}
-    }
-}
-
-/*
- * Code
- */
-
 static mut TWO: usize = 2;
 
 fn index_slice(s: &[u32]) -> u32 {
diff --git a/compiler/rustc_codegen_gcc/tests/run/volatile2.rs b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs
new file mode 100644
index 00000000000..a177b817ab3
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs
@@ -0,0 +1,113 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn puts(s: *const u8) -> i32;
+
+        pub fn sigaction(signum: i32, act: *const sigaction, oldact: *mut sigaction) -> i32;
+        pub fn mmap(addr: *mut (), len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut ();
+        pub fn mprotect(addr: *mut (), len: usize, prot: i32) -> i32;
+    }
+
+    pub const PROT_READ: i32 = 1;
+    pub const PROT_WRITE: i32 = 2;
+    pub const MAP_PRIVATE: i32 = 0x0002;
+    pub const MAP_ANONYMOUS: i32 = 0x0020;
+    pub const MAP_FAILED: *mut u8 = !0 as *mut u8;
+
+    /// glibc sigaction
+    #[repr(C)]
+    pub struct sigaction {
+        pub sa_sigaction: Option<unsafe extern "C" fn(i32, *mut (), *mut ())>,
+        pub sa_mask: [u32; 32],
+        pub sa_flags: i32,
+        pub sa_restorer: Option<unsafe extern "C" fn()>,
+    }
+
+    pub const SA_SIGINFO: i32 = 0x00000004;
+    pub const SIGSEGV: i32 = 11;
+}
+
+static mut COUNT: u32 = 0;
+static mut STORAGE: *mut u8 = core::ptr::null_mut();
+const PAGE_SIZE: usize = 1 << 15;
+
+fn main() {
+    unsafe {
+        // Register a segfault handler
+        libc::sigaction(
+            libc::SIGSEGV,
+            &libc::sigaction {
+                sa_sigaction: Some(segv_handler),
+                sa_flags: libc::SA_SIGINFO,
+                ..core::mem::zeroed()
+            },
+            core::ptr::null_mut(),
+        );
+
+        STORAGE = libc::mmap(
+            core::ptr::null_mut(),
+            PAGE_SIZE * 2,
+            0,
+            libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+            -1,
+            0,
+        ).cast();
+        if STORAGE == libc::MAP_FAILED {
+            panic!("error: mmap failed");
+        }
+
+        let p_count = (&mut COUNT) as *mut u32;
+        p_count.write_volatile(0);
+
+        // Trigger segfaults
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+
+        // The segfault handler should have been called for every `write_volatile` and
+        // `read_volatile` in `STORAGE`. If the compiler ignores volatility, some of these writes
+        // will be combined, causing a different number of segfaults.
+        //
+        // This `p_count` read is done by a volatile read. If the compiler
+        // ignores volatility, the compiler will speculate that `*p_count` is
+        // unchanged and remove this check, failing the test.
+        if p_count.read_volatile() != 14 {
+            panic!("error: segfault count mismatch: {}", p_count.read_volatile());
+        }
+    }
+}
+
+unsafe extern "C" fn segv_handler(_: i32, _: *mut (), _: *mut ()) {
+    let p_count = (&mut COUNT) as *mut u32;
+    p_count.write_volatile(p_count.read_volatile() + 1);
+    let count = p_count.read_volatile();
+
+    // Toggle the protected page so that the handler will be called for
+    // each `write_volatile`
+    libc::mprotect(
+        STORAGE.cast(),
+        PAGE_SIZE,
+        if count % 2 == 1 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+    libc::mprotect(
+        STORAGE.add(PAGE_SIZE).cast(),
+        PAGE_SIZE,
+        if count % 2 == 0 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+}
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 37b53bb5bea..1daa17fbaf3 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -250,10 +250,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                 }
             }
             sym::target_feature => {
-                if !tcx.is_closure_like(did.to_def_id())
-                    && let Some(fn_sig) = fn_sig()
-                    && fn_sig.skip_binder().safety().is_safe()
-                {
+                let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
+                    tcx.dcx().span_delayed_bug(attr.span, "target_feature applied to non-fn");
+                    continue;
+                };
+                let safe_target_features =
+                    matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
+                codegen_fn_attrs.safe_target_features = safe_target_features;
+                if safe_target_features {
                     if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
                         // The `#[target_feature]` attribute is allowed on
                         // WebAssembly targets on all functions, including safe
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 7a5f6c17268..6c940124193 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -35,6 +35,12 @@ use crate::errors;
 type QualifResults<'mir, 'tcx, Q> =
     rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>;
 
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+enum ConstConditionsHold {
+    Yes,
+    No,
+}
+
 #[derive(Default)]
 pub(crate) struct Qualifs<'mir, 'tcx> {
     has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
@@ -376,15 +382,15 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         callee: DefId,
         callee_args: ty::GenericArgsRef<'tcx>,
         call_span: Span,
-    ) -> bool {
+    ) -> Option<ConstConditionsHold> {
         let tcx = self.tcx;
         if !tcx.is_conditionally_const(callee) {
-            return false;
+            return None;
         }
 
         let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
         if const_conditions.is_empty() {
-            return false;
+            return None;
         }
 
         let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
@@ -413,12 +419,13 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         }));
 
         let errors = ocx.select_all_or_error();
-        if !errors.is_empty() {
+        if errors.is_empty() {
+            Some(ConstConditionsHold::Yes)
+        } else {
             tcx.dcx()
                 .span_delayed_bug(call_span, "this should have reported a ~const error in HIR");
+            Some(ConstConditionsHold::No)
         }
-
-        true
     }
 
     pub fn check_drop_terminator(
@@ -706,7 +713,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     trace!("attempting to call a trait method");
                     let trait_is_const = tcx.is_const_trait(trait_did);
 
-                    if trait_is_const {
+                    // Only consider a trait to be const if the const conditions hold.
+                    // Otherwise, it's really misleading to call something "conditionally"
+                    // const when it's very obviously not conditionally const.
+                    if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
                         // Trait calls are always conditionally-const.
                         self.check_op(ops::ConditionallyConstCall {
                             callee,
@@ -730,7 +740,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 }
 
                 // Even if we know the callee, ensure we can use conditionally-const calls.
-                if has_const_conditions {
+                if has_const_conditions.is_some() {
                     self.check_op(ops::ConditionallyConstCall {
                         callee,
                         args: fn_args,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index dd96b30fefc..740c3ee8c07 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3762,9 +3762,30 @@ impl fmt::Display for Constness {
     }
 }
 
+/// The actualy safety specified in syntax. We may treat
+/// its safety different within the type system to create a
+/// "sound by default" system that needs checking this enum
+/// explicitly to allow unsafe operations.
+#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
+pub enum HeaderSafety {
+    /// A safe function annotated with `#[target_features]`.
+    /// The type system treats this function as an unsafe function,
+    /// but safety checking will check this enum to treat it as safe
+    /// and allowing calling other safe target feature functions with
+    /// the same features without requiring an additional unsafe block.
+    SafeTargetFeatures,
+    Normal(Safety),
+}
+
+impl From<Safety> for HeaderSafety {
+    fn from(v: Safety) -> Self {
+        Self::Normal(v)
+    }
+}
+
 #[derive(Copy, Clone, Debug, HashStable_Generic)]
 pub struct FnHeader {
-    pub safety: Safety,
+    pub safety: HeaderSafety,
     pub constness: Constness,
     pub asyncness: IsAsync,
     pub abi: ExternAbi,
@@ -3780,7 +3801,18 @@ impl FnHeader {
     }
 
     pub fn is_unsafe(&self) -> bool {
-        self.safety.is_unsafe()
+        self.safety().is_unsafe()
+    }
+
+    pub fn is_safe(&self) -> bool {
+        self.safety().is_safe()
+    }
+
+    pub fn safety(&self) -> Safety {
+        match self.safety {
+            HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
+            HeaderSafety::Normal(safety) => safety,
+        }
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 0c3ed9b5c60..d7ab6eca84b 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -135,7 +135,7 @@ hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait
 
 hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
 
-hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
     .note = extra field `{$name}` of type `{$ty}` is not allowed
 
 hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 3b98f358b1e..b43a808ccdc 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -259,19 +259,37 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
             let coerced_fields = fields
                 .iter()
                 .filter(|field| {
+                    // Ignore PhantomData fields
+                    let unnormalized_ty = tcx.type_of(field.did).instantiate_identity();
+                    if tcx
+                        .try_normalize_erasing_regions(
+                            ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
+                            unnormalized_ty,
+                        )
+                        .unwrap_or(unnormalized_ty)
+                        .is_phantom_data()
+                    {
+                        return false;
+                    }
+
                     let ty_a = field.ty(tcx, args_a);
                     let ty_b = field.ty(tcx, args_b);
 
-                    if let Ok(layout) =
-                        tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
-                    {
-                        if layout.is_1zst() {
+                    // FIXME: We could do normalization here, but is it really worth it?
+                    if ty_a == ty_b {
+                        // Allow 1-ZSTs that don't mention type params.
+                        //
+                        // Allowing type params here would allow us to possibly transmute
+                        // between ZSTs, which may be used to create library unsoundness.
+                        if let Ok(layout) =
+                            tcx.layout_of(infcx.typing_env(param_env).as_query_input(ty_a))
+                            && layout.is_1zst()
+                            && !ty_a.has_non_region_param()
+                        {
                             // ignore 1-ZST fields
                             return false;
                         }
-                    }
 
-                    if ty_a == ty_b {
                         res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST {
                             span,
                             name: field.name,
@@ -460,8 +478,16 @@ pub(crate) fn coerce_unsized_info<'tcx>(
                 .filter_map(|(i, f)| {
                     let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b));
 
-                    if tcx.type_of(f.did).instantiate_identity().is_phantom_data() {
-                        // Ignore PhantomData fields
+                    // Ignore PhantomData fields
+                    let unnormalized_ty = tcx.type_of(f.did).instantiate_identity();
+                    if tcx
+                        .try_normalize_erasing_regions(
+                            ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
+                            unnormalized_ty,
+                        )
+                        .unwrap_or(unnormalized_ty)
+                        .is_phantom_data()
+                    {
                         return None;
                     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index d41b03640b6..86c6532c97d 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1336,7 +1336,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
             {
                 icx.lowerer().lower_fn_ty(
                     hir_id,
-                    sig.header.safety,
+                    sig.header.safety(),
                     sig.header.abi,
                     sig.decl,
                     Some(generics),
@@ -1351,13 +1351,18 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
             kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
             generics,
             ..
-        }) => {
-            icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None)
-        }
+        }) => icx.lowerer().lower_fn_ty(
+            hir_id,
+            header.safety(),
+            header.abi,
+            decl,
+            Some(generics),
+            None,
+        ),
 
         ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
             let abi = tcx.hir().get_foreign_abi(hir_id);
-            compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety)
+            compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
         }
 
         Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
@@ -1405,7 +1410,7 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
 
     icx.lowerer().lower_fn_ty(
         icx.tcx().local_def_id_to_hir_id(def_id),
-        sig.header.safety,
+        sig.header.safety(),
         sig.header.abi,
         sig.decl,
         Some(generics),
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 0623d35853e..7a3d921f00e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -179,7 +179,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // all visible traits. If there's one clear winner, just suggest that.
 
         let visible_traits: Vec<_> = tcx
-            .all_traits()
+            .visible_traits()
             .filter(|trait_def_id| {
                 let viz = tcx.visibility(*trait_def_id);
                 let def_id = self.item_def_id();
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 39b6823cf0e..3ff6acd79fc 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2407,7 +2407,7 @@ impl<'a> State<'a> {
         self.print_fn(
             decl,
             hir::FnHeader {
-                safety,
+                safety: safety.into(),
                 abi,
                 constness: hir::Constness::NotConst,
                 asyncness: hir::IsAsync::NotAsync,
@@ -2423,12 +2423,20 @@ impl<'a> State<'a> {
     fn print_fn_header_info(&mut self, header: hir::FnHeader) {
         self.print_constness(header.constness);
 
+        let safety = match header.safety {
+            hir::HeaderSafety::SafeTargetFeatures => {
+                self.word_nbsp("#[target_feature]");
+                hir::Safety::Safe
+            }
+            hir::HeaderSafety::Normal(safety) => safety,
+        };
+
         match header.asyncness {
             hir::IsAsync::NotAsync => {}
             hir::IsAsync::Async(_) => self.word_nbsp("async"),
         }
 
-        self.print_safety(header.safety);
+        self.print_safety(safety);
 
         if header.abi != ExternAbi::Rust {
             self.word_nbsp("extern");
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 9ebc7a4657e..ec7c1efa38e 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -932,10 +932,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                         return Err(TypeError::ForceInlineCast);
                     }
 
-                    // Safe `#[target_feature]` functions are not assignable to safe fn pointers
-                    // (RFC 2396).
+                    let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
+                    if matches!(fn_attrs.inline, InlineAttr::Force { .. }) {
+                        return Err(TypeError::ForceInlineCast);
+                    }
+
+                    // FIXME(target_feature): Safe `#[target_feature]` functions could be cast to safe fn pointers (RFC 2396),
+                    // as you can already write that "cast" in user code by wrapping a target_feature fn call in a closure,
+                    // which is safe. This is sound because you already need to be executing code that is satisfying the target
+                    // feature constraints..
                     if b_hdr.safety.is_safe()
-                        && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
+                        && self.tcx.codegen_fn_attrs(def_id).safe_target_features
                     {
                         return Err(TypeError::TargetFeatureCast(def_id));
                     }
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index a406ec9a8fb..cb21961f36b 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -139,7 +139,7 @@ fn typeck_with_fallback<'tcx>(
             // type that has an infer in it, lower the type directly so that it'll
             // be correctly filled with infer. We'll use this inference to provide
             // a suggestion later on.
-            fcx.lowerer().lower_fn_ty(id, header.safety, header.abi, decl, None, None)
+            fcx.lowerer().lower_fn_ty(id, header.safety(), header.abi, decl, None, None)
         } else {
             tcx.fn_sig(def_id).instantiate_identity()
         };
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 0c6147f4a46..9fc527a6a3a 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3597,7 +3597,7 @@ declare_lint! {
     ///
     /// [Other ABIs]: https://doc.rust-lang.org/reference/items/external-blocks.html#abi
     pub MISSING_ABI,
-    Allow,
+    Warn,
     "No declared ABI for extern declaration"
 }
 
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 1ea075c2cb3..6512176cc4a 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -29,7 +29,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
 use rustc_span::edition::Edition;
-use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
+use rustc_span::{DUMMY_SP, Ident, STDLIB_STABLE_CRATES, Span, Symbol, sym};
 use rustc_target::spec::{PanicStrategy, Target, TargetTuple};
 use tracing::{debug, info, trace};
 
@@ -390,19 +390,51 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         None
     }
 
-    // The `dependency` type is determined by the command line arguments(`--extern`) and
-    // `private_dep`. However, sometimes the directly dependent crate is not specified by
-    // `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the
-    // scenario where the command parameter is set to `public-dependency`
-    fn is_private_dep(&self, name: &str, private_dep: Option<bool>) -> bool {
-        self.sess.opts.externs.get(name).map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
-            && private_dep.unwrap_or(true)
+    /// Determine whether a dependency should be considered private.
+    ///
+    /// Dependencies are private if they get extern option specified, e.g. `--extern priv:mycrate`.
+    /// This is stored in metadata, so `private_dep`  can be correctly set during load. A `Some`
+    /// value for `private_dep` indicates that the crate is known to be private or public (note
+    /// that any `None` or `Some(false)` use of the same crate will make it public).
+    ///
+    /// Sometimes the directly dependent crate is not specified by `--extern`, in this case,
+    /// `private-dep` is none during loading. This is equivalent to the scenario where the
+    /// command parameter is set to `public-dependency`
+    fn is_private_dep(
+        &self,
+        name: Symbol,
+        private_dep: Option<bool>,
+        dep_root: Option<&CratePaths>,
+    ) -> bool {
+        // Standard library crates are never private.
+        if STDLIB_STABLE_CRATES.contains(&name) {
+            tracing::info!("returning false for {name} is private");
+            return false;
+        }
+
+        let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep);
+
+        // Any descendants of `std` should be private. These crates are usually not marked
+        // private in metadata, so we ignore that field.
+        if extern_private.is_none()
+            && dep_root.map_or(false, |d| STDLIB_STABLE_CRATES.contains(&d.name))
+        {
+            return true;
+        }
+
+        match (extern_private, private_dep) {
+            // Explicit non-private via `--extern`, explicit non-private from metadata, or
+            // unspecified with default to public.
+            (Some(false), _) | (_, Some(false)) | (None, None) => false,
+            // Marked private via `--extern priv:mycrate` or in metadata.
+            (Some(true) | None, Some(true) | None) => true,
+        }
     }
 
     fn register_crate(
         &mut self,
         host_lib: Option<Library>,
-        root: Option<&CratePaths>,
+        dep_root: Option<&CratePaths>,
         lib: Library,
         dep_kind: CrateDepKind,
         name: Symbol,
@@ -414,7 +446,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         let Library { source, metadata } = lib;
         let crate_root = metadata.get_root();
         let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
-        let private_dep = self.is_private_dep(name.as_str(), private_dep);
+        let private_dep = self.is_private_dep(name, private_dep, dep_root);
 
         // Claim this crate number and cache it
         let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
@@ -430,14 +462,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         // Maintain a reference to the top most crate.
         // Stash paths for top-most crate locally if necessary.
         let crate_paths;
-        let root = if let Some(root) = root {
-            root
+        let dep_root = if let Some(dep_root) = dep_root {
+            dep_root
         } else {
             crate_paths = CratePaths::new(crate_root.name(), source.clone());
             &crate_paths
         };
 
-        let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, dep_kind)?;
+        let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
 
         let raw_proc_macros = if crate_root.is_proc_macro_crate() {
             let temp_root;
@@ -559,23 +591,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         &'b mut self,
         name: Symbol,
         mut dep_kind: CrateDepKind,
-        dep: Option<(&'b CratePaths, &'b CrateDep)>,
+        dep_of: Option<(&'b CratePaths, &'b CrateDep)>,
     ) -> Result<CrateNum, CrateError> {
         info!("resolving crate `{}`", name);
         if !name.as_str().is_ascii() {
             return Err(CrateError::NonAsciiName(name));
         }
-        let (root, hash, host_hash, extra_filename, path_kind, private_dep) = match dep {
-            Some((root, dep)) => (
-                Some(root),
-                Some(dep.hash),
-                dep.host_hash,
-                Some(&dep.extra_filename[..]),
-                PathKind::Dependency,
-                Some(dep.is_private),
-            ),
-            None => (None, None, None, None, PathKind::Crate, None),
-        };
+
+        let dep_root = dep_of.map(|d| d.0);
+        let dep = dep_of.map(|d| d.1);
+        let hash = dep.map(|d| d.hash);
+        let host_hash = dep.map(|d| d.host_hash).flatten();
+        let extra_filename = dep.map(|d| &d.extra_filename[..]);
+        let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
+        let private_dep = dep.map(|d| d.is_private);
+
         let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
             (LoadResult::Previous(cnum), None)
         } else {
@@ -599,7 +629,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
                     dep_kind = CrateDepKind::MacrosOnly;
                     match self.load_proc_macro(&mut locator, path_kind, host_hash)? {
                         Some(res) => res,
-                        None => return Err(locator.into_error(root.cloned())),
+                        None => return Err(locator.into_error(dep_root.cloned())),
                     }
                 }
             }
@@ -612,7 +642,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
                 // not specified by `--extern` on command line parameters, it may be
                 // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
                 // `public-dependency` here.
-                let private_dep = self.is_private_dep(name.as_str(), private_dep);
+                let private_dep = self.is_private_dep(name, private_dep, dep_root);
                 let data = self.cstore.get_crate_data_mut(cnum);
                 if data.is_proc_macro_crate() {
                     dep_kind = CrateDepKind::MacrosOnly;
@@ -623,7 +653,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
             }
             (LoadResult::Loaded(library), host_library) => {
                 info!("register newly loaded library for `{}`", name);
-                self.register_crate(host_library, root, library, dep_kind, name, private_dep)
+                self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep)
             }
             _ => panic!(),
         }
@@ -663,16 +693,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         }))
     }
 
-    // Go through the crate metadata and load any crates that it references
+    /// Go through the crate metadata and load any crates that it references.
     fn resolve_crate_deps(
         &mut self,
-        root: &CratePaths,
+        dep_root: &CratePaths,
         crate_root: &CrateRoot,
         metadata: &MetadataBlob,
         krate: CrateNum,
         dep_kind: CrateDepKind,
     ) -> Result<CrateNumMap, CrateError> {
-        debug!("resolving deps of external crate");
+        debug!(
+            "resolving deps of external crate `{}` with dep root `{}`",
+            crate_root.name(),
+            dep_root.name
+        );
         if crate_root.is_proc_macro_crate() {
             return Ok(CrateNumMap::new());
         }
@@ -685,14 +719,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         crate_num_map.push(krate);
         for dep in deps {
             info!(
-                "resolving dep crate {} hash: `{}` extra filename: `{}`",
-                dep.name, dep.hash, dep.extra_filename
+                "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`",
+                crate_root.name(),
+                dep.name,
+                dep.hash,
+                dep.extra_filename
             );
             let dep_kind = match dep_kind {
                 CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
                 _ => dep.kind,
             };
-            let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?;
+            let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?;
             crate_num_map.push(cnum);
         }
 
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index b9ebf17af24..2ddabeb49f7 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -262,7 +262,7 @@ pub(crate) struct CrateLocator<'a> {
 
 #[derive(Clone)]
 pub(crate) struct CratePaths {
-    name: Symbol,
+    pub(crate) name: Symbol,
     source: CrateSource,
 }
 
@@ -765,10 +765,10 @@ impl<'a> CrateLocator<'a> {
         self.extract_lib(rlibs, rmetas, dylibs).map(|opt| opt.map(|(_, lib)| lib))
     }
 
-    pub(crate) fn into_error(self, root: Option<CratePaths>) -> CrateError {
+    pub(crate) fn into_error(self, dep_root: Option<CratePaths>) -> CrateError {
         CrateError::LocatorCombined(Box::new(CombinedLocatorError {
             crate_name: self.crate_name,
-            root,
+            dep_root,
             triple: self.tuple,
             dll_prefix: self.target.dll_prefix.to_string(),
             dll_suffix: self.target.dll_suffix.to_string(),
@@ -914,7 +914,7 @@ struct CrateRejections {
 /// otherwise they are ignored.
 pub(crate) struct CombinedLocatorError {
     crate_name: Symbol,
-    root: Option<CratePaths>,
+    dep_root: Option<CratePaths>,
     triple: TargetTuple,
     dll_prefix: String,
     dll_suffix: String,
@@ -987,7 +987,7 @@ impl CrateError {
             }
             CrateError::LocatorCombined(locator) => {
                 let crate_name = locator.crate_name;
-                let add_info = match &locator.root {
+                let add_info = match &locator.dep_root {
                     None => String::new(),
                     Some(r) => format!(" which `{}` depends on", r.name),
                 };
@@ -1012,7 +1012,7 @@ impl CrateError {
                             path.display()
                         ));
                     }
-                    if let Some(r) = locator.root {
+                    if let Some(r) = locator.dep_root {
                         for path in r.source.paths() {
                             found_crates.push_str(&format!(
                                 "\ncrate `{}`: {}",
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 16d868300db..e05f42af6fd 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -30,6 +30,8 @@ pub struct CodegenFnAttrs {
     /// features (only enabled features are supported right now).
     /// Implied target features have already been applied.
     pub target_features: Vec<TargetFeature>,
+    /// Whether the function was declared safe, but has target features
+    pub safe_target_features: bool,
     /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
     pub linkage: Option<Linkage>,
     /// The `#[linkage = "..."]` attribute on foreign items and the value we found.
@@ -150,6 +152,7 @@ impl CodegenFnAttrs {
             link_name: None,
             link_ordinal: None,
             target_features: vec![],
+            safe_target_features: false,
             linkage: None,
             import_linkage: None,
             link_section: None,
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 84c3c2eb49e..75ca289056e 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -30,6 +30,14 @@ pub enum StabilityLevel {
     Stable,
 }
 
+#[derive(Copy, Clone)]
+pub enum UnstableKind {
+    /// Enforcing regular stability of an item
+    Regular,
+    /// Enforcing const stability of an item
+    Const(Span),
+}
+
 /// An entry in the `depr_map`.
 #[derive(Copy, Clone, HashStable, Debug, Encodable, Decodable)]
 pub struct DeprecationEntry {
@@ -108,10 +116,16 @@ pub fn report_unstable(
     is_soft: bool,
     span: Span,
     soft_handler: impl FnOnce(&'static Lint, Span, String),
+    kind: UnstableKind,
 ) {
+    let qual = match kind {
+        UnstableKind::Regular => "",
+        UnstableKind::Const(_) => " const",
+    };
+
     let msg = match reason {
-        Some(r) => format!("use of unstable library feature `{feature}`: {r}"),
-        None => format!("use of unstable library feature `{feature}`"),
+        Some(r) => format!("use of unstable{qual} library feature `{feature}`: {r}"),
+        None => format!("use of unstable{qual} library feature `{feature}`"),
     };
 
     if is_soft {
@@ -121,6 +135,9 @@ pub fn report_unstable(
         if let Some((inner_types, msg, sugg, applicability)) = suggestion {
             err.span_suggestion(inner_types, msg, sugg, applicability);
         }
+        if let UnstableKind::Const(kw) = kind {
+            err.span_label(kw, "trait is not stable as const yet");
+        }
         err.emit();
     }
 }
@@ -587,6 +604,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 is_soft,
                 span,
                 soft_handler,
+                UnstableKind::Regular,
             ),
             EvalResult::Unmarked => unmarked(span, def_id),
         }
@@ -594,6 +612,73 @@ impl<'tcx> TyCtxt<'tcx> {
         is_allowed
     }
 
+    /// This function is analogous to `check_optional_stability` but with the logic in
+    /// `eval_stability_allow_unstable` inlined, and which operating on const stability
+    /// instead of regular stability.
+    ///
+    /// This enforces *syntactical* const stability of const traits. In other words,
+    /// it enforces the ability to name `~const`/`const` traits in trait bounds in various
+    /// syntax positions in HIR (including in the trait of an impl header).
+    pub fn check_const_stability(self, def_id: DefId, span: Span, const_kw_span: Span) {
+        let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
+        if !is_staged_api {
+            return;
+        }
+
+        // Only the cross-crate scenario matters when checking unstable APIs
+        let cross_crate = !def_id.is_local();
+        if !cross_crate {
+            return;
+        }
+
+        let stability = self.lookup_const_stability(def_id);
+        debug!(
+            "stability: \
+                inspecting def_id={:?} span={:?} of stability={:?}",
+            def_id, span, stability
+        );
+
+        match stability {
+            Some(ConstStability {
+                level: attr::StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. },
+                feature,
+                ..
+            }) => {
+                assert!(!is_soft);
+
+                if span.allows_unstable(feature) {
+                    debug!("body stability: skipping span={:?} since it is internal", span);
+                    return;
+                }
+                if self.features().enabled(feature) {
+                    return;
+                }
+
+                // If this item was previously part of a now-stabilized feature which is still
+                // enabled (i.e. the user hasn't removed the attribute for the stabilized feature
+                // yet) then allow use of this item.
+                if let Some(implied_by) = implied_by
+                    && self.features().enabled(implied_by)
+                {
+                    return;
+                }
+
+                report_unstable(
+                    self.sess,
+                    feature,
+                    reason.to_opt_reason(),
+                    issue,
+                    None,
+                    false,
+                    span,
+                    |_, _, _| {},
+                    UnstableKind::Const(const_kw_span),
+                );
+            }
+            Some(_) | None => {}
+        }
+    }
+
     pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
         self.lookup_deprecation_entry(id).map(|depr| depr.attr)
     }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 5516770726d..bfbcb0532c1 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2129,6 +2129,8 @@ rustc_queries! {
         eval_always
         desc { "calculating the stability index for the local crate" }
     }
+    /// All available crates in the graph, including those that should not be user-facing
+    /// (such as private crates).
     query crates(_: ()) -> &'tcx [CrateNum] {
         eval_always
         desc { "fetching all foreign CrateNum instances" }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 24f10b4fbe7..fab0047babf 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2078,12 +2078,23 @@ impl<'tcx> TyCtxt<'tcx> {
         self.limits(()).move_size_limit
     }
 
+    /// All traits in the crate graph, including those not visible to the user.
     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
         iter::once(LOCAL_CRATE)
             .chain(self.crates(()).iter().copied())
             .flat_map(move |cnum| self.traits(cnum).iter().copied())
     }
 
+    /// All traits that are visible within the crate graph (i.e. excluding private dependencies).
+    pub fn visible_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
+        let visible_crates =
+            self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
+
+        iter::once(LOCAL_CRATE)
+            .chain(visible_crates)
+            .flat_map(move |cnum| self.traits(cnum).iter().copied())
+    }
+
     #[inline]
     pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
         self.visibility(def_id).expect_local()
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index bf0ccdc0f10..d2875fb3794 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -222,6 +222,7 @@ pub struct DelegationFnSig {
     pub param_count: usize,
     pub has_self: bool,
     pub c_variadic: bool,
+    pub target_feature: bool,
 }
 
 #[derive(Clone, Copy, Debug)]
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 9fe1caa4b58..ac900edefe1 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -690,7 +690,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 if with_reduced_queries() {
                     p!(print_def_path(def_id, args));
                 } else {
-                    let sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
+                    let mut sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
+                    if self.tcx().codegen_fn_attrs(def_id).safe_target_features {
+                        p!("#[target_features] ");
+                        sig = sig.map_bound(|mut sig| {
+                            sig.safety = hir::Safety::Safe;
+                            sig
+                        });
+                    }
                     p!(print(sig), " {{", print_value_path(def_id, args), "}}");
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 4272893df30..75893da0e58 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -876,6 +876,11 @@ impl<'tcx> TyCtxt<'tcx> {
     /// [public]: TyCtxt::is_private_dep
     /// [direct]: rustc_session::cstore::ExternCrate::is_direct
     pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
+        // `#![rustc_private]` overrides defaults to make private dependencies usable.
+        if self.features().enabled(sym::rustc_private) {
+            return true;
+        }
+
         // | Private | Direct | Visible |                    |
         // |---------|--------|---------|--------------------|
         // | Yes     | Yes    | Yes     | !true || true   |
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f7071eb139f..6279d0f94af 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -478,19 +478,27 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 return; // don't visit the whole expression
             }
             ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
-                if self.thir[fun].ty.fn_sig(self.tcx).safety().is_unsafe() {
-                    let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() {
+                let fn_ty = self.thir[fun].ty;
+                let sig = fn_ty.fn_sig(self.tcx);
+                let (callee_features, safe_target_features): (&[_], _) = match fn_ty.kind() {
+                    ty::FnDef(func_id, ..) => {
+                        let cg_attrs = self.tcx.codegen_fn_attrs(func_id);
+                        (&cg_attrs.target_features, cg_attrs.safe_target_features)
+                    }
+                    _ => (&[], false),
+                };
+                if sig.safety().is_unsafe() && !safe_target_features {
+                    let func_id = if let ty::FnDef(func_id, _) = fn_ty.kind() {
                         Some(*func_id)
                     } else {
                         None
                     };
                     self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
-                } else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
+                } else if let &ty::FnDef(func_did, _) = fn_ty.kind() {
                     // If the called function has target features the calling function hasn't,
                     // the call requires `unsafe`. Don't check this on wasm
                     // targets, though. For more information on wasm see the
                     // is_like_wasm check in hir_analysis/src/collect.rs
-                    let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
                     if !self.tcx.sess.target.options.is_like_wasm
                         && !callee_features.iter().all(|feature| {
                             self.body_target_features.iter().any(|f| f.name == feature.name)
@@ -739,7 +747,10 @@ impl UnsafeOpKind {
     ) {
         let parent_id = tcx.hir().get_parent_item(hir_id);
         let parent_owner = tcx.hir_owner_node(parent_id);
-        let should_suggest = parent_owner.fn_sig().is_some_and(|sig| sig.header.is_unsafe());
+        let should_suggest = parent_owner.fn_sig().is_some_and(|sig| {
+            // Do not suggest for safe target_feature functions
+            matches!(sig.header.safety, hir::HeaderSafety::Normal(hir::Safety::Unsafe))
+        });
         let unsafe_not_inherited_note = if should_suggest {
             suggest_unsafe_block.then(|| {
                 let body_span = tcx.hir().body(parent_owner.body_id().unwrap()).value.span;
@@ -902,7 +913,7 @@ impl UnsafeOpKind {
             {
                 true
             } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
-                && sig.header.is_unsafe()
+                && matches!(sig.header.safety, hir::HeaderSafety::Normal(hir::Safety::Unsafe))
             {
                 true
             } else {
@@ -1111,7 +1122,16 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
 
     let hir_id = tcx.local_def_id_to_hir_id(def);
     let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
-        if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }
+        match fn_sig.header.safety {
+            // We typeck the body as safe, but otherwise treat it as unsafe everywhere else.
+            // Call sites to other SafeTargetFeatures functions are checked explicitly and don't need
+            // to care about safety of the body.
+            hir::HeaderSafety::SafeTargetFeatures => SafetyContext::Safe,
+            hir::HeaderSafety::Normal(safety) => match safety {
+                hir::Safety::Unsafe => SafetyContext::UnsafeFn,
+                hir::Safety::Safe => SafetyContext::Safe,
+            },
+        }
     });
     let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
     let mut warnings = Vec::new();
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index c2e9498908c..bb603df1129 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1407,20 +1407,37 @@ impl<'v> RootCollector<'_, 'v> {
         match self.tcx.def_kind(id.owner_id) {
             DefKind::Enum | DefKind::Struct | DefKind::Union => {
                 if self.strategy == MonoItemCollectionStrategy::Eager
-                    && self.tcx.generics_of(id.owner_id).is_empty()
+                    && !self.tcx.generics_of(id.owner_id).requires_monomorphization(self.tcx)
                 {
                     debug!("RootCollector: ADT drop-glue for `{id:?}`",);
+                    let id_args =
+                        ty::GenericArgs::for_item(self.tcx, id.owner_id.to_def_id(), |param, _| {
+                            match param.kind {
+                                GenericParamDefKind::Lifetime => {
+                                    self.tcx.lifetimes.re_erased.into()
+                                }
+                                GenericParamDefKind::Type { .. }
+                                | GenericParamDefKind::Const { .. } => {
+                                    unreachable!(
+                                        "`own_requires_monomorphization` check means that \
+                                we should have no type/const params"
+                                    )
+                                }
+                            }
+                        });
 
                     // This type is impossible to instantiate, so we should not try to
                     // generate a `drop_in_place` instance for it.
                     if self.tcx.instantiate_and_check_impossible_predicates((
                         id.owner_id.to_def_id(),
-                        ty::List::empty(),
+                        id_args,
                     )) {
                         return;
                     }
 
-                    let ty = self.tcx.type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap();
+                    let ty =
+                        self.tcx.type_of(id.owner_id.to_def_id()).instantiate(self.tcx, id_args);
+                    assert!(!ty.has_non_region_param());
                     visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output);
                 }
             }
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 7b02aecdfae..323b414cca0 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -79,8 +79,14 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
     // Initialize the collector.
     let mut items = DiagnosticItems::default();
 
-    // Collect diagnostic items in other crates.
-    for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
+    // Collect diagnostic items in visible crates.
+    for cnum in tcx
+        .crates(())
+        .iter()
+        .copied()
+        .filter(|cnum| tcx.is_user_visible_dep(*cnum))
+        .chain(std::iter::once(LOCAL_CRATE))
+    {
         for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
             collect_item(tcx, &mut items, name, def_id);
         }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 30f9e698521..aabc33b015e 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -593,9 +593,11 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
     }
 
     fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
-        let is_const = self.tcx.is_const_fn(def_id.to_def_id());
+        let is_const = self.tcx.is_const_fn(def_id.to_def_id())
+            || (self.tcx.def_kind(def_id.to_def_id()) == DefKind::Trait
+                && self.tcx.is_const_trait(def_id.to_def_id()));
 
-        // Reachable const fn must have a stability attribute.
+        // Reachable const fn/trait must have a stability attribute.
         if is_const
             && self.effective_visibilities.is_reachable(def_id)
             && self.tcx.lookup_const_stability(def_id).is_none()
@@ -772,7 +774,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
+            hir::ItemKind::Impl(hir::Impl {
+                of_trait: Some(ref t),
+                self_ty,
+                items,
+                constness,
+                ..
+            }) => {
                 let features = self.tcx.features();
                 if features.staged_api() {
                     let attrs = self.tcx.hir().attrs(item.hir_id());
@@ -814,6 +822,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     }
                 }
 
+                match constness {
+                    rustc_hir::Constness::Const => {
+                        if let Some(def_id) = t.trait_def_id() {
+                            // FIXME(const_trait_impl): Improve the span here.
+                            self.tcx.check_const_stability(def_id, t.path.span, t.path.span);
+                        }
+                    }
+                    rustc_hir::Constness::NotConst => {}
+                }
+
                 for impl_item_ref in *items {
                     let impl_item = self.tcx.associated_item(impl_item_ref.id.owner_id);
 
@@ -829,6 +847,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
         intravisit::walk_item(self, item);
     }
 
+    fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef<'tcx>) {
+        match t.modifiers.constness {
+            hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) => {
+                if let Some(def_id) = t.trait_ref.trait_def_id() {
+                    self.tcx.check_const_stability(def_id, t.trait_ref.path.span, span);
+                }
+            }
+            hir::BoundConstness::Never => {}
+        }
+        intravisit::walk_poly_trait_ref(self, t);
+    }
+
     fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) {
         if let Some(def_id) = path.res.opt_def_id() {
             let method_span = path.segments.last().map(|s| s.ident.span);
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 7324d3fe786..c4aeaf478bd 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -5019,12 +5019,13 @@ struct ItemInfoCollector<'a, 'ra, 'tcx> {
 }
 
 impl ItemInfoCollector<'_, '_, '_> {
-    fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId) {
+    fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId, attrs: &[Attribute]) {
         let sig = DelegationFnSig {
             header: sig.header,
             param_count: sig.decl.inputs.len(),
             has_self: sig.decl.has_self(),
             c_variadic: sig.decl.c_variadic(),
+            target_feature: attrs.iter().any(|attr| attr.has_name(sym::target_feature)),
         };
         self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);
     }
@@ -5043,7 +5044,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
             | ItemKind::Trait(box Trait { ref generics, .. })
             | ItemKind::TraitAlias(ref generics, _) => {
                 if let ItemKind::Fn(box Fn { ref sig, .. }) = &item.kind {
-                    self.collect_fn_info(sig, item.id);
+                    self.collect_fn_info(sig, item.id, &item.attrs);
                 }
 
                 let def_id = self.r.local_def_id(item.id);
@@ -5076,7 +5077,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
 
     fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) {
         if let AssocItemKind::Fn(box Fn { ref sig, .. }) = &item.kind {
-            self.collect_fn_info(sig, item.id);
+            self.collect_fn_info(sig, item.id, &item.attrs);
         }
         visit::walk_assoc_item(self, item, ctxt);
     }
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index b24e343c58d..25e35fead7e 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1031,6 +1031,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         is_soft,
                         span,
                         soft_handler,
+                        stability::UnstableKind::Regular,
                     );
                 }
             }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 58c0a05df1f..879f3fac21f 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -19,15 +19,15 @@ pub(super) fn mangle<'tcx>(
     let def_id = instance.def_id();
 
     // We want to compute the "type" of this item. Unfortunately, some
-    // kinds of items (e.g., closures) don't have an entry in the
-    // item-type array. So walk back up the find the closest parent
-    // that DOES have an entry.
+    // kinds of items (e.g., synthetic static allocations from const eval)
+    // don't have a proper implementation for the `type_of` query. So walk
+    // back up the find the closest parent that DOES have a type.
     let mut ty_def_id = def_id;
     let instance_ty;
     loop {
         let key = tcx.def_key(ty_def_id);
         match key.disambiguated_data.data {
-            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
+            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) | DefPathData::Closure => {
                 instance_ty = tcx.type_of(ty_def_id).instantiate_identity();
                 debug!(?instance_ty);
                 break;
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 53300c95fa7..7032f7b9d31 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -824,9 +824,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn cmp_fn_sig(
         &self,
         sig1: &ty::PolyFnSig<'tcx>,
-        fn_def1: Option<(DefId, &'tcx [ty::GenericArg<'tcx>])>,
+        fn_def1: Option<(DefId, Option<&'tcx [ty::GenericArg<'tcx>]>)>,
         sig2: &ty::PolyFnSig<'tcx>,
-        fn_def2: Option<(DefId, &'tcx [ty::GenericArg<'tcx>])>,
+        fn_def2: Option<(DefId, Option<&'tcx [ty::GenericArg<'tcx>]>)>,
     ) -> (DiagStyledString, DiagStyledString) {
         let sig1 = &(self.normalize_fn_sig)(*sig1);
         let sig2 = &(self.normalize_fn_sig)(*sig2);
@@ -850,8 +850,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
         // ^^^^^^
-        values.0.push(sig1.safety.prefix_str(), sig1.safety != sig2.safety);
-        values.1.push(sig2.safety.prefix_str(), sig1.safety != sig2.safety);
+        let safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
+            None => sig.safety.prefix_str(),
+            Some((did, _)) => {
+                if self.tcx.codegen_fn_attrs(did).safe_target_features {
+                    "#[target_features] "
+                } else {
+                    sig.safety.prefix_str()
+                }
+            }
+        };
+        let safety1 = safety(fn_def1, sig1);
+        let safety2 = safety(fn_def2, sig2);
+        values.0.push(safety1, safety1 != safety2);
+        values.1.push(safety2, safety1 != safety2);
 
         // unsafe extern "C" for<'a> fn(&'a T) -> &'a T
         //        ^^^^^^^^^^
@@ -932,23 +944,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             (values.1).0.extend(x2.0);
         }
 
-        let fmt = |(did, args)| format!(" {{{}}}", self.tcx.def_path_str_with_args(did, args));
+        let fmt = |did, args| format!(" {{{}}}", self.tcx.def_path_str_with_args(did, args));
 
         match (fn_def1, fn_def2) {
-            (None, None) => {}
-            (Some(fn_def1), Some(fn_def2)) => {
-                let path1 = fmt(fn_def1);
-                let path2 = fmt(fn_def2);
+            (Some((fn_def1, Some(fn_args1))), Some((fn_def2, Some(fn_args2)))) => {
+                let path1 = fmt(fn_def1, fn_args1);
+                let path2 = fmt(fn_def2, fn_args2);
                 let same_path = path1 == path2;
                 values.0.push(path1, !same_path);
                 values.1.push(path2, !same_path);
             }
-            (Some(fn_def1), None) => {
-                values.0.push_highlighted(fmt(fn_def1));
+            (Some((fn_def1, Some(fn_args1))), None) => {
+                values.0.push_highlighted(fmt(fn_def1, fn_args1));
             }
-            (None, Some(fn_def2)) => {
-                values.1.push_highlighted(fmt(fn_def2));
+            (None, Some((fn_def2, Some(fn_args2)))) => {
+                values.1.push_highlighted(fmt(fn_def2, fn_args2));
             }
+            _ => {}
         }
 
         values
@@ -1339,17 +1351,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => {
                 let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1);
                 let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2);
-                self.cmp_fn_sig(&sig1, Some((*did1, args1)), &sig2, Some((*did2, args2)))
+                self.cmp_fn_sig(
+                    &sig1,
+                    Some((*did1, Some(args1))),
+                    &sig2,
+                    Some((*did2, Some(args2))),
+                )
             }
 
             (ty::FnDef(did1, args1), ty::FnPtr(sig_tys2, hdr2)) => {
                 let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1);
-                self.cmp_fn_sig(&sig1, Some((*did1, args1)), &sig_tys2.with(*hdr2), None)
+                self.cmp_fn_sig(&sig1, Some((*did1, Some(args1))), &sig_tys2.with(*hdr2), None)
             }
 
             (ty::FnPtr(sig_tys1, hdr1), ty::FnDef(did2, args2)) => {
                 let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2);
-                self.cmp_fn_sig(&sig_tys1.with(*hdr1), None, &sig2, Some((*did2, args2)))
+                self.cmp_fn_sig(&sig_tys1.with(*hdr1), None, &sig2, Some((*did2, Some(args2))))
             }
 
             (ty::FnPtr(sig_tys1, hdr1), ty::FnPtr(sig_tys2, hdr2)) => {
@@ -1531,7 +1548,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         (false, Mismatch::Fixed("existential projection"))
                     }
                 };
-                let Some(vals) = self.values_str(values) else {
+                let Some(vals) = self.values_str(values, cause) else {
                     // Derived error. Cancel the emitter.
                     // NOTE(eddyb) this was `.cancel()`, but `diag`
                     // is borrowed, so we can't fully defuse it.
@@ -1956,7 +1973,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         })
         | ObligationCauseCode::BlockTailExpression(.., source)) = code
             && let hir::MatchSource::TryDesugar(_) = source
-            && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values)
+            && let Some((expected_ty, found_ty, _)) = self.values_str(trace.values, &trace.cause)
         {
             suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
                 found: found_ty.content(),
@@ -2085,6 +2102,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     fn values_str(
         &self,
         values: ValuePairs<'tcx>,
+        cause: &ObligationCause<'tcx>,
     ) -> Option<(DiagStyledString, DiagStyledString, Option<PathBuf>)> {
         match values {
             ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found),
@@ -2109,7 +2127,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 if exp_found.references_error() {
                     return None;
                 }
-                let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, None, &exp_found.found, None);
+                let (fn_def1, fn_def2) = if let ObligationCauseCode::CompareImplItem {
+                    impl_item_def_id,
+                    trait_item_def_id,
+                    ..
+                } = *cause.code()
+                {
+                    (Some((trait_item_def_id, None)), Some((impl_item_def_id.to_def_id(), None)))
+                } else {
+                    (None, None)
+                };
+
+                let (exp, fnd) =
+                    self.cmp_fn_sig(&exp_found.expected, fn_def1, &exp_found.found, fn_def2);
                 Some((exp, fnd, None))
             }
         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index 2cfccc57c97..1dd09fe7aaf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -461,9 +461,11 @@ impl<T> Trait<T> for X {
                     (ty::FnPtr(_, hdr), ty::FnDef(def_id, _))
                     | (ty::FnDef(def_id, _), ty::FnPtr(_, hdr)) => {
                         if tcx.fn_sig(def_id).skip_binder().safety() < hdr.safety {
-                            diag.note(
+                            if !tcx.codegen_fn_attrs(def_id).safe_target_features {
+                                diag.note(
                                 "unsafe functions cannot be coerced into safe function pointers",
-                            );
+                                );
+                            }
                         }
                     }
                     (ty::Adt(_, _), ty::Adt(def, args))
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 98b5fb2052f..3acca47025c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -221,7 +221,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
                 span: trace.cause.span,
                 requirement: ObligationCauseAsDiagArg(trace.cause.clone()),
-                expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)),
+                expected_found: self.values_str(trace.values, &trace.cause).map(|(e, f, _)| (e, f)),
             }
             .add_to_diag(err),
             infer::Reborrow(span) => {
@@ -946,8 +946,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         if let infer::Subtype(ref sup_trace) = sup_origin
             && let infer::Subtype(ref sub_trace) = sub_origin
-            && let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values)
-            && let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values)
+            && let Some((sup_expected, sup_found, _)) =
+                self.values_str(sup_trace.values, &sup_trace.cause)
+            && let Some((sub_expected, sub_found, _)) =
+                self.values_str(sub_trace.values, &sup_trace.cause)
             && sub_expected == sup_expected
             && sub_found == sup_found
         {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 405c26b5b3b..6076c999086 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -2189,7 +2189,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
         let traits_with_same_path: UnordSet<_> = self
             .tcx
-            .all_traits()
+            .visible_traits()
             .filter(|trait_def_id| *trait_def_id != trait_ref.def_id())
             .map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id))
             .filter(|(p, _)| *p == required_trait_path)
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 51efe39a7bc..2d248d00066 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -205,9 +205,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
             if self_ty.is_fn() {
                 let fn_sig = self_ty.fn_sig(self.tcx);
-                let shortname = match fn_sig.safety() {
-                    hir::Safety::Safe => "fn",
-                    hir::Safety::Unsafe => "unsafe fn",
+                let shortname = if let ty::FnDef(def_id, _) = self_ty.kind()
+                    && self.tcx.codegen_fn_attrs(def_id).safe_target_features
+                {
+                    "#[target_feature] fn"
+                } else {
+                    match fn_sig.safety() {
+                        hir::Safety::Safe => "fn",
+                        hir::Safety::Unsafe => "unsafe fn",
+                    }
                 };
                 flags.push((sym::_Self, Some(shortname.to_owned())));
             }
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 7db0f2bb5a7..4498beff4ea 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -264,9 +264,10 @@ fn fulfillment_error_for_no_solution<'tcx>(
                     infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
                 }
                 ty::ConstKind::Param(param_ct) => param_ct.find_ty_from_env(obligation.param_env),
-                _ => span_bug!(
+                ty::ConstKind::Value(ty, _) => ty,
+                kind => span_bug!(
                     obligation.cause.span,
-                    "ConstArgHasWrongType failed but we don't know how to compute type"
+                    "ConstArgHasWrongType failed but we don't know how to compute type for {kind:?}"
                 ),
             };
             FulfillmentErrorCode::Select(SelectionError::ConstArgHasWrongType {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 1dcd0d0dfb8..da16a742099 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -714,9 +714,18 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
     }
     let errors = ocx.select_all_or_error();
 
-    let result = !errors.is_empty();
-    debug!("impossible_predicates = {:?}", result);
-    result
+    if !errors.is_empty() {
+        return true;
+    }
+
+    // Leak check for any higher-ranked trait mismatches.
+    // We only need to do this in the old solver, since the new solver already
+    // leak-checks.
+    if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
+        return true;
+    }
+
+    false
 }
 
 fn instantiate_and_check_impossible_predicates<'tcx>(
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index ab606478c51..17be0bd0ab9 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -105,21 +105,27 @@ fn map_error<'tcx>(
             // See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
             assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
             if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
-                cx.tcx().dcx().delayed_bug(format!(
+                let guar = cx.tcx().dcx().delayed_bug(format!(
                     "encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
                 ));
+                LayoutError::ReferencesError(guar)
+            } else {
+                LayoutError::Unknown(ty)
             }
-            LayoutError::Unknown(ty)
         }
         LayoutCalculatorError::EmptyUnion => {
             // This is always a compile error.
-            cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
-            LayoutError::Unknown(ty)
+            let guar =
+                cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
+            LayoutError::ReferencesError(guar)
         }
         LayoutCalculatorError::ReprConflict => {
             // packed enums are the only known trigger of this, but others might arise
-            cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
-            LayoutError::Unknown(ty)
+            let guar = cx
+                .tcx()
+                .dcx()
+                .delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
+            LayoutError::ReferencesError(guar)
         }
     };
     error(cx, err)
@@ -432,8 +438,10 @@ fn layout_of_uncached<'tcx>(
         ty::Adt(def, args) if def.repr().simd() => {
             if !def.is_struct() {
                 // Should have yielded E0517 by now.
-                tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
-                return Err(error(cx, LayoutError::Unknown(ty)));
+                let guar = tcx
+                    .dcx()
+                    .delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
+                return Err(error(cx, LayoutError::ReferencesError(guar)));
             }
 
             let fields = &def.non_enum_variant().fields;
@@ -459,10 +467,10 @@ fn layout_of_uncached<'tcx>(
             // (should be caught by typeck)
             for fi in fields {
                 if fi.ty(tcx, args) != f0_ty {
-                    tcx.dcx().delayed_bug(
+                    let guar = tcx.dcx().delayed_bug(
                         "#[repr(simd)] was applied to an ADT with heterogeneous field type",
                     );
-                    return Err(error(cx, LayoutError::Unknown(ty)));
+                    return Err(error(cx, LayoutError::ReferencesError(guar)));
                 }
             }
 
@@ -567,11 +575,11 @@ fn layout_of_uncached<'tcx>(
 
             if def.is_union() {
                 if def.repr().pack.is_some() && def.repr().align.is_some() {
-                    tcx.dcx().span_delayed_bug(
+                    let guar = tcx.dcx().span_delayed_bug(
                         tcx.def_span(def.did()),
                         "union cannot be packed and aligned",
                     );
-                    return Err(error(cx, LayoutError::Unknown(ty)));
+                    return Err(error(cx, LayoutError::ReferencesError(guar)));
                 }
 
                 return Ok(tcx.mk_layout(
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index cb59bc608c2..0d0092ea1aa 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -804,7 +804,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> {
     #[inline(never)]
     fn region_param_out_of_range(&self, ebr: I::EarlyParamRegion, r: I::Region) -> ! {
         panic!(
-            "const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
+            "region parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
             ebr,
             r,
             ebr.index(),
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 207c744ee22..c8007dd9be0 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.140"
+version = "0.1.143"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df14d41c5d172a886df3753d54238eefb0f61c96cbd8b363c33ccc92c457bee3"
+checksum = "c85ba2077e3eab3dd81be4ece6b7fb2ad0887c1fb813e9a45400baf75c6c7c29"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 07596fa16f9..96caac890a3 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.143", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 8831443a10f..7180593edf0 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -124,37 +124,25 @@ pub struct CStr {
 ///
 /// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err();
 /// ```
-#[derive(Clone, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 #[stable(feature = "core_c_str", since = "1.64.0")]
-pub struct FromBytesWithNulError {
-    kind: FromBytesWithNulErrorKind,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-enum FromBytesWithNulErrorKind {
-    InteriorNul(usize),
+pub enum FromBytesWithNulError {
+    /// Data provided contains an interior nul byte at byte `position`.
+    InteriorNul {
+        /// The position of the interior nul byte.
+        position: usize,
+    },
+    /// Data provided is not nul terminated.
     NotNulTerminated,
 }
 
-// FIXME: const stability attributes should not be required here, I think
-impl FromBytesWithNulError {
-    const fn interior_nul(pos: usize) -> FromBytesWithNulError {
-        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
-    }
-    const fn not_nul_terminated() -> FromBytesWithNulError {
-        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
-    }
-}
-
 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
 impl Error for FromBytesWithNulError {
     #[allow(deprecated)]
     fn description(&self) -> &str {
-        match self.kind {
-            FromBytesWithNulErrorKind::InteriorNul(..) => {
-                "data provided contains an interior nul byte"
-            }
-            FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated",
+        match self {
+            Self::InteriorNul { .. } => "data provided contains an interior nul byte",
+            Self::NotNulTerminated => "data provided is not nul terminated",
         }
     }
 }
@@ -199,8 +187,8 @@ impl fmt::Display for FromBytesWithNulError {
     #[allow(deprecated, deprecated_in_future)]
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.description())?;
-        if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind {
-            write!(f, " at byte pos {pos}")?;
+        if let Self::InteriorNul { position } = self {
+            write!(f, " at byte pos {position}")?;
         }
         Ok(())
     }
@@ -349,25 +337,25 @@ impl CStr {
     /// use std::ffi::CStr;
     ///
     /// let cstr = CStr::from_bytes_with_nul(b"hello\0");
-    /// assert!(cstr.is_ok());
+    /// assert_eq!(cstr, Ok(c"hello"));
     /// ```
     ///
     /// Creating a `CStr` without a trailing nul terminator is an error:
     ///
     /// ```
-    /// use std::ffi::CStr;
+    /// use std::ffi::{CStr, FromBytesWithNulError};
     ///
     /// let cstr = CStr::from_bytes_with_nul(b"hello");
-    /// assert!(cstr.is_err());
+    /// assert_eq!(cstr, Err(FromBytesWithNulError::NotNulTerminated));
     /// ```
     ///
     /// Creating a `CStr` with an interior nul byte is an error:
     ///
     /// ```
-    /// use std::ffi::CStr;
+    /// use std::ffi::{CStr, FromBytesWithNulError};
     ///
     /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
-    /// assert!(cstr.is_err());
+    /// assert_eq!(cstr, Err(FromBytesWithNulError::InteriorNul { position: 2 }));
     /// ```
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")]
@@ -379,8 +367,8 @@ impl CStr {
                 // of the byte slice.
                 Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
             }
-            Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
-            None => Err(FromBytesWithNulError::not_nul_terminated()),
+            Some(position) => Err(FromBytesWithNulError::InteriorNul { position }),
+            None => Err(FromBytesWithNulError::NotNulTerminated),
         }
     }
 
diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs
index 1779126b180..70484e4d0f2 100644
--- a/library/core/src/intrinsics/fallback.rs
+++ b/library/core/src/intrinsics/fallback.rs
@@ -8,6 +8,7 @@
 #![allow(missing_docs)]
 
 #[const_trait]
+#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
 pub trait CarryingMulAdd: Copy + 'static {
     type Unsigned: Copy + 'static;
     fn carrying_mul_add(
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 4af9b666e54..01af964a83e 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -952,6 +952,7 @@ marker_impls! {
 /// This should be used for `~const` bounds,
 /// as non-const bounds will always hold for every type.
 #[unstable(feature = "const_destruct", issue = "133214")]
+#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
 #[lang = "destruct"]
 #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
 #[rustc_deny_explicit_impl]
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 810b906b871..fe7ff2d9ede 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -65,6 +65,7 @@
 /// ```
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
 #[rustc_on_unimplemented(
     on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
     on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index ed0d30a0f50..11490ea2bfc 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -134,6 +134,7 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Deref"]
 #[const_trait]
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
 pub trait Deref {
     /// The resulting type after dereferencing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -263,6 +264,7 @@ impl<T: ?Sized> const Deref for &mut T {
 #[doc(alias = "*")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[const_trait]
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
 pub trait DerefMut: ~const Deref {
     /// Mutably dereferences the value.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index 78b5252195f..e024b7fb4d3 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -204,6 +204,7 @@
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[const_trait]
+#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
 pub trait Drop {
     /// Executes the destructor for this type.
     ///
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index e7f7f38cb41..da58d7c13bd 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.140" }
+compiler_builtins = { version = "=0.1.143" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 54fa31620ac..fdf011c1948 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -709,7 +709,7 @@ impl Iterator for ReadDir {
                 // thread safety for readdir() as long an individual DIR* is not accessed
                 // concurrently, which is sufficient for Rust.
                 super::os::set_errno(0);
-                let entry_ptr = readdir64(self.inner.dirp.0);
+                let entry_ptr: *const dirent64 = readdir64(self.inner.dirp.0);
                 if entry_ptr.is_null() {
                     // We either encountered an error, or reached the end. Either way,
                     // the next call to next() should return None.
@@ -735,29 +735,19 @@ impl Iterator for ReadDir {
                 // contents were "simply" partially initialized data.
                 //
                 // Like for uninitialized contents, converting entry_ptr to `&dirent64`
-                // would not be legal. However, unique to dirent64 is that we don't even
-                // get to use `&raw const (*entry_ptr).d_name` because that operation
-                // requires the full extent of *entry_ptr to be in bounds of the same
-                // allocation, which is not necessarily the case here.
-                //
-                // Instead we must access fields individually through their offsets.
-                macro_rules! offset_ptr {
-                    ($entry_ptr:expr, $field:ident) => {{
-                        const OFFSET: isize = mem::offset_of!(dirent64, $field) as isize;
-                        if true {
-                            // Cast to the same type determined by the else branch.
-                            $entry_ptr.byte_offset(OFFSET).cast::<_>()
-                        } else {
-                            #[allow(deref_nullptr)]
-                            {
-                                &raw const (*ptr::null::<dirent64>()).$field
-                            }
-                        }
-                    }};
+                // would not be legal. However, we can use `&raw const (*entry_ptr).d_name`
+                // to refer the fields individually, because that operation is equivalent
+                // to `byte_offset` and thus does not require the full extent of `*entry_ptr`
+                // to be in bounds of the same allocation, only the offset of the field
+                // being referenced.
+                macro_rules! entry_field_ptr {
+                    ($field:ident) => {
+                        &raw const (*entry_ptr).$field
+                    };
                 }
 
                 // d_name is guaranteed to be null-terminated.
-                let name = CStr::from_ptr(offset_ptr!(entry_ptr, d_name).cast());
+                let name = CStr::from_ptr(entry_field_ptr!(d_name).cast());
                 let name_bytes = name.to_bytes();
                 if name_bytes == b"." || name_bytes == b".." {
                     continue;
@@ -765,14 +755,14 @@ impl Iterator for ReadDir {
 
                 #[cfg(not(target_os = "vita"))]
                 let entry = dirent64_min {
-                    d_ino: *offset_ptr!(entry_ptr, d_ino) as u64,
+                    d_ino: *entry_field_ptr!(d_ino) as u64,
                     #[cfg(not(any(
                         target_os = "solaris",
                         target_os = "illumos",
                         target_os = "aix",
                         target_os = "nto",
                     )))]
-                    d_type: *offset_ptr!(entry_ptr, d_type) as u8,
+                    d_type: *entry_field_ptr!(d_type) as u8,
                 };
 
                 #[cfg(target_os = "vita")]
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 40c908c3fa9..c7eafadee2d 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -116,7 +116,7 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
         println!("fmt: {verb} {len} {adjective}files");
     }
     if len > 1000 && !CiEnv::is_ci() {
-        println!("hint: if this number seems too high, try running `git fetch origin master");
+        println!("hint: if this number seems too high, try running `git fetch origin master`");
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 5af05c395d8..fdc1f30b859 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -24,8 +24,8 @@ use crate::core::config::flags::{Subcommand, get_completion};
 use crate::utils::build_stamp::{self, BuildStamp};
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{
-    self, LldThreads, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var,
-    linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date,
+    self, LldThreads, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, linker_args,
+    linker_flags, t, target_supports_cranelift_backend, up_to_date,
 };
 use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
 use crate::{CLang, DocTests, GitRepo, Mode, PathSet, envify};
@@ -1975,11 +1975,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             // Tests that use compiler libraries may inherit the `-lLLVM` link
             // requirement, but the `-L` library path is not propagated across
             // separate compilations. We can add LLVM's library path to the
-            // platform-specific environment variable as a workaround.
+            // rustc args as a workaround.
             if !builder.config.dry_run() && suite.ends_with("fulldeps") {
                 let llvm_libdir =
                     command(&llvm_config).arg("--libdir").run_capture_stdout(builder).stdout();
-                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
+                let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
+                if target.is_msvc() {
+                    rustflags.push_str(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}"));
+                } else {
+                    rustflags.push_str(&format!("-Clink-arg=-L{llvm_libdir}"));
+                }
+                cmd.env("RUSTFLAGS", rustflags);
             }
 
             if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") {
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 2692a129ef3..f9fb19ddb09 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -8,9 +8,7 @@ use crate::core::build_steps::{compile, test};
 use crate::core::config::SplitDebuginfo;
 use crate::core::config::flags::Color;
 use crate::utils::build_stamp;
-use crate::utils::helpers::{
-    self, LldThreads, add_link_lib_path, check_cfg_arg, linker_args, linker_flags,
-};
+use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags};
 use crate::{
     BootstrapCommand, CLang, Compiler, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
     TargetSelection, command, prepare_behaviour_dump_dir, t,
@@ -947,12 +945,16 @@ impl Builder<'_> {
         // Tools that use compiler libraries may inherit the `-lLLVM` link
         // requirement, but the `-L` library path is not propagated across
         // separate Cargo projects. We can add LLVM's library path to the
-        // platform-specific environment variable as a workaround.
+        // rustc args as a workaround.
         if mode == Mode::ToolRustc || mode == Mode::Codegen {
             if let Some(llvm_config) = self.llvm_config(target) {
                 let llvm_libdir =
                     command(llvm_config).arg("--libdir").run_capture_stdout(self).stdout();
-                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo);
+                if target.is_msvc() {
+                    rustflags.arg(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}"));
+                } else {
+                    rustflags.arg(&format!("-Clink-arg=-L{llvm_libdir}"));
+                }
             }
         }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 516c314024b..a1b1748c85b 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -106,31 +106,6 @@ pub fn add_dylib_path(path: Vec<PathBuf>, cmd: &mut BootstrapCommand) {
     cmd.env(dylib_path_var(), t!(env::join_paths(list)));
 }
 
-/// Adds a list of lookup paths to `cmd`'s link library lookup path.
-pub fn add_link_lib_path(path: Vec<PathBuf>, cmd: &mut BootstrapCommand) {
-    let mut list = link_lib_path();
-    for path in path {
-        list.insert(0, path);
-    }
-    cmd.env(link_lib_path_var(), t!(env::join_paths(list)));
-}
-
-/// Returns the environment variable which the link library lookup path
-/// resides in for this platform.
-fn link_lib_path_var() -> &'static str {
-    if cfg!(target_env = "msvc") { "LIB" } else { "LIBRARY_PATH" }
-}
-
-/// Parses the `link_lib_path_var()` environment variable, returning a list of
-/// paths that are members of this lookup path.
-fn link_lib_path() -> Vec<PathBuf> {
-    let var = match env::var_os(link_lib_path_var()) {
-        Some(v) => v,
-        None => return vec![],
-    };
-    env::split_paths(&var).collect()
-}
-
 pub struct TimeIt(bool, Instant);
 
 /// Returns an RAII structure that prints out how long it took to drop.
diff --git a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
index 8b0fb0710d4..6f33c632181 100644
--- a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
+++ b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
@@ -91,9 +91,12 @@ ENV RUST_CONFIGURE_ARGS \
       --set rust.debug-assertions=false \
       --set rust.jemalloc \
       --set rust.use-lld=true \
+      --set rust.lto=thin \
       --set rust.codegen-units=1
 
-ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
+ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
+      ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci --  python3 ../x.py dist \
+      --host $HOSTS --target $HOSTS --include-default-paths build-manifest bootstrap
 
 ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=clang
 ENV LIBCURL_NO_PKG_CONFIG 1
diff --git a/src/ci/docker/scripts/build-gccjit.sh b/src/ci/docker/scripts/build-gccjit.sh
index c565922dcd1..43ed2270d31 100755
--- a/src/ci/docker/scripts/build-gccjit.sh
+++ b/src/ci/docker/scripts/build-gccjit.sh
@@ -3,7 +3,7 @@
 GIT_REPO="https://github.com/rust-lang/gcc"
 
 # This commit hash needs to be updated to use a more recent gcc fork version.
-GIT_COMMIT="e744a9459d33864067214741daf5c5bc2a7b88c6"
+GIT_COMMIT="45648c2edd4ecd862d9f08196d3d6c6ccba79f07"
 
 set -ex
 
diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
deleted file mode 100644
index 8b2b39ee162..00000000000
--- a/src/ci/docker/scripts/emscripten.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-set -ex
-
-hide_output() {
-  set +x
-  on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
-  trap "$on_err" ERR
-  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
-  PING_LOOP_PID=$!
-  "$@" &> /tmp/build.log
-  trap - ERR
-  kill $PING_LOOP_PID
-  rm -f /tmp/build.log
-  set -x
-}
-
-git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
-cd /emsdk-portable
-hide_output ./emsdk install 3.1.68
-./emsdk activate 3.1.68
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index c59dce185f4..bfa789b1f39 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -90,11 +90,11 @@ impl Cfg {
             },
             MetaItemKind::List(ref items) => {
                 let orig_len = items.len();
-                let sub_cfgs =
+                let mut sub_cfgs =
                     items.iter().filter_map(|i| Cfg::parse_nested(i, exclude).transpose());
                 let ret = match name {
-                    sym::all => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)),
-                    sym::any => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)),
+                    sym::all => sub_cfgs.try_fold(Cfg::True, |x, y| Ok(x & y?)),
+                    sym::any => sub_cfgs.try_fold(Cfg::False, |x, y| Ok(x | y?)),
                     sym::not => {
                         if orig_len == 1 {
                             let mut sub_cfgs = sub_cfgs.collect::<Vec<_>>();
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2ed2df799dd..f619b2c66ac 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3094,7 +3094,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
         let kind = match item.kind {
             hir::ForeignItemKind::Fn(sig, names, generics) => ForeignFunctionItem(
                 clean_function(cx, &sig, generics, FunctionArgs::Names(names)),
-                sig.header.safety,
+                sig.header.safety(),
             ),
             hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(
                 Static { type_: Box::new(clean_ty(ty, cx)), mutability, expr: None },
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index dcee96978d2..ff1c0294fb8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -668,17 +668,28 @@ impl Item {
                 ty::Asyncness::Yes => hir::IsAsync::Async(DUMMY_SP),
                 ty::Asyncness::No => hir::IsAsync::NotAsync,
             };
-            hir::FnHeader { safety: sig.safety(), abi: sig.abi(), constness, asyncness }
+            hir::FnHeader {
+                safety: if tcx.codegen_fn_attrs(def_id).safe_target_features {
+                    hir::HeaderSafety::SafeTargetFeatures
+                } else {
+                    sig.safety().into()
+                },
+                abi: sig.abi(),
+                constness,
+                asyncness,
+            }
         }
         let header = match self.kind {
             ItemKind::ForeignFunctionItem(_, safety) => {
                 let def_id = self.def_id().unwrap();
                 let abi = tcx.fn_sig(def_id).skip_binder().abi();
                 hir::FnHeader {
-                    safety: if abi == ExternAbi::RustIntrinsic {
-                        intrinsic_operation_unsafety(tcx, def_id.expect_local())
+                    safety: if tcx.codegen_fn_attrs(def_id).safe_target_features {
+                        hir::HeaderSafety::SafeTargetFeatures
+                    } else if abi == ExternAbi::RustIntrinsic {
+                        intrinsic_operation_unsafety(tcx, def_id.expect_local()).into()
                     } else {
-                        safety
+                        safety.into()
                     },
                     abi,
                     constness: if tcx.is_const_fn(def_id) {
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 99e88f878fb..80dc6b7250c 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -320,7 +320,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
             );
             return Symbol::intern("()");
         }
-        PatKind::Guard(p, _) => return name_from_pat(&*p),
+        PatKind::Guard(p, _) => return name_from_pat(p),
         PatKind::Range(..) => return kw::Underscore,
         PatKind::Slice(begin, ref mid, end) => {
             let begin = begin.iter().map(|p| name_from_pat(p).to_string());
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index af3c7cc7be3..80bc6cebd2a 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -303,6 +303,8 @@ pub(crate) struct RenderOptions {
     pub(crate) include_parts_dir: Vec<PathToParts>,
     /// Where to write crate-info
     pub(crate) parts_out_dir: Option<PathToParts>,
+    /// disable minification of CSS/JS
+    pub(crate) disable_minification: bool,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -781,6 +783,9 @@ impl Options {
 
         let unstable_features =
             rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
+
+        let disable_minification = matches.opt_present("disable-minification");
+
         let options = Options {
             bin_crate,
             proc_macro_crate,
@@ -857,6 +862,7 @@ impl Options {
             should_merge,
             include_parts_dir,
             parts_out_dir,
+            disable_minification,
         };
         Some((input, options, render_options))
     }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 621abd53501..92935c72b47 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1637,6 +1637,15 @@ impl PrintWithSpace for hir::Safety {
     }
 }
 
+impl PrintWithSpace for hir::HeaderSafety {
+    fn print_with_space(&self) -> &str {
+        match self {
+            hir::HeaderSafety::SafeTargetFeatures => "",
+            hir::HeaderSafety::Normal(safety) => safety.print_with_space(),
+        }
+    }
+}
+
 impl PrintWithSpace for hir::IsAsync {
     fn print_with_space(&self) -> &str {
         match self {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 48a537ad5e7..62cf2b63f7f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -337,7 +337,7 @@ enum Class {
     Ident(Span),
     Lifetime,
     PreludeTy(Span),
-    PreludeVal,
+    PreludeVal(Span),
     QuestionMark,
     Decoration(&'static str),
 }
@@ -385,7 +385,7 @@ impl Class {
             Class::Ident(_) => "",
             Class::Lifetime => "lifetime",
             Class::PreludeTy(_) => "prelude-ty",
-            Class::PreludeVal => "prelude-val",
+            Class::PreludeVal(_) => "prelude-val",
             Class::QuestionMark => "question-mark",
             Class::Decoration(kind) => kind,
         }
@@ -395,7 +395,11 @@ impl Class {
     /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
     fn get_span(self) -> Option<Span> {
         match self {
-            Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) | Self::PreludeTy(sp) => Some(sp),
+            Self::Ident(sp)
+            | Self::Self_(sp)
+            | Self::Macro(sp)
+            | Self::PreludeTy(sp)
+            | Self::PreludeVal(sp) => Some(sp),
             Self::Comment
             | Self::DocComment
             | Self::Attribute
@@ -406,7 +410,6 @@ impl Class {
             | Self::Number
             | Self::Bool
             | Self::Lifetime
-            | Self::PreludeVal
             | Self::QuestionMark
             | Self::Decoration(_) => None,
         }
@@ -851,7 +854,9 @@ impl<'src> Classifier<'src> {
             TokenKind::Ident => match get_real_ident_class(text, false) {
                 None => match text {
                     "Option" | "Result" => Class::PreludeTy(self.new_span(before, text)),
-                    "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
+                    "Some" | "None" | "Ok" | "Err" => {
+                        Class::PreludeVal(self.new_span(before, text))
+                    }
                     // "union" is a weak keyword and is only considered as a keyword when declaring
                     // a union type.
                     "union" if self.check_if_is_union_keyword() => Class::KeyWord,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index e8230e63c0f..1376bdb2e90 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -469,7 +469,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
 
                 let unsafety_flag = match myitem.kind {
                     clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
-                        if myitem.fn_header(tcx).unwrap().safety.is_unsafe() =>
+                        if myitem.fn_header(tcx).unwrap().is_unsafe() =>
                     {
                         "<sup title=\"unsafe function\">âš </sup>"
                     }
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 26f75fa241c..85f87f01afd 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node};
+use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, Pat, PatKind, QPath};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
@@ -170,7 +170,7 @@ impl SpanMapVisitor<'_> {
         true
     }
 
-    fn handle_call(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
+    fn infer_id(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
         let hir = self.tcx.hir();
         let body_id = hir.enclosing_body_owner(hir_id);
         // FIXME: this is showing error messages for parts of the code that are not
@@ -189,6 +189,27 @@ impl SpanMapVisitor<'_> {
             self.matches.insert(span, link);
         }
     }
+
+    fn handle_pat(&mut self, p: &Pat<'_>) {
+        match p.kind {
+            PatKind::Binding(_, _, _, Some(p)) => self.handle_pat(p),
+            PatKind::Struct(qpath, _, _)
+            | PatKind::TupleStruct(qpath, _, _)
+            | PatKind::Path(qpath) => match qpath {
+                QPath::TypeRelative(_, path) if matches!(path.res, Res::Err) => {
+                    self.infer_id(path.hir_id, Some(p.hir_id), qpath.span());
+                }
+                QPath::Resolved(_, path) => self.handle_path(path),
+                _ => {}
+            },
+            PatKind::Or(pats) => {
+                for pat in pats {
+                    self.handle_pat(pat);
+                }
+            }
+            _ => {}
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
@@ -206,6 +227,10 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         intravisit::walk_path(self, path);
     }
 
+    fn visit_pat(&mut self, p: &Pat<'tcx>) {
+        self.handle_pat(p);
+    }
+
     fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
         // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
         // file, we want to link to it. Otherwise no need to create a link.
@@ -228,9 +253,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
         match expr.kind {
             ExprKind::MethodCall(segment, ..) => {
-                self.handle_call(segment.hir_id, Some(expr.hir_id), segment.ident.span)
+                self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span)
             }
-            ExprKind::Call(call, ..) => self.handle_call(call.hir_id, None, call.span),
+            ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span),
             _ => {
                 if self.handle_macro(expr.span) {
                     // We don't want to go deeper into the macro.
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index ce10e5ecc24..fb6f3bc2c76 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -207,7 +207,15 @@ fn write_static_files(
     if opt.emit.is_empty() || opt.emit.contains(&EmitType::Toolchain) {
         static_files::for_each(|f: &static_files::StaticFile| {
             let filename = static_dir.join(f.output_filename());
-            fs::write(&filename, f.minified()).map_err(|e| PathError::new(e, &filename))
+            let contents: &[u8];
+            let contents_vec: Vec<u8>;
+            if opt.disable_minification {
+                contents = f.bytes;
+            } else {
+                contents_vec = f.minified();
+                contents = &contents_vec;
+            };
+            fs::write(&filename, contents).map_err(|e| PathError::new(e, &filename))
         })?;
     }
 
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 27496381b2c..a1ab258ff30 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -942,6 +942,8 @@ rustdoc-toolbar {
 pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers {
 	background-color: var(--code-block-background-color);
 	border-radius: var(--code-block-border-radius);
+	/* code blocks within links (such as in most intra-doc links) should be underlined */
+	text-decoration: inherit;
 }
 
 #main-content {
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 5fd5eb14478..0a0550ab82f 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2717,9 +2717,26 @@ class DocSearch {
             const normalizedUserQuery = parsedQuery.userQuery.toLowerCase();
             const isMixedCase = normalizedUserQuery !== userQuery;
             const result_list = [];
+            const isReturnTypeQuery = parsedQuery.elems.length === 0 ||
+                typeInfo === "returned";
             for (const result of results.values()) {
                 result.item = this.searchIndex[result.id];
                 result.word = this.searchIndex[result.id].word;
+                if (isReturnTypeQuery) {
+                    // we are doing a return-type based search,
+                    // deprioritize "clone-like" results,
+                    // ie. functions that also take the queried type as an argument.
+                    const hasType = result.item && result.item.type;
+                    if (!hasType) {
+                        continue;
+                    }
+                    const inputs = result.item.type.inputs;
+                    const where_clause = result.item.type.where_clause;
+                    if (containsTypeFromQuery(inputs, where_clause)) {
+                        result.path_dist *= 100;
+                        result.dist *= 100;
+                    }
+                }
                 result_list.push(result);
             }
 
@@ -3541,6 +3558,35 @@ class DocSearch {
         }
 
         /**
+         * This function checks if the given list contains any
+         * (non-generic) types mentioned in the query.
+         *
+         * @param {Array<FunctionType>} list    - A list of function types.
+         * @param {[FunctionType]} where_clause - Trait bounds for generic items.
+         */
+        function containsTypeFromQuery(list, where_clause) {
+            if (!list) return false;
+            for (const ty of parsedQuery.returned) {
+                // negative type ids are generics
+                if (ty.id < 0) {
+                    continue;
+                }
+                if (checkIfInList(list, ty, where_clause, null, 0)) {
+                    return true;
+                }
+            }
+            for (const ty of parsedQuery.elems) {
+                if (ty.id < 0) {
+                    continue;
+                }
+                if (checkIfInList(list, ty, where_clause, null, 0)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
          * This function checks if the object (`row`) matches the given type (`elem`) and its
          * generics (if any).
          *
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7fcdfe3fb22..33166a39574 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -622,7 +622,7 @@ impl FromClean<clean::Type> for Type {
 impl FromClean<clean::Path> for Path {
     fn from_clean(path: clean::Path, renderer: &JsonRenderer<'_>) -> Path {
         Path {
-            name: path.whole_name(),
+            name: path.last_opt().map_or(String::from(""), |s| String::from(s.as_str())),
             id: renderer.id_from_item_default(path.def_id().into()),
             args: path.segments.last().map(|args| Box::new(args.clone().args.into_json(renderer))),
         }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 96ca96ee6bc..ba620b6cb6b 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -651,8 +651,15 @@ fn opts() -> Vec<RustcOptGroup> {
             "",
             "add arguments to be used when compiling doctests",
         ),
+        opt(
+            Unstable,
+            FlagMulti,
+            "",
+            "disable-minification",
+            "disable the minification of CSS/JS files (perma-unstable, do not use with cached files)",
+            "",
+        ),
         // deprecated / removed options
-        opt(Unstable, FlagMulti, "", "disable-minification", "removed", ""),
         opt(
             Stable,
             Multi,
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 84b33e3d860..5a99977ded5 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 /// This integer is incremented with every breaking change to the API,
 /// and is returned along with the JSON blob as [`Crate::format_version`].
 /// Consuming code should assert that this value matches the format version(s) that it supports.
-pub const FORMAT_VERSION: u32 = 37;
+pub const FORMAT_VERSION: u32 = 38;
 
 /// The root of the emitted JSON blob.
 ///
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 7c2f5efd8dd..91ddbb44ff8 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -419,7 +419,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
         id: LocalDefId,
     ) -> Self::Result {
         if let Some(header) = kind.header()
-            && header.safety.is_unsafe()
+            && header.is_unsafe()
         {
             ControlFlow::Break(())
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
index 3e2b7055de4..8e2af6bf14a 100644
--- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
@@ -32,7 +32,7 @@ pub fn check(
     }
 
     let span = cx.tcx.def_span(owner_id);
-    match (headers.safety, sig.header.safety) {
+    match (headers.safety, sig.header.safety()) {
         (false, Safety::Unsafe) => span_lint(
             cx,
             MISSING_SAFETY_DOC,
diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
index 017571c38db..854fe144c29 100644
--- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
@@ -34,7 +34,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
         ImplicitSelfKind::None => return,
     };
 
-    let name = if sig.header.safety.is_unsafe() {
+    let name = if sig.header.is_unsafe() {
         name.strip_suffix("_unchecked").unwrap_or(name)
     } else {
         name
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index 3ded8dc3012..8a74951ef63 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -20,8 +20,8 @@ pub(super) fn check_fn<'tcx>(
     def_id: LocalDefId,
 ) {
     let safety = match kind {
-        intravisit::FnKind::ItemFn(_, _, hir::FnHeader { safety, .. }) => safety,
-        intravisit::FnKind::Method(_, sig) => sig.header.safety,
+        intravisit::FnKind::ItemFn(_, _, header) => header.safety(),
+        intravisit::FnKind::Method(_, sig) => sig.header.safety(),
         intravisit::FnKind::Closure => return,
     };
 
@@ -31,7 +31,7 @@ pub(super) fn check_fn<'tcx>(
 pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
     if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind {
         let body = cx.tcx.hir().body(eid);
-        check_raw_ptr(cx, sig.header.safety, sig.decl, body, item.owner_id.def_id);
+        check_raw_ptr(cx, sig.header.safety(), sig.decl, body, item.owner_id.def_id);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index e096dd25175..415b47adac5 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
         if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
             // #11201
             && let header = signature.header
-            && header.safety.is_safe()
+            && header.is_safe()
             && header.abi == Abi::Rust
             && impl_item.ident.name == sym::to_string
             && let decl = signature.decl
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 51351f6b7cd..3965c4d4087 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -5309,7 +5309,7 @@ fn lint_binary_expr_with_method_call(cx: &LateContext<'_>, info: &mut BinaryExpr
 }
 
 const FN_HEADER: hir::FnHeader = hir::FnHeader {
-    safety: hir::Safety::Safe,
+    safety: hir::HeaderSafety::Normal(hir::Safety::Safe),
     constness: hir::Constness::NotConst,
     asyncness: hir::IsAsync::NotAsync,
     abi: rustc_target::spec::abi::Abi::Rust,
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index abdce69e764..688374b5676 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                     if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
                         let name = impl_item.ident.name;
                         let id = impl_item.owner_id;
-                        if sig.header.safety.is_unsafe() {
+                        if sig.header.is_unsafe() {
                             // can't be implemented for unsafe new
                             return;
                         }
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index a86926d8416..506adf0f2cc 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -541,7 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
             .collect();
         if let Some(args) = args
             && !args.is_empty()
-            && body.is_none_or(|body| sig.header.safety.is_unsafe() || contains_unsafe_block(cx, body.value))
+            && body.is_none_or(|body| sig.header.is_unsafe() || contains_unsafe_block(cx, body.value))
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/tests/ui/boxed_local.rs b/src/tools/clippy/tests/ui/boxed_local.rs
index e2c27e585fc..4f361f5162b 100644
--- a/src/tools/clippy/tests/ui/boxed_local.rs
+++ b/src/tools/clippy/tests/ui/boxed_local.rs
@@ -173,6 +173,7 @@ mod issue_3739 {
 /// This shouldn't warn for `boxed_local` as it is intended to called from non-Rust code.
 pub extern "C" fn do_not_warn_me(_c_pointer: Box<String>) -> () {}
 
+#[allow(missing_abi)]
 #[rustfmt::skip] // Forces rustfmt to not add ABI
 pub extern fn do_not_warn_me_no_abi(_c_pointer: Box<String>) -> () {}
 
diff --git a/src/tools/clippy/tests/ui/boxed_local.stderr b/src/tools/clippy/tests/ui/boxed_local.stderr
index d3156c820b2..08fe375afb2 100644
--- a/src/tools/clippy/tests/ui/boxed_local.stderr
+++ b/src/tools/clippy/tests/ui/boxed_local.stderr
@@ -14,13 +14,13 @@ LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
    |            ^^^^^^^^^^^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:188:44
+  --> tests/ui/boxed_local.rs:189:44
    |
 LL |         fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
    |                                            ^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:196:16
+  --> tests/ui/boxed_local.rs:197:16
    |
 LL |         fn foo(x: Box<u32>) {}
    |                ^
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index 5cf5c608a85..83574a5cd98 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -240,7 +240,7 @@ fn parenthesized_word() {}
 /// UXes
 fn plural_acronym_test() {}
 
-extern {
+extern "C" {
     /// `foo()`
     fn in_extern();
 }
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 420211c6539..20fe89cdc53 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -240,7 +240,7 @@ fn parenthesized_word() {}
 /// UXes
 fn plural_acronym_test() {}
 
-extern {
+extern "C" {
     /// foo()
     fn in_extern();
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
index 014fbb85c7a..dd9dedcdd04 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
@@ -149,6 +149,7 @@ mod msrv {
         //~^ ERROR: this could be a `const fn`
 
         #[rustfmt::skip]
+        #[allow(missing_abi)]
         const extern fn implicit_c() {}
         //~^ ERROR: this could be a `const fn`
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 4f7c2cbcf0b..f974478540c 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -149,6 +149,7 @@ mod msrv {
         //~^ ERROR: this could be a `const fn`
 
         #[rustfmt::skip]
+        #[allow(missing_abi)]
         extern fn implicit_c() {}
         //~^ ERROR: this could be a `const fn`
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index cc7dfd0888d..33836bdfe9f 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -222,7 +222,7 @@ LL |         const extern "C" fn c() {}
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:153:9
    |
 LL |         extern fn implicit_c() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |         const extern fn implicit_c() {}
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:169:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:170:9
    |
 LL | /         pub fn new(strings: Vec<String>) -> Self {
 LL | |             Self { strings }
@@ -246,7 +246,7 @@ LL |         pub const fn new(strings: Vec<String>) -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:174:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:175:9
    |
 LL | /         pub fn empty() -> Self {
 LL | |             Self { strings: Vec::new() }
@@ -259,7 +259,7 @@ LL |         pub const fn empty() -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:185:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:186:9
    |
 LL | /         pub fn new(text: String) -> Self {
 LL | |             let vec = Vec::new();
@@ -273,7 +273,7 @@ LL |         pub const fn new(text: String) -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:204:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:205:5
    |
 LL |     fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,7 +284,7 @@ LL |     const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:208:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:209:5
    |
 LL |     extern "C-unwind" fn c_unwind() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -295,7 +295,7 @@ LL |     const extern "C-unwind" fn c_unwind() {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:210:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:211:5
    |
 LL |     extern "system" fn system() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -306,7 +306,7 @@ LL |     const extern "system" fn system() {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:212:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:213:5
    |
 LL |     extern "system-unwind" fn system_unwind() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index 8c7ff08ccd7..f6e84465780 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -473,37 +473,64 @@ impl<'a> LintExtractor<'a> {
             .filter(|line| line.starts_with('{'))
             .map(serde_json::from_str)
             .collect::<Result<Vec<serde_json::Value>, _>>()?;
+
         // First try to find the messages with the `code` field set to our lint.
         let matches: Vec<_> = msgs
             .iter()
             .filter(|msg| matches!(&msg["code"]["code"], serde_json::Value::String(s) if s==name))
             .map(|msg| msg["rendered"].as_str().expect("rendered field should exist").to_string())
             .collect();
-        if matches.is_empty() {
-            // Some lints override their code to something else (E0566).
-            // Try to find something that looks like it could be our lint.
-            let matches: Vec<_> = msgs.iter().filter(|msg|
-                matches!(&msg["rendered"], serde_json::Value::String(s) if s.contains(name)))
-                .map(|msg| msg["rendered"].as_str().expect("rendered field should exist").to_string())
-                .collect();
-            if matches.is_empty() {
-                let rendered: Vec<&str> =
-                    msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
-                let non_json: Vec<&str> =
-                    stderr.lines().filter(|line| !line.starts_with('{')).collect();
-                Err(format!(
-                    "did not find lint `{}` in output of example, got:\n{}\n{}",
-                    name,
-                    non_json.join("\n"),
-                    rendered.join("\n")
-                )
-                .into())
-            } else {
-                Ok(matches.join("\n"))
-            }
-        } else {
-            Ok(matches.join("\n"))
+        if !matches.is_empty() {
+            return Ok(matches.join("\n"));
+        }
+
+        // Try to detect if an unstable lint forgot to enable a `#![feature(..)]`.
+        // Specifically exclude `test_unstable_lint` which exercises this on purpose.
+        if name != "test_unstable_lint"
+            && msgs.iter().any(|msg| {
+                matches!(&msg["code"]["code"], serde_json::Value::String(s) if s=="unknown_lints")
+                    && matches!(&msg["message"], serde_json::Value::String(s) if s.contains(name))
+            })
+        {
+            let rendered: Vec<&str> =
+                msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
+            let non_json: Vec<&str> =
+                stderr.lines().filter(|line| !line.starts_with('{')).collect();
+            return Err(format!(
+                "did not find lint `{}` in output of example (got unknown_lints)\n\
+                Is the lint possibly misspelled, or does it need a `#![feature(...)]`?\n\
+                Output was:\n\
+                {}\n{}",
+                name,
+                rendered.join("\n"),
+                non_json.join("\n"),
+            )
+            .into());
         }
+
+        // Some lints override their code to something else (E0566).
+        // Try to find something that looks like it could be our lint.
+        let matches: Vec<_> = msgs
+            .iter()
+            .filter(
+                |msg| matches!(&msg["rendered"], serde_json::Value::String(s) if s.contains(name)),
+            )
+            .map(|msg| msg["rendered"].as_str().expect("rendered field should exist").to_string())
+            .collect();
+        if !matches.is_empty() {
+            return Ok(matches.join("\n"));
+        }
+
+        // Otherwise, give a descriptive error.
+        let rendered: Vec<&str> = msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
+        let non_json: Vec<&str> = stderr.lines().filter(|line| !line.starts_with('{')).collect();
+        Err(format!(
+            "did not find lint `{}` in output of example, got:\n{}\n{}",
+            name,
+            non_json.join("\n"),
+            rendered.join("\n")
+        )
+        .into())
     }
 
     /// Saves the mdbook lint chapters at the given path.
diff --git a/src/tools/opt-dist/src/bolt.rs b/src/tools/opt-dist/src/bolt.rs
index d9efbb8d880..0f1fda38115 100644
--- a/src/tools/opt-dist/src/bolt.rs
+++ b/src/tools/opt-dist/src/bolt.rs
@@ -1,6 +1,7 @@
 use anyhow::Context;
 use camino::{Utf8Path, Utf8PathBuf};
 
+use crate::environment::Environment;
 use crate::exec::cmd;
 use crate::training::BoltProfile;
 use crate::utils::io::copy_file;
@@ -45,13 +46,21 @@ pub fn with_bolt_instrumented<F: FnOnce(&Utf8Path) -> anyhow::Result<R>, R>(
 }
 
 /// Optimizes the file at `path` with BOLT in-place using the given `profile`.
-pub fn bolt_optimize(path: &Utf8Path, profile: &BoltProfile) -> anyhow::Result<()> {
+pub fn bolt_optimize(
+    path: &Utf8Path,
+    profile: &BoltProfile,
+    env: &Environment,
+) -> anyhow::Result<()> {
     // Copy the artifact to a new location, so that we do not use the same input and output file.
     // BOLT cannot handle optimizing when the input and output is the same file, because it performs
     // in-place patching.
     let temp_path = tempfile::NamedTempFile::new()?.into_temp_path();
     copy_file(path, &temp_path)?;
 
+    // FIXME: cdsplit in llvm-bolt is currently broken on AArch64, drop this once it's fixed upstream
+    let split_strategy =
+        if env.host_tuple().starts_with("aarch64") { "profile2" } else { "cdsplit" };
+
     cmd(&["llvm-bolt"])
         .arg(temp_path.display())
         .arg("-data")
@@ -65,7 +74,7 @@ pub fn bolt_optimize(path: &Utf8Path, profile: &BoltProfile) -> anyhow::Result<(
         // Split function code into hot and code regions
         .arg("-split-functions")
         // Split using best available strategy (three-way splitting, Cache-Directed Sort)
-        .arg("-split-strategy=cdsplit")
+        .arg(format!("-split-strategy={split_strategy}"))
         // Split as many basic blocks as possible
         .arg("-split-all-cold")
         // Move jump tables to a separate section
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index c871200f3cf..aa05b5f0e76 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -146,6 +146,21 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
             let target_triple =
                 std::env::var("PGO_HOST").expect("PGO_HOST environment variable missing");
 
+            let is_aarch64 = target_triple.starts_with("aarch64");
+
+            let mut skip_tests = vec![
+                // Fails because of linker errors, as of June 2023.
+                "tests/ui/process/nofile-limit.rs".to_string(),
+            ];
+
+            if is_aarch64 {
+                skip_tests.extend([
+                    // Those tests fail only inside of Docker on aarch64, as of December 2024
+                    "tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs".to_string(),
+                    "tests/ui/consts/large_const_alloc.rs".to_string(),
+                ]);
+            }
+
             let checkout_dir = Utf8PathBuf::from("/checkout");
             let env = EnvironmentBuilder::default()
                 .host_tuple(target_triple)
@@ -155,11 +170,9 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .artifact_dir(Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts"))
                 .build_dir(checkout_dir.join("obj"))
                 .shared_llvm(true)
-                .use_bolt(true)
-                .skipped_tests(vec![
-                    // Fails because of linker errors, as of June 2023.
-                    "tests/ui/process/nofile-limit.rs".to_string(),
-                ])
+                // FIXME: Enable bolt for aarch64 once it's fixed upstream. Broken as of December 2024.
+                .use_bolt(!is_aarch64)
+                .skipped_tests(skip_tests)
                 .build()?;
 
             (env, shared.build_args)
@@ -304,7 +317,8 @@ fn execute_pipeline(
             // the final dist build. However, when BOLT optimizes an artifact, it does so *in-place*,
             // therefore it will actually optimize all the hard links, which means that the final
             // packaged `libLLVM.so` file *will* be BOLT optimized.
-            bolt_optimize(&llvm_lib, &llvm_profile).context("Could not optimize LLVM with BOLT")?;
+            bolt_optimize(&llvm_lib, &llvm_profile, env)
+                .context("Could not optimize LLVM with BOLT")?;
 
             let rustc_lib = io::find_file_in_dir(&libdir, "librustc_driver", ".so")?;
 
@@ -319,7 +333,7 @@ fn execute_pipeline(
             print_free_disk_space()?;
 
             // Now optimize the library with BOLT.
-            bolt_optimize(&rustc_lib, &rustc_profile)
+            bolt_optimize(&rustc_lib, &rustc_profile, env)
                 .context("Could not optimize rustc with BOLT")?;
 
             // LLVM is not being cleared here, we want to use the BOLT-optimized LLVM
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index b5b360db252..e05b3c33ca3 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -123,9 +123,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
 
 [[package]]
 name = "block-buffer"
@@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "cc"
-version = "1.2.7"
+version = "1.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
+checksum = "ad0cf6e91fde44c773c6ee7ec6bba798504641a8bc2eb7e37a04ffbf4dfaa55a"
 dependencies = [
  "shlex",
 ]
@@ -190,9 +190,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.23"
+version = "4.5.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
+checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -200,9 +200,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.23"
+version = "4.5.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
+checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
 dependencies = [
  "anstream",
  "anstyle",
@@ -213,18 +213,18 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.40"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac2e663e3e3bed2d32d065a8404024dad306e699a04263ec59919529f803aee9"
+checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.5.18"
+version = "4.5.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -279,6 +279,41 @@ dependencies = [
 ]
 
 [[package]]
+name = "darling"
+version = "0.20.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.20.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.20.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
 name = "dateparser"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -302,6 +337,37 @@ dependencies = [
 ]
 
 [[package]]
+name = "derive_builder"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
+dependencies = [
+ "derive_builder_core",
+ "syn",
+]
+
+[[package]]
 name = "digest"
 version = "0.10.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -452,17 +518,18 @@ dependencies = [
 
 [[package]]
 name = "handlebars"
-version = "6.2.0"
+version = "6.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315"
+checksum = "3d6b224b95c1e668ac0270325ad563b2eef1469fbbb8959bc7c692c844b813d9"
 dependencies = [
+ "derive_builder",
  "log",
  "num-order",
  "pest",
  "pest_derive",
  "serde",
  "serde_json",
- "thiserror 1.0.69",
+ "thiserror 2.0.11",
 ]
 
 [[package]]
@@ -654,6 +721,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
 name = "idna"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -739,9 +812,9 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
 
 [[package]]
 name = "litemap"
@@ -1006,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
 dependencies = [
  "memchr",
- "thiserror 2.0.9",
+ "thiserror 2.0.11",
  "ucd-trie",
 ]
 
@@ -1046,21 +1119,21 @@ dependencies = [
 
 [[package]]
 name = "phf"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
 dependencies = [
- "phf_shared 0.11.2",
+ "phf_shared 0.11.3",
 ]
 
 [[package]]
 name = "phf_codegen"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
 dependencies = [
- "phf_generator 0.11.2",
- "phf_shared 0.11.2",
+ "phf_generator 0.11.3",
+ "phf_shared 0.11.3",
 ]
 
 [[package]]
@@ -1075,11 +1148,11 @@ dependencies = [
 
 [[package]]
 name = "phf_generator"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
 dependencies = [
- "phf_shared 0.11.2",
+ "phf_shared 0.11.3",
  "rand",
 ]
 
@@ -1089,16 +1162,16 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
 dependencies = [
- "siphasher",
+ "siphasher 0.3.11",
 ]
 
 [[package]]
 name = "phf_shared"
-version = "0.11.2"
+version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
 dependencies = [
- "siphasher",
+ "siphasher 1.0.1",
 ]
 
 [[package]]
@@ -1133,9 +1206,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
 dependencies = [
  "unicode-ident",
 ]
@@ -1146,7 +1219,7 @@ version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.7.0",
  "memchr",
  "pulldown-cmark-escape 0.10.1",
  "unicase",
@@ -1158,7 +1231,7 @@ version = "0.11.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.7.0",
  "memchr",
  "pulldown-cmark-escape 0.11.0",
  "unicase",
@@ -1170,7 +1243,7 @@ version = "0.12.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.7.0",
  "getopts",
  "memchr",
  "pulldown-cmark-escape 0.11.0",
@@ -1252,7 +1325,7 @@ version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.7.0",
 ]
 
 [[package]]
@@ -1298,11 +1371,11 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.42"
+version = "0.38.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
+checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
 dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.7.0",
  "errno",
  "libc",
  "linux-raw-sys",
@@ -1358,9 +1431,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.134"
+version = "1.0.135"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
+checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
 dependencies = [
  "itoa",
  "memchr",
@@ -1401,6 +1474,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
 
 [[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
 name = "smallvec"
 version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1446,9 +1525,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.94"
+version = "2.0.96"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1538,11 +1617,11 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "2.0.9"
+version = "2.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc"
+checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
 dependencies = [
- "thiserror-impl 2.0.9",
+ "thiserror-impl 2.0.11",
 ]
 
 [[package]]
@@ -1558,9 +1637,9 @@ dependencies = [
 
 [[package]]
 name = "thiserror-impl"
-version = "2.0.9"
+version = "2.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4"
+checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1882,9 +1961,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
 name = "winnow"
-version = "0.6.22"
+version = "0.6.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980"
+checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
 dependencies = [
  "memchr",
 ]
diff --git a/tests/codegen-units/item-collection/closures.rs b/tests/codegen-units/item-collection/closures.rs
index 5fc80230925..864f98817a8 100644
--- a/tests/codegen-units/item-collection/closures.rs
+++ b/tests/codegen-units/item-collection/closures.rs
@@ -10,3 +10,9 @@ pub async fn async_fn() {}
 pub fn closure() {
     let _ = || {};
 }
+
+//~ MONO_ITEM fn A::{constant#0}::{closure#0} @@
+trait A where
+    [(); (|| {}, 1).1]: Sized,
+{
+}
diff --git a/tests/codegen-units/item-collection/drop-glue-eager.rs b/tests/codegen-units/item-collection/drop-glue-eager.rs
new file mode 100644
index 00000000000..c81074de490
--- /dev/null
+++ b/tests/codegen-units/item-collection/drop-glue-eager.rs
@@ -0,0 +1,56 @@
+// Ensure that we *eagerly* monomorphize drop instances for structs with lifetimes.
+
+//@ compile-flags:-Zprint-mono-items=eager
+//@ compile-flags:--crate-type=lib
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop))
+struct StructWithDrop {
+    x: i32,
+}
+
+impl Drop for StructWithDrop {
+    //~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+struct StructNoDrop {
+    x: i32,
+}
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop))
+enum EnumWithDrop {
+    A(i32),
+}
+
+impl Drop for EnumWithDrop {
+    //~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+enum EnumNoDrop {
+    A(i32),
+}
+
+// We should be able to monomorphize drops for struct with lifetimes.
+impl<'a> Drop for StructWithDropAndLt<'a> {
+    //~ MONO_ITEM fn <StructWithDropAndLt<'_> as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
+
+//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDropAndLt<'_>> - shim(Some(StructWithDropAndLt<'_>))
+struct StructWithDropAndLt<'a> {
+    x: &'a i32,
+}
+
+// Make sure we don't ICE when checking impossible predicates for the struct.
+// Regression test for <https://github.com/rust-lang/rust/issues/135515>.
+//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithLtAndPredicate<'_>> - shim(Some(StructWithLtAndPredicate<'_>))
+struct StructWithLtAndPredicate<'a: 'a> {
+    x: &'a i32,
+}
+
+// We should be able to monomorphize drops for struct with lifetimes.
+impl<'a> Drop for StructWithLtAndPredicate<'a> {
+    //~ MONO_ITEM fn <StructWithLtAndPredicate<'_> as std::ops::Drop>::drop
+    fn drop(&mut self) {}
+}
diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout
index c2d9309ba2e..c1b246e849c 100644
--- a/tests/run-make/rustdoc-default-output/output-default.stdout
+++ b/tests/run-make/rustdoc-default-output/output-default.stdout
@@ -194,7 +194,8 @@ Options:
         --doctest-compilation-args add arguments to be used when compiling doctests
                         
         --disable-minification 
-                        removed
+                        disable the minification of CSS/JS files
+                        (perma-unstable, do not use with cached files)
         --plugin-path DIR
                         removed, see issue #44136
                         <https://github.com/rust-lang/rust/issues/44136> for
diff --git a/tests/rustdoc-js-std/return-based-sort.js b/tests/rustdoc-js-std/return-based-sort.js
new file mode 100644
index 00000000000..30baf1cd36e
--- /dev/null
+++ b/tests/rustdoc-js-std/return-based-sort.js
@@ -0,0 +1,30 @@
+// test that `clone`-like functions are sorted lower when
+// a search is based soley on return type
+
+const FILTER_CRATE = "core";
+
+const EXPECTED = [
+    {
+        'query': '-> AllocError',
+        'others': [
+            { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+            { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+        ],
+    },
+    {
+        'query': 'AllocError',
+        'returned': [
+            { 'path': 'core::alloc::Allocator', 'name': 'allocate' },
+            { 'path': 'core::alloc::AllocError', 'name': 'clone' },
+         ],
+    },
+    {
+        'query': '-> &str',
+        'others': [
+            // type_name_of_val should not be consider clone-like
+            { 'path': 'core::any', 'name': 'type_name_of_val' },
+            // this returns `Option<&str>`, and thus should be sorted lower
+            { 'path': 'core::str::Split', 'name': 'next' },
+         ],
+    },
+]
diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs
index 0b341e2bda7..c238a536e0d 100644
--- a/tests/rustdoc-json/return_private.rs
+++ b/tests/rustdoc-json/return_private.rs
@@ -6,7 +6,7 @@ mod secret {
 }
 
 //@ has "$.index[*][?(@.name=='get_secret')].inner.function"
-//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"secret::Secret\"
+//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"Secret\"
 pub fn get_secret() -> secret::Secret {
     secret::Secret
 }
diff --git a/tests/rustdoc/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def-pats.rs
new file mode 100644
index 00000000000..147902b44cf
--- /dev/null
+++ b/tests/rustdoc/jump-to-def-pats.rs
@@ -0,0 +1,52 @@
+// This test ensures that patterns also get a link generated.
+
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+//@ has 'src/foo/jump-to-def-pats.rs.html'
+
+use std::fmt;
+
+pub enum MyEnum<T, E> {
+    Ok(T),
+    Err(E),
+    Some(T),
+    None,
+}
+
+pub enum X {
+    A,
+}
+
+pub fn foo() -> Result<(), ()> {
+    // FIXME: would be nice to be able to check both the class and the href at the same time so
+    // we could check the text as well...
+    //@ has - '//a[@class="prelude-val"]/@href' '{{channel}}/core/result/enum.Result.html#variant.Ok'
+    //@ has - '//a[@href="{{channel}}/core/result/enum.Result.html#variant.Ok"]' 'Ok'
+    Ok(())
+}
+
+impl<T, E> fmt::Display for MyEnum<T, E> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            //@ has - '//a[@href="#12"]' 'Self::Ok'
+            Self::Ok(_) => f.write_str("MyEnum::Ok"),
+            //@ has - '//a[@href="#13"]' 'MyEnum::Err'
+            MyEnum::Err(_) => f.write_str("MyEnum::Err"),
+            //@ has - '//a[@href="#14"]' 'Self::Some'
+            Self::Some(_) => f.write_str("MyEnum::Some"),
+            //@ has - '//a[@href="#15"]' 'Self::None'
+            Self::None => f.write_str("MyEnum::None"),
+        }
+    }
+}
+
+impl X {
+    fn p(&self) -> &str {
+        match self {
+            //@ has - '//a[@href="#19"]' 'Self::A'
+            Self::A => "X::A",
+        }
+    }
+}
diff --git a/tests/ui/associated-types/issue-91231.rs b/tests/ui/associated-types/issue-91231.rs
index d1c99fd44fa..a04ab60a7fc 100644
--- a/tests/ui/associated-types/issue-91231.rs
+++ b/tests/ui/associated-types/issue-91231.rs
@@ -3,7 +3,7 @@
 #![feature(extern_types)]
 #![allow(dead_code)]
 
-extern {
+extern "C" {
     type Extern;
 }
 
diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
index db5895108bb..37977b45250 100644
--- a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
@@ -1,11 +1,12 @@
-error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
+error[E0277]: the trait bound `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception-target-features.rs:16:10
    |
 LL |     test(target_feature);
-   |     ---- ^^^^^^^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
+   |     ---- ^^^^^^^^^^^^^^ unsatisfied trait bound
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `AsyncFn()` is not implemented for fn item `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
 note: required by a bound in `test`
   --> $DIR/fn-exception-target-features.rs:13:17
    |
diff --git a/tests/ui/attributes/key-value-expansion.rs b/tests/ui/attributes/key-value-expansion.rs
index e5700a75935..9034e0a7398 100644
--- a/tests/ui/attributes/key-value-expansion.rs
+++ b/tests/ui/attributes/key-value-expansion.rs
@@ -39,7 +39,7 @@ bug!();
 macro_rules! doc_comment {
     ($x:expr) => {
         #[doc = $x]
-        extern {}
+        extern "C" {}
     };
 }
 
diff --git a/tests/ui/borrowck/issue-92157.rs b/tests/ui/borrowck/issue-92157.rs
index 3a6f8908b21..a2b685cdf6e 100644
--- a/tests/ui/borrowck/issue-92157.rs
+++ b/tests/ui/borrowck/issue-92157.rs
@@ -5,7 +5,7 @@
 
 #[cfg(target_os = "linux")]
 #[link(name = "c")]
-extern {}
+extern "C" {}
 
 #[lang = "start"]
 fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize {
diff --git a/tests/ui/closures/binder/nested-closures-regions.stderr b/tests/ui/closures/binder/nested-closures-regions.stderr
index a30339ac67b..909cbcaa808 100644
--- a/tests/ui/closures/binder/nested-closures-regions.stderr
+++ b/tests/ui/closures/binder/nested-closures-regions.stderr
@@ -9,7 +9,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn((&(),)),
                (),
            ]
-   = note: late-bound region is '?4
+   = note: late-bound region is '?3
    = note: late-bound region is '?2
    = note: number of external vids: 3
    = note: where '?1: '?2
@@ -26,7 +26,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn(()),
                (),
            ]
-   = note: late-bound region is '?2
+   = note: late-bound region is '?1
 
 note: no external requirements
   --> $DIR/nested-closures-regions.rs:7:1
diff --git a/tests/ui/coherence/coherence-negative-impls-copy.rs b/tests/ui/coherence/coherence-negative-impls-copy.rs
index 377d750f8ba..c0d852180a5 100644
--- a/tests/ui/coherence/coherence-negative-impls-copy.rs
+++ b/tests/ui/coherence/coherence-negative-impls-copy.rs
@@ -18,7 +18,7 @@ impl !Copy for WithDrop {}
 
 struct Type;
 trait Trait {}
-extern {
+extern "C" {
     type ExternType;
 }
 
diff --git a/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs b/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
index e357d3c6cb5..2ac57f35674 100644
--- a/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
+++ b/tests/ui/conditional-compilation/cfg_accessible-not_sure.rs
@@ -63,7 +63,7 @@ const B: bool = true;
 
 // ForeignType::unresolved - error
 
-extern {
+extern "C" {
     type ForeignType;
 }
 
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr
new file mode 100644
index 00000000000..c6fb07926c8
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr
@@ -0,0 +1,45 @@
+error: the constant `N` is not of type `bool`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:50
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |                                                  ^^^^ expected `bool`, found `usize`
+   |
+note: required by a const generic parameter in `A`
+  --> $DIR/type-mismatch-in-nested-goal.rs:5:9
+   |
+LL | trait A<const B: bool> {}
+   |         ^^^^^^^^^^^^^ required by this const generic parameter in `A`
+
+error: the constant `true` is not of type `usize`
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected `usize`, found `bool`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a const generic parameter in `needs_a`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:12
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |            ^^^^^^^^^^^^^^ required by this const generic parameter in `needs_a`
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected an array with a size of true, found one with a size of 0
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected array `[u8; true]`
+              found array `[_; 0]`
+note: function defined here
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:4
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |    ^^^^^^^                 ----------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr
new file mode 100644
index 00000000000..c6fb07926c8
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr
@@ -0,0 +1,45 @@
+error: the constant `N` is not of type `bool`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:50
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |                                                  ^^^^ expected `bool`, found `usize`
+   |
+note: required by a const generic parameter in `A`
+  --> $DIR/type-mismatch-in-nested-goal.rs:5:9
+   |
+LL | trait A<const B: bool> {}
+   |         ^^^^^^^^^^^^^ required by this const generic parameter in `A`
+
+error: the constant `true` is not of type `usize`
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected `usize`, found `bool`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a const generic parameter in `needs_a`
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:12
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |            ^^^^^^^^^^^^^^ required by this const generic parameter in `needs_a`
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch-in-nested-goal.rs:13:13
+   |
+LL |     needs_a([]);
+   |     ------- ^^ expected an array with a size of true, found one with a size of 0
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected array `[u8; true]`
+              found array `[_; 0]`
+note: function defined here
+  --> $DIR/type-mismatch-in-nested-goal.rs:9:4
+   |
+LL | fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+   |    ^^^^^^^                 ----------
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.rs b/tests/ui/const-generics/type-mismatch-in-nested-goal.rs
new file mode 100644
index 00000000000..fd29019f89b
--- /dev/null
+++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.rs
@@ -0,0 +1,17 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+
+trait A<const B: bool> {}
+
+impl A<true> for () {}
+
+fn needs_a<const N: usize>(_: [u8; N]) where (): A<N> {}
+//~^ ERROR the constant `N` is not of type `bool`
+
+pub fn main() {
+    needs_a([]);
+    //~^ ERROR the constant `true` is not of type `usize`
+    //~| ERROR mismatched types
+    // FIXME(const_generics): we should hide this error as we've already errored above
+}
diff --git a/tests/ui/consts/const-eval/validation-ice-extern-type-field.rs b/tests/ui/consts/const-eval/validation-ice-extern-type-field.rs
index 3502409d576..8a32b170c40 100644
--- a/tests/ui/consts/const-eval/validation-ice-extern-type-field.rs
+++ b/tests/ui/consts/const-eval/validation-ice-extern-type-field.rs
@@ -1,6 +1,6 @@
 #![feature(extern_types)]
 
-extern {
+extern "C" {
     type Opaque;
 }
 
diff --git a/tests/ui/consts/promoted-const-drop.rs b/tests/ui/consts/promoted-const-drop.rs
index e09c30ea785..1d1897e15d4 100644
--- a/tests/ui/consts/promoted-const-drop.rs
+++ b/tests/ui/consts/promoted-const-drop.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_destruct)]
 
 struct A();
 
diff --git a/tests/ui/consts/promoted_const_call.rs b/tests/ui/consts/promoted_const_call.rs
index c3920ff7241..79cb2ea2a02 100644
--- a/tests/ui/consts/promoted_const_call.rs
+++ b/tests/ui/consts/promoted_const_call.rs
@@ -1,6 +1,4 @@
-//@ known-bug: #103507
-
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_destruct)]
 
 struct Panic;
 impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
@@ -8,15 +6,15 @@ impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
 pub const fn id<T>(x: T) -> T { x }
 pub const C: () = {
     let _: &'static _ = &id(&Panic);
-    //FIXME ~^ ERROR: temporary value dropped while borrowed
-    //FIXME ~| ERROR: temporary value dropped while borrowed
+    //~^ ERROR: temporary value dropped while borrowed
+    //~| ERROR: temporary value dropped while borrowed
 };
 
 fn main() {
     let _: &'static _ = &id(&Panic);
-    //FIXME ~^ ERROR: temporary value dropped while borrowed
-    //FIXME ~| ERROR: temporary value dropped while borrowed
+    //~^ ERROR: temporary value dropped while borrowed
+    //~| ERROR: temporary value dropped while borrowed
     let _: &'static _ = &&(Panic, 0).1;
-    //FIXME~^ ERROR: temporary value dropped while borrowed
-    //FIXME~| ERROR: temporary value dropped while borrowed
+    //~^ ERROR: temporary value dropped while borrowed
+    //~| ERROR: temporary value dropped while borrowed
 }
diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr
index 40c6d083b06..7a9cdd68704 100644
--- a/tests/ui/consts/promoted_const_call.stderr
+++ b/tests/ui/consts/promoted_const_call.stderr
@@ -1,17 +1,25 @@
-error[E0493]: destructor of `Panic` cannot be evaluated at compile-time
-  --> $DIR/promoted_const_call.rs:10:30
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promoted_const_call.rs:8:26
    |
 LL |     let _: &'static _ = &id(&Panic);
-   |                              ^^^^^ - value is dropped here
-   |                              |
-   |                              the destructor for this type cannot be evaluated in constants
+   |            ----------    ^^^^^^^^^^ creates a temporary value which is freed while still in use
+   |            |
+   |            type annotation requires that borrow lasts for `'static`
+...
+LL | };
+   | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/promoted_const_call.rs:8:30
    |
-   = note: see issue #133214 <https://github.com/rust-lang/rust/issues/133214> for more information
-   = help: add `#![feature(const_destruct)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+LL |     let _: &'static _ = &id(&Panic);
+   |            ----------        ^^^^^ - temporary value is freed at the end of this statement
+   |            |                 |
+   |            |                 creates a temporary value which is freed while still in use
+   |            type annotation requires that borrow lasts for `'static`
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:16:26
+  --> $DIR/promoted_const_call.rs:14:26
    |
 LL |     let _: &'static _ = &id(&Panic);
    |            ----------    ^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -22,7 +30,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:16:30
+  --> $DIR/promoted_const_call.rs:14:30
    |
 LL |     let _: &'static _ = &id(&Panic);
    |            ----------        ^^^^^ - temporary value is freed at the end of this statement
@@ -31,7 +39,7 @@ LL |     let _: &'static _ = &id(&Panic);
    |            type annotation requires that borrow lasts for `'static`
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:19:26
+  --> $DIR/promoted_const_call.rs:17:26
    |
 LL |     let _: &'static _ = &&(Panic, 0).1;
    |            ----------    ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -42,7 +50,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:19:27
+  --> $DIR/promoted_const_call.rs:17:27
    |
 LL |     let _: &'static _ = &&(Panic, 0).1;
    |            ----------     ^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -52,7 +60,6 @@ LL |     let _: &'static _ = &&(Panic, 0).1;
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0493, E0716.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/delegation/glob-non-impl.rs b/tests/ui/delegation/glob-non-impl.rs
index d523731eeb3..e3a4061fb15 100644
--- a/tests/ui/delegation/glob-non-impl.rs
+++ b/tests/ui/delegation/glob-non-impl.rs
@@ -11,7 +11,7 @@ trait OtherTrait {
     reuse Trait::*; //~ ERROR glob delegation is only supported in impls
 }
 
-extern {
+extern "C" {
     reuse Trait::*; //~ ERROR delegation is not supported in `extern` blocks
 }
 
diff --git a/tests/ui/enum-discriminant/eval-error.rs b/tests/ui/enum-discriminant/eval-error.rs
new file mode 100644
index 00000000000..f2c3b581627
--- /dev/null
+++ b/tests/ui/enum-discriminant/eval-error.rs
@@ -0,0 +1,37 @@
+union Foo {
+    a: str,
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>`
+}
+
+enum Bar {
+    Boo = {
+        let _: Option<Foo> = None;
+        0
+    },
+}
+
+union Foo2 {}
+//~^ ERROR unions cannot have zero fields
+
+enum Bar2 {
+    Boo = {
+        let _: Option<Foo2> = None;
+        0
+    },
+}
+
+#[repr(u8, packed)]
+//~^ ERROR attribute should be applied to a struct or union
+enum Foo3 {
+    A
+}
+
+enum Bar3 {
+    Boo = {
+        let _: Option<Foo3> = None;
+        0
+    },
+}
+
+fn main() {}
diff --git a/tests/ui/enum-discriminant/eval-error.stderr b/tests/ui/enum-discriminant/eval-error.stderr
new file mode 100644
index 00000000000..0f12308de3c
--- /dev/null
+++ b/tests/ui/enum-discriminant/eval-error.stderr
@@ -0,0 +1,51 @@
+error: unions cannot have zero fields
+  --> $DIR/eval-error.rs:14:1
+   |
+LL | union Foo2 {}
+   | ^^^^^^^^^^^^^
+
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/eval-error.rs:24:12
+   |
+LL |   #[repr(u8, packed)]
+   |              ^^^^^^
+LL |
+LL | / enum Foo3 {
+LL | |     A
+LL | | }
+   | |_- not a struct or union
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/eval-error.rs:2:8
+   |
+LL |     a: str,
+   |        ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of a union may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     a: &str,
+   |        +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     a: Box<str>,
+   |        ++++   +
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/eval-error.rs:2:5
+   |
+LL |     a: str,
+   |     ^^^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |     a: std::mem::ManuallyDrop<str>,
+   |        +++++++++++++++++++++++   +
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0517, E0740.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/extern/extern-type-diag-not-similar.rs b/tests/ui/extern/extern-type-diag-not-similar.rs
index 39d00a6c1bc..cd3eec9f1f7 100644
--- a/tests/ui/extern/extern-type-diag-not-similar.rs
+++ b/tests/ui/extern/extern-type-diag-not-similar.rs
@@ -4,11 +4,11 @@
 // because they are both extern types.
 
 #![feature(extern_types)]
-extern {
+extern "C" {
     type ShouldNotBeMentioned;
 }
 
-extern {
+extern "C" {
     type Foo;
 }
 
diff --git a/tests/ui/extern/issue-10025.rs b/tests/ui/extern/issue-10025.rs
index 140012f4a16..9be0f616fd2 100644
--- a/tests/ui/extern/issue-10025.rs
+++ b/tests/ui/extern/issue-10025.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-#![allow(dead_code)]
+#![allow(dead_code, missing_abi)]
 
 unsafe extern fn foo() {}
 unsafe extern "C" fn bar() {}
diff --git a/tests/ui/extern/issue-95829.rs b/tests/ui/extern/issue-95829.rs
index c5ae4c68265..493d53d2532 100644
--- a/tests/ui/extern/issue-95829.rs
+++ b/tests/ui/extern/issue-95829.rs
@@ -1,6 +1,6 @@
 //@ edition:2018
 
-extern {
+extern "C" {
     async fn L() { //~ ERROR: incorrect function inside `extern` block
         //~^ ERROR: functions in `extern` blocks cannot have `async` qualifier
         async fn M() {}
diff --git a/tests/ui/extern/issue-95829.stderr b/tests/ui/extern/issue-95829.stderr
index 2f396b8cc04..2acd0fa3a26 100644
--- a/tests/ui/extern/issue-95829.stderr
+++ b/tests/ui/extern/issue-95829.stderr
@@ -1,8 +1,8 @@
 error: incorrect function inside `extern` block
   --> $DIR/issue-95829.rs:4:14
    |
-LL |   extern {
-   |   ------ `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL |   extern "C" {
+   |   ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
 LL |       async fn L() {
    |  ______________^___-
    | |              |
@@ -18,8 +18,8 @@ LL | |     }
 error: functions in `extern` blocks cannot have `async` qualifier
   --> $DIR/issue-95829.rs:4:5
    |
-LL | extern {
-   | ------ in this `extern` block
+LL | extern "C" {
+   | ---------- in this `extern` block
 LL |     async fn L() {
    |     ^^^^^ help: remove the `async` qualifier
 
diff --git a/tests/ui/extern/not-in-block.rs b/tests/ui/extern/not-in-block.rs
index d3bcafdef7b..c2161635090 100644
--- a/tests/ui/extern/not-in-block.rs
+++ b/tests/ui/extern/not-in-block.rs
@@ -1,4 +1,5 @@
 #![crate_type = "lib"]
+#![allow(missing_abi)]
 
 extern fn none_fn(x: bool) -> i32;
 //~^ ERROR free function without a body
diff --git a/tests/ui/extern/not-in-block.stderr b/tests/ui/extern/not-in-block.stderr
index 2544949ab17..f86c279a234 100644
--- a/tests/ui/extern/not-in-block.stderr
+++ b/tests/ui/extern/not-in-block.stderr
@@ -1,5 +1,5 @@
 error: free function without a body
-  --> $DIR/not-in-block.rs:3:1
+  --> $DIR/not-in-block.rs:4:1
    |
 LL | extern fn none_fn(x: bool) -> i32;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL | extern { fn none_fn(x: bool) -> i32; }
    | ~~~~~~~~                             +
 
 error: free function without a body
-  --> $DIR/not-in-block.rs:5:1
+  --> $DIR/not-in-block.rs:6:1
    |
 LL | extern "C" fn c_fn(x: bool) -> i32;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs
index 2ac3ca29355..e8634de86ea 100644
--- a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs
+++ b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.rs
@@ -1,6 +1,6 @@
 // Regression test for issue #91370.
 
-extern {
+extern "C" {
     //~^ `extern` blocks define existing foreign functions
     fn f() {
         //~^ incorrect function inside `extern` block
diff --git a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr
index fea2ab61e92..155fdf9d09a 100644
--- a/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr
+++ b/tests/ui/foreign/issue-91370-foreign-fn-block-impl.stderr
@@ -1,8 +1,8 @@
 error: incorrect function inside `extern` block
   --> $DIR/issue-91370-foreign-fn-block-impl.rs:5:8
    |
-LL |   extern {
-   |   ------ `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL |   extern "C" {
+   |   ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
 LL |
 LL |       fn f() {
    |  ________^___-
diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
index 6eabd9b1015..73a0363904a 100644
--- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
+++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs
@@ -21,7 +21,7 @@ struct S;
 #[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes
 fn foo6<const X: usize>() {}
 
-extern {
+extern "C" {
     #[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function
     fn foo7<const X: usize>(); //~ ERROR foreign items may not have const parameters
 }
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
index 168ed37d0e6..02718334c73 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr
+++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
@@ -1,4 +1,4 @@
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
    |
 LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
@@ -35,7 +35,7 @@ LL | | where
 LL | |     T: Unsize<U>,
    | |_________________^
 
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:46:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs
index bfcee1ac503..0ca34da95f5 100644
--- a/tests/ui/issues/issue-25901.rs
+++ b/tests/ui/issues/issue-25901.rs
@@ -2,7 +2,7 @@ struct A;
 struct B;
 
 static S: &'static B = &A;
-//~^ ERROR cannot perform conditionally-const deref coercion
+//~^ ERROR cannot perform non-const deref coercion
 
 use std::ops::Deref;
 
diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr
index a954f38af83..233b5bfee50 100644
--- a/tests/ui/issues/issue-25901.stderr
+++ b/tests/ui/issues/issue-25901.stderr
@@ -1,4 +1,4 @@
-error[E0658]: cannot perform conditionally-const deref coercion on `A` in statics
+error[E0015]: cannot perform non-const deref coercion on `A` in statics
   --> $DIR/issue-25901.rs:4:24
    |
 LL | static S: &'static B = &A;
@@ -10,11 +10,14 @@ note: deref defined here
    |
 LL |     type Target = B;
    |     ^^^^^^^^^^^
+note: impl defined here, but it is not `const`
+  --> $DIR/issue-25901.rs:9:1
+   |
+LL | impl Deref for A {
+   | ^^^^^^^^^^^^^^^^
    = note: calls in statics are limited to constant functions, tuple structs and tuple variants
-   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
-   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0658`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.rs b/tests/ui/layout/base-layout-is-sized-ice-123078.rs
index b1c33e15075..15f11145f84 100644
--- a/tests/ui/layout/base-layout-is-sized-ice-123078.rs
+++ b/tests/ui/layout/base-layout-is-sized-ice-123078.rs
@@ -8,7 +8,6 @@ struct S {
 }
 
 const C: S = unsafe { std::mem::transmute(()) };
-//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
 const _: [(); {
     C;
     0
diff --git a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
index 455bd2cbf8b..9181368533a 100644
--- a/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
+++ b/tests/ui/layout/base-layout-is-sized-ice-123078.stderr
@@ -16,16 +16,6 @@ help: the `Box` type always has a statically known size and allocates its conten
 LL |     a: Box<[u8]>,
    |        ++++    +
 
-error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/base-layout-is-sized-ice-123078.rs:10:23
-   |
-LL | const C: S = unsafe { std::mem::transmute(()) };
-   |                       ^^^^^^^^^^^^^^^^^^^
-   |
-   = note: source type: `()` (0 bits)
-   = note: target type: `S` (size can vary because of [u8])
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0512.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index 1fc55511384..319c0de26a9 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -590,7 +590,7 @@ LL | type Impossible = (str, str);
    = help: the trait `Sized` is not implemented for `str`
    = note: only the last element of a tuple may have a dynamically sized type
 
-error: the type `EmptyUnion` has an unknown layout
+error: the type has an unknown layout
   --> $DIR/debug.rs:83:1
    |
 LL | union EmptyUnion {}
diff --git a/tests/ui/link-native-libs/issue-109144.rs b/tests/ui/link-native-libs/issue-109144.rs
index 2f740e55389..6970a4989bb 100644
--- a/tests/ui/link-native-libs/issue-109144.rs
+++ b/tests/ui/link-native-libs/issue-109144.rs
@@ -1,4 +1,4 @@
 #![crate_type = "lib"]
 #[link(kind = "static", modifiers = "+whole-archive,+bundle")]
 //~^ ERROR `#[link]` attribute requires a `name = "string"` argument
-extern  {}
+extern "C" {}
diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.stderr b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
index e142835a9d6..aae8f7de966 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-1.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-1.stderr
@@ -1,6 +1,14 @@
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/suggest-libname-only-1.rs:7:1
+   |
+LL | extern { }
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   |
+   = note: `#[warn(missing_abi)]` on by default
+
 error: could not find native static library `libfoo.a`, perhaps an -L flag is missing?
    |
    = help: only provide the library name `foo`, not the full filename
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.stderr b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
index 392d2f01f61..a2adaee3f97 100644
--- a/tests/ui/link-native-libs/suggest-libname-only-2.stderr
+++ b/tests/ui/link-native-libs/suggest-libname-only-2.stderr
@@ -1,6 +1,14 @@
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/suggest-libname-only-2.rs:7:1
+   |
+LL | extern { }
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   |
+   = note: `#[warn(missing_abi)]` on by default
+
 error: could not find native static library `bar.lib`, perhaps an -L flag is missing?
    |
    = help: only provide the library name `bar`, not the full filename
 
-error: aborting due to 1 previous error
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/lint/function-item-references.rs b/tests/ui/lint/function-item-references.rs
index 918d72e28a9..4f2fc4de863 100644
--- a/tests/ui/lint/function-item-references.rs
+++ b/tests/ui/lint/function-item-references.rs
@@ -11,7 +11,7 @@ fn baz(x: u32, y: u32) -> u32 { x + y }
 unsafe fn unsafe_fn() { }
 extern "C" fn c_fn() { }
 unsafe extern "C" fn unsafe_c_fn() { }
-unsafe extern fn variadic(_x: u32, _args: ...) { }
+unsafe extern "C" fn variadic(_x: u32, _args: ...) { }
 fn take_generic_ref<'a, T>(_x: &'a T) { }
 fn take_generic_array<T, const N: usize>(_x: [T; N]) { }
 fn multiple_generic<T, U>(_x: T, _y: U) { }
diff --git a/tests/ui/lint/lint-ctypes.rs b/tests/ui/lint/lint-ctypes.rs
index dae07930aba..6dd9be10a48 100644
--- a/tests/ui/lint/lint-ctypes.rs
+++ b/tests/ui/lint/lint-ctypes.rs
@@ -72,7 +72,7 @@ extern "C" {
     pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
     pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
 
-    pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
+    pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>);
     //~^ ERROR: uses type `Option<UnsafeCell<extern "C" fn()>>`
     pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
     //~^ ERROR: uses type `Option<UnsafeCell<&i32>>`
diff --git a/tests/ui/lint/lint-ctypes.stderr b/tests/ui/lint/lint-ctypes.stderr
index 2c81c7b8e4b..8137ae868d3 100644
--- a/tests/ui/lint/lint-ctypes.stderr
+++ b/tests/ui/lint/lint-ctypes.stderr
@@ -227,8 +227,8 @@ LL |     pub fn raw_array(arr: [u8; 8]);
 error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:75:26
    |
-LL |     pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+LL |     pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
diff --git a/tests/ui/macros/issue-68060.rs b/tests/ui/macros/issue-68060.rs
index 1a826bd60e0..4eddb96848c 100644
--- a/tests/ui/macros/issue-68060.rs
+++ b/tests/ui/macros/issue-68060.rs
@@ -3,8 +3,6 @@ fn main() {
         .map(
             #[target_feature(enable = "")]
             //~^ ERROR: attribute should be applied to a function
-            //~| ERROR: feature named `` is not valid
-            //~| NOTE: `` is not valid for this target
             #[track_caller]
             //~^ ERROR: `#[track_caller]` on closures is currently unstable
             //~| NOTE: see issue #87417
diff --git a/tests/ui/macros/issue-68060.stderr b/tests/ui/macros/issue-68060.stderr
index 5724a9ea438..ef2246d5bd6 100644
--- a/tests/ui/macros/issue-68060.stderr
+++ b/tests/ui/macros/issue-68060.stderr
@@ -7,14 +7,8 @@ LL |             #[target_feature(enable = "")]
 LL |             |_| (),
    |             ------ not a function definition
 
-error: the feature named `` is not valid for this target
-  --> $DIR/issue-68060.rs:4:30
-   |
-LL |             #[target_feature(enable = "")]
-   |                              ^^^^^^^^^^^ `` is not valid for this target
-
 error[E0658]: `#[track_caller]` on closures is currently unstable
-  --> $DIR/issue-68060.rs:8:13
+  --> $DIR/issue-68060.rs:6:13
    |
 LL |             #[track_caller]
    |             ^^^^^^^^^^^^^^^
@@ -23,6 +17,6 @@ LL |             #[track_caller]
    = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
index a7a59dccf22..a445534c8d8 100644
--- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -17,7 +17,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                       -  -  ^^^^^^ assignment requires that `'1` must outlive `'2`
    |                                       |  |
    |                                       |  has type `&'1 i32`
-   |                                       has type `&'?2 mut &'2 i32`
+   |                                       has type `&'?1 mut &'2 i32`
 
 note: no external requirements
   --> $DIR/escape-argument-callee.rs:20:1
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 0094d7a50d3..621c1ea083b 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -20,7 +20,7 @@ LL |     foo(cell, |cell_a, cell_x| {
 LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
    |
-   = note: requirement occurs because of the type `Cell<&'?8 u32>`, which makes the generic argument `&'?8 u32` invariant
+   = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant
    = note: the struct `Cell<T>` is invariant over the parameter `T`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 4558ff50674..f48ed2823dd 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - has type `&'?7 Cell<&'1 u32>`
+   |                                                ---------  - has type `&'?6 Cell<&'1 u32>`
    |                                                |
-   |                                                has type `&'?5 Cell<&'2 &'?1 u32>`
+   |                                                has type `&'?4 Cell<&'2 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 83173ae80c0..a090e94593f 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- has type `&'?8 Cell<&'2 &'?2 u32>`
+   |                                                ----------  ---------- has type `&'?7 Cell<&'2 &'?2 u32>`
    |                                                |
-   |                                                has type `&'?6 Cell<&'1 &'?1 u32>`
+   |                                                has type `&'?5 Cell<&'1 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs
index 5ae15f32357..2e0bdb151e1 100644
--- a/tests/ui/offset-of/offset-of-dst-field.rs
+++ b/tests/ui/offset-of/offset-of-dst-field.rs
@@ -16,7 +16,7 @@ struct Beta {
     z: dyn Trait,
 }
 
-extern {
+extern "C" {
     type Extern;
 }
 
diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.fixed b/tests/ui/parser/bad-fn-ptr-qualifier.fixed
index 558a27cd456..e2a2f9486b7 100644
--- a/tests/ui/parser/bad-fn-ptr-qualifier.fixed
+++ b/tests/ui/parser/bad-fn-ptr-qualifier.fixed
@@ -4,9 +4,9 @@
 
 pub type T0 =  fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type T1 =  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-pub type T2 =  unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 =  unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type T3 =  fn(); //~ ERROR an `fn` pointer type cannot be `async`
-pub type T4 =  extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 =  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type T5 =  unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type T6 =   unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `const`
@@ -14,9 +14,9 @@ pub type T6 =   unsafe extern "C" fn();
 
 pub type FTT0 = for<'a>  fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type FTT1 = for<'a>  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-pub type FTT2 = for<'a>  unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a>  unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type FTT3 = for<'a>  fn(); //~ ERROR an `fn` pointer type cannot be `async`
-pub type FTT4 = for<'a>  extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a>  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type FTT5 = for<'a>  unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `async`
 pub type FTT6 = for<'a>   unsafe extern "C" fn();
diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.rs b/tests/ui/parser/bad-fn-ptr-qualifier.rs
index 9750f480935..f2611c93b17 100644
--- a/tests/ui/parser/bad-fn-ptr-qualifier.rs
+++ b/tests/ui/parser/bad-fn-ptr-qualifier.rs
@@ -4,9 +4,9 @@
 
 pub type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-pub type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 = const unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
-pub type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 = async extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type T6 = const async unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `const`
@@ -14,9 +14,9 @@ pub type T6 = const async unsafe extern "C" fn();
 
 pub type FTT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type FTT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-pub type FTT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a> const unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 pub type FTT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
-pub type FTT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a> async extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 pub type FTT5 = for<'a> async unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `async`
 pub type FTT6 = for<'a> const async unsafe extern "C" fn();
diff --git a/tests/ui/parser/bad-fn-ptr-qualifier.stderr b/tests/ui/parser/bad-fn-ptr-qualifier.stderr
index 523ee47b0c9..ddc8bac678c 100644
--- a/tests/ui/parser/bad-fn-ptr-qualifier.stderr
+++ b/tests/ui/parser/bad-fn-ptr-qualifier.stderr
@@ -29,15 +29,15 @@ LL + pub type T1 =  extern "C" fn();
 error: an `fn` pointer type cannot be `const`
   --> $DIR/bad-fn-ptr-qualifier.rs:7:15
    |
-LL | pub type T2 = const unsafe extern fn();
-   |               -----^^^^^^^^^^^^^^^^^^^
+LL | pub type T2 = const unsafe extern "C" fn();
+   |               -----^^^^^^^^^^^^^^^^^^^^^^^
    |               |
    |               `const` because of this
    |
 help: remove the `const` qualifier
    |
-LL - pub type T2 = const unsafe extern fn();
-LL + pub type T2 =  unsafe extern fn();
+LL - pub type T2 = const unsafe extern "C" fn();
+LL + pub type T2 =  unsafe extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -57,15 +57,15 @@ LL + pub type T3 =  fn();
 error: an `fn` pointer type cannot be `async`
   --> $DIR/bad-fn-ptr-qualifier.rs:9:15
    |
-LL | pub type T4 = async extern fn();
-   |               -----^^^^^^^^^^^^
+LL | pub type T4 = async extern "C" fn();
+   |               -----^^^^^^^^^^^^^^^^
    |               |
    |               `async` because of this
    |
 help: remove the `async` qualifier
    |
-LL - pub type T4 = async extern fn();
-LL + pub type T4 =  extern fn();
+LL - pub type T4 = async extern "C" fn();
+LL + pub type T4 =  extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -141,15 +141,15 @@ LL + pub type FTT1 = for<'a>  extern "C" fn();
 error: an `fn` pointer type cannot be `const`
   --> $DIR/bad-fn-ptr-qualifier.rs:17:17
    |
-LL | pub type FTT2 = for<'a> const unsafe extern fn();
-   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+LL | pub type FTT2 = for<'a> const unsafe extern "C" fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
    |                         |
    |                         `const` because of this
    |
 help: remove the `const` qualifier
    |
-LL - pub type FTT2 = for<'a> const unsafe extern fn();
-LL + pub type FTT2 = for<'a>  unsafe extern fn();
+LL - pub type FTT2 = for<'a> const unsafe extern "C" fn();
+LL + pub type FTT2 = for<'a>  unsafe extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -169,15 +169,15 @@ LL + pub type FTT3 = for<'a>  fn();
 error: an `fn` pointer type cannot be `async`
   --> $DIR/bad-fn-ptr-qualifier.rs:19:17
    |
-LL | pub type FTT4 = for<'a> async extern fn();
-   |                 ^^^^^^^^-----^^^^^^^^^^^^
+LL | pub type FTT4 = for<'a> async extern "C" fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^
    |                         |
    |                         `async` because of this
    |
 help: remove the `async` qualifier
    |
-LL - pub type FTT4 = for<'a> async extern fn();
-LL + pub type FTT4 = for<'a>  extern fn();
+LL - pub type FTT4 = for<'a> async extern "C" fn();
+LL + pub type FTT4 = for<'a>  extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs
index c614f493885..f29dc53d322 100644
--- a/tests/ui/parser/bad-lit-suffixes.rs
+++ b/tests/ui/parser/bad-lit-suffixes.rs
@@ -1,10 +1,10 @@
 #![feature(rustc_attrs)]
 
-extern
+extern //~ WARN missing_abi
     "C"suffix //~ ERROR suffixes on string literals are invalid
     fn foo() {}
 
-extern
+extern //~ WARN missing_abi
     "C"suffix //~ ERROR suffixes on string literals are invalid
 {}
 
diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr
index b5dacdf7d0d..121db2058f1 100644
--- a/tests/ui/parser/bad-lit-suffixes.stderr
+++ b/tests/ui/parser/bad-lit-suffixes.stderr
@@ -49,6 +49,20 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
    |
    = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
 
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/bad-lit-suffixes.rs:3:1
+   |
+LL | extern
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   |
+   = note: `#[warn(missing_abi)]` on by default
+
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/bad-lit-suffixes.rs:7:1
+   |
+LL | extern
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+
 error: suffixes on string literals are invalid
   --> $DIR/bad-lit-suffixes.rs:12:5
    |
@@ -149,5 +163,5 @@ LL |     1.0e10suffix;
    |
    = help: valid suffixes are `f32` and `f64`
 
-error: aborting due to 21 previous errors
+error: aborting due to 21 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
index 34b687a0f52..5ecf804de09 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
@@ -1,4 +1,5 @@
 //@ edition:2018
+#![allow(missing_abi)]
 
 // There is an order to respect for keywords before a function:
 // `<visibility>, const, async, unsafe, extern, "<ABI>"`
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
index 0e9f7c51e1a..232da9acef3 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
@@ -1,5 +1,5 @@
 error: expected `fn`, found keyword `unsafe`
-  --> $DIR/wrong-unsafe.rs:9:8
+  --> $DIR/wrong-unsafe.rs:10:8
    |
 LL | extern unsafe fn test() {}
    | -------^^^^^^
diff --git a/tests/ui/parser/item-kw-case-mismatch.fixed b/tests/ui/parser/item-kw-case-mismatch.fixed
index f5afa482712..4ee8f9c19dc 100644
--- a/tests/ui/parser/item-kw-case-mismatch.fixed
+++ b/tests/ui/parser/item-kw-case-mismatch.fixed
@@ -25,7 +25,7 @@ const unsafe fn _e() {}
 //~| ERROR keyword `unsafe` is written in the wrong case
 //~| ERROR keyword `fn` is written in the wrong case
 
-unsafe extern fn _f() {}
+unsafe extern "C" fn _f() {}
 //~^ ERROR keyword `unsafe` is written in the wrong case
 //~| ERROR keyword `extern` is written in the wrong case
 
diff --git a/tests/ui/parser/item-kw-case-mismatch.rs b/tests/ui/parser/item-kw-case-mismatch.rs
index ea224e08a00..6c858b848cf 100644
--- a/tests/ui/parser/item-kw-case-mismatch.rs
+++ b/tests/ui/parser/item-kw-case-mismatch.rs
@@ -25,7 +25,7 @@ CONST UNSAFE FN _e() {}
 //~| ERROR keyword `unsafe` is written in the wrong case
 //~| ERROR keyword `fn` is written in the wrong case
 
-unSAFE EXTern fn _f() {}
+unSAFE EXTern "C" fn _f() {}
 //~^ ERROR keyword `unsafe` is written in the wrong case
 //~| ERROR keyword `extern` is written in the wrong case
 
diff --git a/tests/ui/parser/item-kw-case-mismatch.stderr b/tests/ui/parser/item-kw-case-mismatch.stderr
index 0abc59e064a..36df72b5cad 100644
--- a/tests/ui/parser/item-kw-case-mismatch.stderr
+++ b/tests/ui/parser/item-kw-case-mismatch.stderr
@@ -111,23 +111,23 @@ LL | CONST UNSAFE fn _e() {}
 error: keyword `unsafe` is written in the wrong case
   --> $DIR/item-kw-case-mismatch.rs:28:1
    |
-LL | unSAFE EXTern fn _f() {}
+LL | unSAFE EXTern "C" fn _f() {}
    | ^^^^^^
    |
 help: write it in the correct case
    |
-LL | unsafe EXTern fn _f() {}
+LL | unsafe EXTern "C" fn _f() {}
    | ~~~~~~
 
 error: keyword `extern` is written in the wrong case
   --> $DIR/item-kw-case-mismatch.rs:28:8
    |
-LL | unSAFE EXTern fn _f() {}
+LL | unSAFE EXTern "C" fn _f() {}
    |        ^^^^^^
    |
 help: write it in the correct case
    |
-LL | unSAFE extern fn _f() {}
+LL | unSAFE extern "C" fn _f() {}
    |        ~~~~~~
 
 error: keyword `extern` is written in the wrong case
diff --git a/tests/ui/parser/lit-err-in-macro.rs b/tests/ui/parser/lit-err-in-macro.rs
index cff8ee6b40c..ca117ac4a15 100644
--- a/tests/ui/parser/lit-err-in-macro.rs
+++ b/tests/ui/parser/lit-err-in-macro.rs
@@ -1,6 +1,6 @@
 macro_rules! f {
     ($abi:literal) => {
-        extern $abi fn f() {}
+        extern $abi fn f() {} //~ WARN missing_abi
     }
 }
 
diff --git a/tests/ui/parser/lit-err-in-macro.stderr b/tests/ui/parser/lit-err-in-macro.stderr
index 12e6d519060..fc2603d0b10 100644
--- a/tests/ui/parser/lit-err-in-macro.stderr
+++ b/tests/ui/parser/lit-err-in-macro.stderr
@@ -4,5 +4,17 @@ error: suffixes on string literals are invalid
 LL | f!("Foo"__);
    |    ^^^^^^^ invalid suffix `__`
 
-error: aborting due to 1 previous error
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/lit-err-in-macro.rs:3:9
+   |
+LL |         extern $abi fn f() {}
+   |         ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+...
+LL | f!("Foo"__);
+   | ----------- in this macro invocation
+   |
+   = note: `#[warn(missing_abi)]` on by default
+   = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.rs b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs
index 2d8a3858aa6..45d75349599 100644
--- a/tests/ui/parser/recover/recover-const-async-fn-ptr.rs
+++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.rs
@@ -2,9 +2,9 @@
 
 type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
 type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type T2 = const unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
-type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type T4 = async extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 type T6 = const async unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `const`
@@ -12,9 +12,9 @@ type T6 = const async unsafe extern "C" fn();
 
 type FT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
 type FT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
-type FT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+type FT2 = for<'a> const unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
 type FT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
-type FT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+type FT4 = for<'a> async extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 type FT5 = for<'a> async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
 type FT6 = for<'a> const async unsafe extern "C" fn();
 //~^ ERROR an `fn` pointer type cannot be `const`
diff --git a/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr
index 8e5b76163ad..9112a0e135a 100644
--- a/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr
+++ b/tests/ui/parser/recover/recover-const-async-fn-ptr.stderr
@@ -29,15 +29,15 @@ LL + type T1 =  extern "C" fn();
 error: an `fn` pointer type cannot be `const`
   --> $DIR/recover-const-async-fn-ptr.rs:5:11
    |
-LL | type T2 = const unsafe extern fn();
-   |           -----^^^^^^^^^^^^^^^^^^^
+LL | type T2 = const unsafe extern "C" fn();
+   |           -----^^^^^^^^^^^^^^^^^^^^^^^
    |           |
    |           `const` because of this
    |
 help: remove the `const` qualifier
    |
-LL - type T2 = const unsafe extern fn();
-LL + type T2 =  unsafe extern fn();
+LL - type T2 = const unsafe extern "C" fn();
+LL + type T2 =  unsafe extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -57,15 +57,15 @@ LL + type T3 =  fn();
 error: an `fn` pointer type cannot be `async`
   --> $DIR/recover-const-async-fn-ptr.rs:7:11
    |
-LL | type T4 = async extern fn();
-   |           -----^^^^^^^^^^^^
+LL | type T4 = async extern "C" fn();
+   |           -----^^^^^^^^^^^^^^^^
    |           |
    |           `async` because of this
    |
 help: remove the `async` qualifier
    |
-LL - type T4 = async extern fn();
-LL + type T4 =  extern fn();
+LL - type T4 = async extern "C" fn();
+LL + type T4 =  extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -141,15 +141,15 @@ LL + type FT1 = for<'a>  extern "C" fn();
 error: an `fn` pointer type cannot be `const`
   --> $DIR/recover-const-async-fn-ptr.rs:15:12
    |
-LL | type FT2 = for<'a> const unsafe extern fn();
-   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+LL | type FT2 = for<'a> const unsafe extern "C" fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
    |                    |
    |                    `const` because of this
    |
 help: remove the `const` qualifier
    |
-LL - type FT2 = for<'a> const unsafe extern fn();
-LL + type FT2 = for<'a>  unsafe extern fn();
+LL - type FT2 = for<'a> const unsafe extern "C" fn();
+LL + type FT2 = for<'a>  unsafe extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
@@ -169,15 +169,15 @@ LL + type FT3 = for<'a>  fn();
 error: an `fn` pointer type cannot be `async`
   --> $DIR/recover-const-async-fn-ptr.rs:17:12
    |
-LL | type FT4 = for<'a> async extern fn();
-   |            ^^^^^^^^-----^^^^^^^^^^^^
+LL | type FT4 = for<'a> async extern "C" fn();
+   |            ^^^^^^^^-----^^^^^^^^^^^^^^^^
    |                    |
    |                    `async` because of this
    |
 help: remove the `async` qualifier
    |
-LL - type FT4 = for<'a> async extern fn();
-LL + type FT4 = for<'a>  extern fn();
+LL - type FT4 = for<'a> async extern "C" fn();
+LL + type FT4 = for<'a>  extern "C" fn();
    |
 
 error: an `fn` pointer type cannot be `async`
diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs
index 76c56a715d2..ab2cfc961df 100644
--- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs
+++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs
@@ -19,7 +19,7 @@ fn main() {
     type Hmm = fn<>();
     //~^ ERROR function pointer types may not have generic parameters
 
-    let _: extern fn<'a: 'static>();
+    let _: extern "C" fn<'a: 'static>();
     //~^ ERROR function pointer types may not have generic parameters
     //~| ERROR bounds cannot be used in this context
 
diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr
index 6b6cb2d6bdd..9023856ef24 100644
--- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr
+++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr
@@ -59,15 +59,15 @@ LL |     type Hmm = fn<>();
    |                  ^^
 
 error: function pointer types may not have generic parameters
-  --> $DIR/recover-fn-ptr-with-generics.rs:22:21
+  --> $DIR/recover-fn-ptr-with-generics.rs:22:25
    |
-LL |     let _: extern fn<'a: 'static>();
-   |                     ^^^^^^^^^^^^^
+LL |     let _: extern "C" fn<'a: 'static>();
+   |                         ^^^^^^^^^^^^^
    |
 help: consider moving the lifetime parameter to a `for` parameter list
    |
-LL -     let _: extern fn<'a: 'static>();
-LL +     let _: for<'a> extern fn();
+LL -     let _: extern "C" fn<'a: 'static>();
+LL +     let _: for<'a> extern "C" fn();
    |
 
 error: function pointer types may not have generic parameters
@@ -101,10 +101,10 @@ LL |     type Identity = fn<T>(T) -> T;
    |                                 ^ not found in this scope
 
 error: bounds cannot be used in this context
-  --> $DIR/recover-fn-ptr-with-generics.rs:22:26
+  --> $DIR/recover-fn-ptr-with-generics.rs:22:30
    |
-LL |     let _: extern fn<'a: 'static>();
-   |                          ^^^^^^^
+LL |     let _: extern "C" fn<'a: 'static>();
+   |                              ^^^^^^^
 
 error: aborting due to 12 previous errors
 
diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.fixed b/tests/ui/parser/recover/recover-missing-semi-before-item.fixed
index 6f85452c6fb..871fa0d24ec 100644
--- a/tests/ui/parser/recover/recover-missing-semi-before-item.fixed
+++ b/tests/ui/parser/recover/recover-missing-semi-before-item.fixed
@@ -28,7 +28,7 @@ fn for_fn() {
 
 fn for_extern() {
     let foo = 3; //~ ERROR expected `;`, found keyword `extern`
-    extern fn foo() {}
+    extern "C" fn foo() {}
 }
 
 fn for_impl() {
diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.rs b/tests/ui/parser/recover/recover-missing-semi-before-item.rs
index f75945b55c2..de92603a74c 100644
--- a/tests/ui/parser/recover/recover-missing-semi-before-item.rs
+++ b/tests/ui/parser/recover/recover-missing-semi-before-item.rs
@@ -28,7 +28,7 @@ fn for_fn() {
 
 fn for_extern() {
     let foo = 3 //~ ERROR expected `;`, found keyword `extern`
-    extern fn foo() {}
+    extern "C" fn foo() {}
 }
 
 fn for_impl() {
diff --git a/tests/ui/parser/recover/recover-missing-semi-before-item.stderr b/tests/ui/parser/recover/recover-missing-semi-before-item.stderr
index 61c43f2f189..3b55cd9ddd0 100644
--- a/tests/ui/parser/recover/recover-missing-semi-before-item.stderr
+++ b/tests/ui/parser/recover/recover-missing-semi-before-item.stderr
@@ -35,7 +35,7 @@ error: expected `;`, found keyword `extern`
    |
 LL |     let foo = 3
    |                ^ help: add `;` here
-LL |     extern fn foo() {}
+LL |     extern "C" fn foo() {}
    |     ------ unexpected token
 
 error: expected `;`, found keyword `impl`
diff --git a/tests/ui/privacy/sysroot-private.default.stderr b/tests/ui/privacy/sysroot-private.default.stderr
new file mode 100644
index 00000000000..845d4558d13
--- /dev/null
+++ b/tests/ui/privacy/sysroot-private.default.stderr
@@ -0,0 +1,39 @@
+error[E0405]: cannot find trait `Equivalent` in this scope
+  --> $DIR/sysroot-private.rs:26:18
+   |
+LL | trait Trait2<K>: Equivalent<K> {}
+   |                  ^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `K` in this scope
+  --> $DIR/sysroot-private.rs:31:35
+   |
+LL | fn trait_member<T>(val: &T, key: &K) -> bool {
+   |                 -                 ^
+   |                 |
+   |                 similarly named type parameter `T` defined here
+   |
+help: a type parameter with a similar name exists
+   |
+LL | fn trait_member<T>(val: &T, key: &T) -> bool {
+   |                                   ~
+help: you might be missing a type parameter
+   |
+LL | fn trait_member<T, K>(val: &T, key: &K) -> bool {
+   |                  +++
+
+error[E0220]: associated type `ExpressionStack` not found for `Trait`
+  --> $DIR/sysroot-private.rs:21:31
+   |
+LL | type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
+   |                               ^^^^^^^^^^^^^^^ help: `Trait` has the following associated type: `Bar`
+
+error[E0425]: cannot find function `memchr2` in this scope
+  --> $DIR/sysroot-private.rs:39:5
+   |
+LL |     memchr2(b'a', b'b', buf)
+   |     ^^^^^^^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0220, E0405, E0412, E0425.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/privacy/sysroot-private.rs b/tests/ui/privacy/sysroot-private.rs
new file mode 100644
index 00000000000..67ab67c7f5c
--- /dev/null
+++ b/tests/ui/privacy/sysroot-private.rs
@@ -0,0 +1,42 @@
+//! Test that private dependencies of `std` that live in the sysroot do not reach through to
+//! diagnostics.
+//!
+//! This test would be more robust if we could patch the sysroot with an "evil" crate that
+//! provided known types that we control; however, this would effectively require rebuilding
+//! `std` (or patching crate metadata). So, this test relies on what is currently public API
+//! of `std`'s dependencies, but may not be robust against dependency upgrades/changes.
+
+//@ only-unix Windows sysroots seem to not expose this dependency
+//@ revisions: default rustc_private_enabled
+
+// Enabling `rustc_private` should `std`'s dependencies accessible, so they should show up
+// in diagnostics. NB: not all diagnostics are affected by this.
+#![cfg_attr(rustc_private_enabled, feature(rustc_private))]
+#![crate_type = "lib"]
+
+trait Trait { type Bar; }
+
+// Attempt to get a suggestion for `gimli::read::op::EvaluationStoreage`, which should not be
+// present in diagnostics (it is a dependency of the compiler).
+type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
+//~^ ERROR associated type `ExpressionStack` not found
+//[rustc_private_enabled]~| NOTE there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage`
+
+// Attempt to get a suggestion for `hashbrown::Equivalent`
+trait Trait2<K>: Equivalent<K> {}
+//~^ ERROR cannot find trait
+//~| NOTE not found
+
+// Attempt to get a suggestion for `hashbrown::Equivalent::equivalent`
+fn trait_member<T>(val: &T, key: &K) -> bool {
+    //~^ ERROR cannot find type `K`
+    //~| NOTE similarly named
+    val.equivalent(key)
+}
+
+// Attempt to get a suggestion for `memchr::memchr2`
+fn free_function(buf: &[u8]) -> Option<usize> {
+    memchr2(b'a', b'b', buf)
+    //~^ ERROR cannot find function
+    //~| NOTE not found
+}
diff --git a/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr b/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr
new file mode 100644
index 00000000000..98e6922428a
--- /dev/null
+++ b/tests/ui/privacy/sysroot-private.rustc_private_enabled.stderr
@@ -0,0 +1,39 @@
+error[E0405]: cannot find trait `Equivalent` in this scope
+  --> $DIR/sysroot-private.rs:26:18
+   |
+LL | trait Trait2<K>: Equivalent<K> {}
+   |                  ^^^^^^^^^^ not found in this scope
+
+error[E0412]: cannot find type `K` in this scope
+  --> $DIR/sysroot-private.rs:31:35
+   |
+LL | fn trait_member<T>(val: &T, key: &K) -> bool {
+   |                 -                 ^
+   |                 |
+   |                 similarly named type parameter `T` defined here
+   |
+help: a type parameter with a similar name exists
+   |
+LL | fn trait_member<T>(val: &T, key: &T) -> bool {
+   |                                   ~
+help: you might be missing a type parameter
+   |
+LL | fn trait_member<T, K>(val: &T, key: &K) -> bool {
+   |                  +++
+
+error[E0220]: associated type `ExpressionStack` not found for `Trait`
+  --> $DIR/sysroot-private.rs:21:31
+   |
+LL | type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
+   |                               ^^^^^^^^^^^^^^^ there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage`
+
+error[E0425]: cannot find function `memchr2` in this scope
+  --> $DIR/sysroot-private.rs:39:5
+   |
+LL |     memchr2(b'a', b'b', buf)
+   |     ^^^^^^^ not found in this scope
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0220, E0405, E0412, E0425.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/proc-macro/inner-attrs.stderr b/tests/ui/proc-macro/inner-attrs.stderr
index ee8732c650d..3ab180be821 100644
--- a/tests/ui/proc-macro/inner-attrs.stderr
+++ b/tests/ui/proc-macro/inner-attrs.stderr
@@ -22,5 +22,13 @@ error: expected non-macro inner attribute, found attribute macro `print_attr`
 LL |         #![print_attr]
    |            ^^^^^^^^^^ not a non-macro inner attribute
 
-error: aborting due to 4 previous errors
+warning: extern declarations without an explicit ABI are deprecated
+  --> $DIR/inner-attrs.rs:82:1
+   |
+LL | extern {
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
+   |
+   = note: `#[warn(missing_abi)]` on by default
+
+error: aborting due to 4 previous errors; 1 warning emitted
 
diff --git a/tests/ui/proc-macro/issue-66286.rs b/tests/ui/proc-macro/issue-66286.rs
index 57d1af26e93..882f87fa4ac 100644
--- a/tests/ui/proc-macro/issue-66286.rs
+++ b/tests/ui/proc-macro/issue-66286.rs
@@ -5,7 +5,7 @@
 extern crate issue_66286;
 
 #[issue_66286::vec_ice]
-pub extern fn foo(_: Vec(u32)) -> u32 {
+pub extern "C" fn foo(_: Vec(u32)) -> u32 {
     //~^ ERROR: parenthesized type parameters may only be used with a `Fn` trait
     0
 }
diff --git a/tests/ui/proc-macro/issue-66286.stderr b/tests/ui/proc-macro/issue-66286.stderr
index fc4c2062fd7..c92bed1b563 100644
--- a/tests/ui/proc-macro/issue-66286.stderr
+++ b/tests/ui/proc-macro/issue-66286.stderr
@@ -1,13 +1,13 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-66286.rs:8:22
+  --> $DIR/issue-66286.rs:8:26
    |
-LL | pub extern fn foo(_: Vec(u32)) -> u32 {
-   |                      ^^^^^^^^ only `Fn` traits may use parentheses
+LL | pub extern "C" fn foo(_: Vec(u32)) -> u32 {
+   |                          ^^^^^^^^ only `Fn` traits may use parentheses
    |
 help: use angle brackets instead
    |
-LL | pub extern fn foo(_: Vec<u32>) -> u32 {
-   |                         ~   ~
+LL | pub extern "C" fn foo(_: Vec<u32>) -> u32 {
+   |                             ~   ~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
index cc941be5479..a2bda229d10 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
@@ -10,13 +10,8 @@ LL |     let foo: fn() = foo;
    |              expected due to this
    |
    = note: expected fn pointer `fn()`
-                 found fn item `fn() {foo}`
-   = note: fn items are distinct from fn pointers
+                 found fn item `#[target_features] fn() {foo}`
    = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
-help: consider casting to a fn pointer
-   |
-LL |     let foo: fn() = foo as fn();
-   |                     ~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
index 3c370a1b8f3..3eae79faf42 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
@@ -21,9 +21,9 @@ fn call_once(f: impl FnOnce()) {
 }
 
 fn main() {
-    call(foo); //~ ERROR expected a `Fn()` closure, found `fn() {foo}`
-    call_mut(foo); //~ ERROR expected a `FnMut()` closure, found `fn() {foo}`
-    call_once(foo); //~ ERROR expected a `FnOnce()` closure, found `fn() {foo}`
+    call(foo); //~ ERROR expected a `Fn()` closure, found `#[target_features] fn() {foo}`
+    call_mut(foo); //~ ERROR expected a `FnMut()` closure, found `#[target_features] fn() {foo}`
+    call_once(foo); //~ ERROR expected a `FnOnce()` closure, found `#[target_features] fn() {foo}`
 
     call(foo_unsafe);
     //~^ ERROR expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}`
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
index 4c07f4d6b99..2915b9ad1b3 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
@@ -1,13 +1,13 @@
-error[E0277]: expected a `Fn()` closure, found `fn() {foo}`
+error[E0277]: expected a `Fn()` closure, found `#[target_features] fn() {foo}`
   --> $DIR/fn-traits.rs:24:10
    |
 LL |     call(foo);
-   |     ---- ^^^ expected an `Fn()` closure, found `fn() {foo}`
+   |     ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `Fn()` is not implemented for fn item `fn() {foo}`
-   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = help: the trait `Fn()` is not implemented for fn item `#[target_features] fn() {foo}`
+   = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
    = note: `#[target_feature]` functions do not implement the `Fn` traits
 note: required by a bound in `call`
   --> $DIR/fn-traits.rs:11:17
@@ -15,16 +15,16 @@ note: required by a bound in `call`
 LL | fn call(f: impl Fn()) {
    |                 ^^^^ required by this bound in `call`
 
-error[E0277]: expected a `FnMut()` closure, found `fn() {foo}`
+error[E0277]: expected a `FnMut()` closure, found `#[target_features] fn() {foo}`
   --> $DIR/fn-traits.rs:25:14
    |
 LL |     call_mut(foo);
-   |     -------- ^^^ expected an `FnMut()` closure, found `fn() {foo}`
+   |     -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `FnMut()` is not implemented for fn item `fn() {foo}`
-   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = help: the trait `FnMut()` is not implemented for fn item `#[target_features] fn() {foo}`
+   = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
    = note: `#[target_feature]` functions do not implement the `Fn` traits
 note: required by a bound in `call_mut`
   --> $DIR/fn-traits.rs:15:25
@@ -32,16 +32,16 @@ note: required by a bound in `call_mut`
 LL | fn call_mut(mut f: impl FnMut()) {
    |                         ^^^^^^^ required by this bound in `call_mut`
 
-error[E0277]: expected a `FnOnce()` closure, found `fn() {foo}`
+error[E0277]: expected a `FnOnce()` closure, found `#[target_features] fn() {foo}`
   --> $DIR/fn-traits.rs:26:15
    |
 LL |     call_once(foo);
-   |     --------- ^^^ expected an `FnOnce()` closure, found `fn() {foo}`
+   |     --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `FnOnce()` is not implemented for fn item `fn() {foo}`
-   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = help: the trait `FnOnce()` is not implemented for fn item `#[target_features] fn() {foo}`
+   = note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
    = note: `#[target_feature]` functions do not implement the `Fn` traits
 note: required by a bound in `call_once`
   --> $DIR/fn-traits.rs:19:22
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs
index df575b0f6b6..a2ac6ff45fc 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs
@@ -13,6 +13,7 @@ impl Foo for Bar {
     #[target_feature(enable = "sse2")]
     //~^ ERROR cannot be applied to safe trait method
     fn foo(&self) {}
+    //~^ ERROR method `foo` has an incompatible type for trait
 
     #[target_feature(enable = "sse2")]
     unsafe fn unsf_foo(&self) {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
index 00efbb52f15..1ab1fad64cc 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
@@ -7,8 +7,22 @@ LL |
 LL |     fn foo(&self) {}
    |     ------------- not an `unsafe` function
 
+error[E0053]: method `foo` has an incompatible type for trait
+  --> $DIR/trait-impl.rs:15:5
+   |
+LL |     fn foo(&self) {}
+   |     ^^^^^^^^^^^^^ expected safe fn, found unsafe fn
+   |
+note: type in trait
+  --> $DIR/trait-impl.rs:6:5
+   |
+LL |     fn foo(&self);
+   |     ^^^^^^^^^^^^^^
+   = note: expected signature `fn(&Bar)`
+              found signature `#[target_features] fn(&Bar)`
+
 error: `#[target_feature(..)]` cannot be applied to safe trait method
-  --> $DIR/trait-impl.rs:22:5
+  --> $DIR/trait-impl.rs:23:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
@@ -16,5 +30,6 @@ LL |
 LL |     fn foo(&self) {}
    |     ------------- not an `unsafe` function
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
index f33a3d62e26..5982c771033 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
@@ -11,7 +11,7 @@ fn test() {}
 static mut imported_val: i32 = 123;
 
 #[link(name = "exporter", kind = "raw-dylib")]
-extern {
+extern "C" {
     #[link_ordinal(13)]
     fn imported_function();
 
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
index 586881d1807..8b179f7ef93 100644
--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
@@ -4,7 +4,7 @@
 macro_rules! tt {
     ($e:tt) => {
         #$e
-        extern fn foo() {}
+        extern "C" fn foo() {}
     }
 }
 
@@ -13,7 +13,7 @@ macro_rules! ident {
         #[unsafe($e)]
         //~^ ERROR: unsafe attribute used without unsafe
         //~| WARN this is accepted in the current edition
-        extern fn bar() {}
+        extern "C" fn bar() {}
     }
 }
 
@@ -22,21 +22,21 @@ macro_rules! ident2 {
         #[unsafe($e = $l)]
         //~^ ERROR: unsafe attribute used without unsafe
         //~| WARN this is accepted in the current edition
-        extern fn bars() {}
+        extern "C" fn bars() {}
     }
 }
 
 macro_rules! meta {
     ($m:meta) => {
         #[$m]
-        extern fn baz() {}
+        extern "C" fn baz() {}
     }
 }
 
 macro_rules! meta2 {
     ($m:meta) => {
         #[$m]
-        extern fn baw() {}
+        extern "C" fn baw() {}
     }
 }
 
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
index 03e122c7d57..34e5a6b96e3 100644
--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
@@ -4,7 +4,7 @@
 macro_rules! tt {
     ($e:tt) => {
         #$e
-        extern fn foo() {}
+        extern "C" fn foo() {}
     }
 }
 
@@ -13,7 +13,7 @@ macro_rules! ident {
         #[$e]
         //~^ ERROR: unsafe attribute used without unsafe
         //~| WARN this is accepted in the current edition
-        extern fn bar() {}
+        extern "C" fn bar() {}
     }
 }
 
@@ -22,21 +22,21 @@ macro_rules! ident2 {
         #[$e = $l]
         //~^ ERROR: unsafe attribute used without unsafe
         //~| WARN this is accepted in the current edition
-        extern fn bars() {}
+        extern "C" fn bars() {}
     }
 }
 
 macro_rules! meta {
     ($m:meta) => {
         #[$m]
-        extern fn baz() {}
+        extern "C" fn baz() {}
     }
 }
 
 macro_rules! meta2 {
     ($m:meta) => {
         #[$m]
-        extern fn baw() {}
+        extern "C" fn baw() {}
     }
 }
 
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
index 2d6df816bb1..46e4afd8532 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
@@ -11,7 +11,7 @@ impl Foo {
         //~^ ERROR invalid generic `self` parameter type
         //~| ERROR destructor of `R` cannot be evaluated at compile-time
         self.0
-        //~^ ERROR cannot perform conditionally-const deref coercion on `R` in constant functions
+        //~^ ERROR cannot perform non-const deref coercion on `R` in constant functions
     }
 }
 
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
index e6319d5a2c9..f217370b024 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
@@ -1,4 +1,4 @@
-error[E0658]: cannot perform conditionally-const deref coercion on `R` in constant functions
+error[E0015]: cannot perform non-const deref coercion on `R` in constant functions
   --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
    |
 LL |         self.0
@@ -6,9 +6,6 @@ LL |         self.0
    |
    = note: attempting to deref into `Foo`
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
-   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0493]: destructor of `R` cannot be evaluated at compile-time
   --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
@@ -30,5 +27,5 @@ LL |     const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0493, E0658, E0801.
-For more information about an error, try `rustc --explain E0493`.
+Some errors have detailed explanations: E0015, E0493, E0801.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
new file mode 100644
index 00000000000..71f198f7dc7
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.rs
@@ -0,0 +1,25 @@
+// We used to allow erroneous `DispatchFromDyn` impls whose RHS type contained
+// fields that weren't ZSTs. I don't believe this was possible to abuse, but
+// it's at least nice to give users better errors.
+
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+
+struct Dispatchable<T: ?Sized, Z> {
+    _ptr: Box<T>,
+    z: Z,
+}
+
+impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
new file mode 100644
index 00000000000..1f13c51f679
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute-zst-nonzst.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute-zst-nonzst.rs:17:1
+   |
+LL | / impl<T, U> DispatchFromDyn<Dispatchable<U, i32>> for Dispatchable<T, ()>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized,
+   | |______________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `_ptr` (`Box<T>` to `Box<U>`), `z` (`()` to `i32`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.rs b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
new file mode 100644
index 00000000000..57c255b4d7b
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.rs
@@ -0,0 +1,34 @@
+#![feature(arbitrary_self_types)]
+#![feature(unsize)]
+#![feature(dispatch_from_dyn)]
+
+use std::marker::PhantomData;
+use std::marker::Unsize;
+use std::ops::DispatchFromDyn;
+use std::ops::Deref;
+
+struct IsSendToken<T: ?Sized>(PhantomData<fn(T) -> T>);
+
+struct Foo<'a, U: ?Sized> {
+    token: IsSendToken<U>,
+    ptr: &'a U,
+}
+
+impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+//~^ ERROR implementing the `DispatchFromDyn` trait requires multiple coercions
+where
+    T: Unsize<U> + ?Sized,
+    U: ?Sized {}
+
+trait Bar {
+    fn f(self: Foo<'_, Self>);
+}
+
+impl<U: ?Sized> Deref for Foo<'_, U> {
+    type Target = U;
+    fn deref(&self) -> &U {
+        self.ptr
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
new file mode 100644
index 00000000000..5a8ae88b5f1
--- /dev/null
+++ b/tests/ui/self/dispatch-from-dyn-zst-transmute.stderr
@@ -0,0 +1,16 @@
+error[E0378]: implementing the `DispatchFromDyn` trait requires multiple coercions
+  --> $DIR/dispatch-from-dyn-zst-transmute.rs:17:1
+   |
+LL | / impl<'a, T, U> DispatchFromDyn<Foo<'a, U>> for Foo<'a, T>
+LL | |
+LL | | where
+LL | |     T: Unsize<U> + ?Sized,
+LL | |     U: ?Sized {}
+   | |_____________^
+   |
+   = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+   = note: currently, 2 fields need coercions: `token` (`IsSendToken<T>` to `IsSendToken<U>`), `ptr` (`&'a T` to `&'a U`)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0378`.
diff --git a/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
new file mode 100644
index 00000000000..9c7e33830f5
--- /dev/null
+++ b/tests/ui/self/phantomdata-in-coerce-and-dispatch-impls.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+
+#![feature(coerce_unsized, dispatch_from_dyn, unsize)]
+
+use std::marker::Unsize;
+use std::ops::{CoerceUnsized, DispatchFromDyn};
+use std::marker::PhantomData;
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+struct W<T: 'static> {
+    t: &'static T,
+    f: <PhantomData<T> as Mirror>::Assoc,
+}
+
+impl<T, U> CoerceUnsized<W<U>> for W<T> where T: Unsize<U> {}
+
+impl<T, U> DispatchFromDyn<W<U>> for W<T> where T: Unsize<U> {}
+
+fn main() {}
diff --git a/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs b/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
index a969295c9f9..65c57c42530 100644
--- a/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
@@ -6,7 +6,7 @@
 
 use std::ptr::NonNull;
 
-extern {
+extern "C" {
     type Extern;
 }
 
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 19820730736..c3e72e83948 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -22,6 +22,7 @@ impl Foo {
 #[stable(feature = "stable", since = "1.0.0")]
 #[const_trait]
 pub trait Bar {
+//~^ ERROR trait has missing const stability attribute
     #[stable(feature = "stable", since = "1.0.0")]
     fn fun();
 }
diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr
index baa4c34af06..09461e6fb54 100644
--- a/tests/ui/stability-attribute/missing-const-stability.stderr
+++ b/tests/ui/stability-attribute/missing-const-stability.stderr
@@ -4,8 +4,18 @@ error: function has missing const stability attribute
 LL | pub const fn foo() {}
    | ^^^^^^^^^^^^^^^^^^^^^
 
+error: trait has missing const stability attribute
+  --> $DIR/missing-const-stability.rs:24:1
+   |
+LL | / pub trait Bar {
+LL | |
+LL | |     #[stable(feature = "stable", since = "1.0.0")]
+LL | |     fn fun();
+LL | | }
+   | |_^
+
 error: function has missing const stability attribute
-  --> $DIR/missing-const-stability.rs:36:1
+  --> $DIR/missing-const-stability.rs:37:1
    |
 LL | pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,5 +26,5 @@ error: associated function has missing const stability attribute
 LL |     pub const fn foo() {}
    |     ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/statics/uninhabited-static.rs b/tests/ui/statics/uninhabited-static.rs
index a0f83f45079..0f7c5ae6ef4 100644
--- a/tests/ui/statics/uninhabited-static.rs
+++ b/tests/ui/statics/uninhabited-static.rs
@@ -2,7 +2,7 @@
 #![deny(uninhabited_static)]
 
 enum Void {}
-extern {
+extern "C" {
     static VOID: Void; //~ ERROR static of uninhabited type
     //~| WARN: previously accepted
     static NEVER: !; //~ ERROR static of uninhabited type
diff --git a/tests/ui/target-feature/invalid-attribute.rs b/tests/ui/target-feature/invalid-attribute.rs
index 2f951c4a00a..c0f5b6b2fb2 100644
--- a/tests/ui/target-feature/invalid-attribute.rs
+++ b/tests/ui/target-feature/invalid-attribute.rs
@@ -97,6 +97,7 @@ impl Foo {}
 
 trait Quux {
     fn foo(); //~ NOTE `foo` from trait
+    //~^ NOTE: type in trait
 }
 
 impl Quux for Foo {
@@ -106,6 +107,9 @@ impl Quux for Foo {
     //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
     fn foo() {}
     //~^ NOTE not an `unsafe` function
+    //~| ERROR: incompatible type for trait
+    //~| NOTE: expected safe fn, found unsafe fn
+    //~| NOTE: expected signature `fn()`
 }
 
 fn main() {
diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr
index bf48911edec..10fcf65bb9a 100644
--- a/tests/ui/target-feature/invalid-attribute.stderr
+++ b/tests/ui/target-feature/invalid-attribute.stderr
@@ -126,7 +126,7 @@ LL | impl Foo {}
    | ----------- not a function definition
 
 error: attribute should be applied to a function definition
-  --> $DIR/invalid-attribute.rs:112:5
+  --> $DIR/invalid-attribute.rs:116:5
    |
 LL |       #[target_feature(enable = "sse2")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +138,7 @@ LL | |     }
    | |_____- not a function definition
 
 error: attribute should be applied to a function definition
-  --> $DIR/invalid-attribute.rs:120:5
+  --> $DIR/invalid-attribute.rs:124:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -193,7 +193,7 @@ LL |     fn foo();
    |     --------- `foo` from trait
 
 error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
-  --> $DIR/invalid-attribute.rs:103:5
+  --> $DIR/invalid-attribute.rs:104:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -205,7 +205,21 @@ LL |     fn foo() {}
    = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 23 previous errors
+error[E0053]: method `foo` has an incompatible type for trait
+  --> $DIR/invalid-attribute.rs:108:5
+   |
+LL |     fn foo() {}
+   |     ^^^^^^^^ expected safe fn, found unsafe fn
+   |
+note: type in trait
+  --> $DIR/invalid-attribute.rs:99:5
+   |
+LL |     fn foo();
+   |     ^^^^^^^^^
+   = note: expected signature `fn()`
+              found signature `#[target_features] fn()`
+
+error: aborting due to 24 previous errors
 
-Some errors have detailed explanations: E0046, E0658.
+Some errors have detailed explanations: E0046, E0053, E0658.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/traits/const-traits/auxiliary/staged-api.rs b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
index abe22db702c..933a25769dc 100644
--- a/tests/ui/traits/const-traits/auxiliary/staged-api.rs
+++ b/tests/ui/traits/const-traits/auxiliary/staged-api.rs
@@ -4,6 +4,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "unstable", issue = "none")]
 #[const_trait]
 pub trait MyTrait {
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
index b854b422b3a..3004647ede0 100644
--- a/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #110395
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_ops)]
 
 struct Int(i32);
 
diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.rs b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
index 6b96fcf0ae3..85e2c5d3df6 100644
--- a/tests/ui/traits/const-traits/const-and-non-const-impl.rs
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #110395
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_ops)]
 
 pub struct Int(i32);
 
diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
index 2358731c901..fb47bf9169f 100644
--- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
@@ -1,13 +1,10 @@
-error[E0658]: cannot call conditionally-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+error[E0015]: cannot call non-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
   --> $DIR/cross-crate.rs:19:14
    |
 LL |     NonConst.func();
    |              ^^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-   = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
-   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
   --> $DIR/cross-crate.rs:22:11
@@ -22,4 +19,5 @@ LL |     Const.func();
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs
index 5eb236acde2..99de21471b2 100644
--- a/tests/ui/traits/const-traits/generic-bound.rs
+++ b/tests/ui/traits/const-traits/generic-bound.rs
@@ -1,6 +1,6 @@
 //@ check-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_ops)]
 
 use std::marker::PhantomData;
 
diff --git a/tests/ui/traits/const-traits/syntactical-unstable.rs b/tests/ui/traits/const-traits/syntactical-unstable.rs
new file mode 100644
index 00000000000..e192e80fabd
--- /dev/null
+++ b/tests/ui/traits/const-traits/syntactical-unstable.rs
@@ -0,0 +1,34 @@
+//@ aux-build:staged-api.rs
+
+// Ensure that we enforce const stability of traits in `~const`/`const` bounds.
+
+#![feature(const_trait_impl)]
+
+use std::ops::Deref;
+
+extern crate staged_api;
+use staged_api::MyTrait;
+
+#[const_trait]
+trait Foo: ~const MyTrait {
+    //~^ ERROR use of unstable const library feature `unstable`
+    type Item: ~const MyTrait;
+    //~^ ERROR use of unstable const library feature `unstable`
+}
+
+const fn where_clause<T>() where T: ~const MyTrait {}
+//~^ ERROR use of unstable const library feature `unstable`
+
+const fn nested<T>() where T: Deref<Target: ~const MyTrait> {}
+//~^ ERROR use of unstable const library feature `unstable`
+
+const fn rpit() -> impl ~const MyTrait { Local }
+//~^ ERROR use of unstable const library feature `unstable`
+
+struct Local;
+impl const MyTrait for Local {
+//~^ ERROR use of unstable const library feature `unstable`
+    fn func() {}
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/syntactical-unstable.stderr b/tests/ui/traits/const-traits/syntactical-unstable.stderr
new file mode 100644
index 00000000000..a2ce2f2b6e9
--- /dev/null
+++ b/tests/ui/traits/const-traits/syntactical-unstable.stderr
@@ -0,0 +1,67 @@
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:13:19
+   |
+LL | trait Foo: ~const MyTrait {
+   |            ------ ^^^^^^^
+   |            |
+   |            trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:19:44
+   |
+LL | const fn where_clause<T>() where T: ~const MyTrait {}
+   |                                     ------ ^^^^^^^
+   |                                     |
+   |                                     trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:22:52
+   |
+LL | const fn nested<T>() where T: Deref<Target: ~const MyTrait> {}
+   |                                             ------ ^^^^^^^
+   |                                             |
+   |                                             trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:25:32
+   |
+LL | const fn rpit() -> impl ~const MyTrait { Local }
+   |                         ------ ^^^^^^^
+   |                         |
+   |                         trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:29:12
+   |
+LL | impl const MyTrait for Local {
+   |            ^^^^^^^ trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable const library feature `unstable`
+  --> $DIR/syntactical-unstable.rs:15:23
+   |
+LL |     type Item: ~const MyTrait;
+   |                ------ ^^^^^^^
+   |                |
+   |                trait is not stable as const yet
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.rs b/tests/ui/traits/const-traits/trait-default-body-stability.rs
index 5f7486eb176..567f1b3c284 100644
--- a/tests/ui/traits/const-traits/trait-default-body-stability.rs
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.rs
@@ -38,6 +38,7 @@ impl const FromResidual for T {
 }
 
 #[stable(feature = "foo", since = "1.0")]
+#[rustc_const_unstable(feature = "const_tr", issue = "none")]
 #[const_trait]
 pub trait Tr {
     #[stable(feature = "foo", since = "1.0")]
diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.stderr b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
index 77b81211e81..a13d9a1e075 100644
--- a/tests/ui/traits/const-traits/trait-default-body-stability.stderr
+++ b/tests/ui/traits/const-traits/trait-default-body-stability.stderr
@@ -17,7 +17,7 @@ LL | impl const FromResidual for T {
    = note: adding a non-const method body in the future would be a breaking change
 
 error[E0015]: `?` is not allowed on `T` in constant functions
-  --> $DIR/trait-default-body-stability.rs:45:9
+  --> $DIR/trait-default-body-stability.rs:46:9
    |
 LL |         T?
    |         ^^
@@ -25,7 +25,7 @@ LL |         T?
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error[E0015]: `?` is not allowed on `T` in constant functions
-  --> $DIR/trait-default-body-stability.rs:45:9
+  --> $DIR/trait-default-body-stability.rs:46:9
    |
 LL |         T?
    |         ^^
diff --git a/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs b/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs
new file mode 100644
index 00000000000..55fea005ea1
--- /dev/null
+++ b/tests/ui/traits/next-solver/known-type-outlives-has-constraints.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+trait Norm {
+    type Out;
+}
+impl<'a, T: 'a> Norm for &'a T {
+    type Out = T;
+}
+
+fn hello<'a, T: 'a>() where <&'a T as Norm>::Out: 'a {}
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
new file mode 100644
index 00000000000..c03b5145aa7
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
@@ -0,0 +1,39 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+// Regression test for #135462.
+#![allow(coherence_leak_check)]
+
+type A = fn(&'static ());
+type B = fn(&());
+
+trait Bound<P: WithAssoc>: From<GetAssoc<P>> {
+}
+impl Bound<B> for String {}
+
+trait Trt<T> {
+    fn __(&self, x: T) where T: Bound<A> {
+        T::from(());
+    }
+}
+
+impl<T, S> Trt<T> for S {}
+
+type GetAssoc<T> = <T as WithAssoc>::Ty;
+
+trait WithAssoc {
+    type Ty;
+}
+
+impl WithAssoc for B {
+    type Ty = String;
+}
+
+impl WithAssoc for A {
+    type Ty = ();
+}
+
+fn main() {
+    let x: &'static dyn Trt<String> = &();
+}
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
new file mode 100644
index 00000000000..63ad1c0a060
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
@@ -0,0 +1,40 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait Foo {}
+impl Foo for fn(&'static ()) {}
+
+trait Bar {
+    type Assoc: Default;
+}
+impl<T: Foo> Bar for T {
+    type Assoc = usize;
+}
+impl Bar for fn(&()) {
+    type Assoc = ();
+}
+
+fn needs_foo<T: Foo>() -> usize {
+    needs_bar::<T>()
+}
+
+fn needs_bar<T: Bar>() -> <T as Bar>::Assoc {
+    Default::default()
+}
+
+trait Evil<T> {
+    fn bad(&self)
+    where
+        T: Foo,
+    {
+        needs_foo::<T>();
+    }
+}
+
+impl Evil<fn(&())> for () {}
+
+fn main() {
+    let x: &dyn Evil<fn(&())> = &();
+}
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 26c253d049b..31af323ecda 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -452,15 +452,15 @@ mod items {
     /// ItemKind::Fn
     mod item_fn {
         pub const unsafe extern "C" fn f() {}
-        pub async unsafe extern fn g() {}
+        pub async unsafe extern "C" fn g() {}
         fn h<'a, T>() where T: 'a {}
 
         trait TraitItems {
-            unsafe extern fn f();
+            unsafe extern "C" fn f();
         }
 
         impl TraitItems for _ {
-            default unsafe extern fn f() {}
+            default unsafe extern "C" fn f() {}
         }
     }
 
@@ -472,7 +472,7 @@ mod items {
     /// ItemKind::ForeignMod
     mod item_foreign_mod {
         unsafe extern "C++" {}
-        unsafe extern {}
+        unsafe extern "C" {}
     }
 
     /// ItemKind::GlobalAsm
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index bd7aa1117cc..11066c90edb 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -433,13 +433,13 @@ mod items {
     /// ItemKind::Fn
     mod item_fn {
         pub const unsafe extern "C" fn f() {}
-        pub async unsafe extern fn g() {}
+        pub async unsafe extern "C" fn g() {}
         fn h<'a, T>() where T: 'a {}
         trait TraitItems {
-            unsafe extern fn f();
+            unsafe extern "C" fn f();
         }
         impl TraitItems for _ {
-            default unsafe extern fn f() {}
+            default unsafe extern "C" fn f() {}
         }
     }
     /// ItemKind::Mod
@@ -447,7 +447,7 @@ mod items {
     /// ItemKind::ForeignMod
     mod item_foreign_mod {
         unsafe extern "C++" {}
-        unsafe extern {}
+        unsafe extern "C" {}
     }
     /// ItemKind::GlobalAsm
     mod item_global_asm {