about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock235
-rw-r--r--Cargo.toml10
-rw-r--r--compiler/rustc_abi/Cargo.toml4
-rw-r--r--compiler/rustc_ast/Cargo.toml8
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml4
-rw-r--r--compiler/rustc_ast_passes/Cargo.toml4
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/Cargo.toml4
-rw-r--r--compiler/rustc_attr_parsing/Cargo.toml3
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl52
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/cfg.rs2
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/link_attrs.rs419
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs3
-rw-r--r--compiler/rustc_attr_parsing/src/interface.rs9
-rw-r--r--compiler/rustc_attr_parsing/src/lib.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/parser.rs59
-rw-r--r--compiler/rustc_attr_parsing/src/session_diagnostics.rs94
-rw-r--r--compiler/rustc_attr_parsing/src/target_checking.rs37
-rw-r--r--compiler/rustc_baked_icu_data/Cargo.toml9
-rw-r--r--compiler/rustc_baked_icu_data/src/data/any.rs2
-rw-r--r--compiler/rustc_baked_icu_data/src/data/list_and_v1.rs.data71
-rw-r--r--compiler/rustc_baked_icu_data/src/data/macros.rs46
-rw-r--r--compiler/rustc_baked_icu_data/src/data/macros/fallback_likelysubtags_v1.data.rs40
-rw-r--r--compiler/rustc_baked_icu_data/src/data/macros/fallback_parents_v1.data.rs28
-rw-r--r--compiler/rustc_baked_icu_data/src/data/macros/fallback_supplement_co_v1.data.rs32
-rw-r--r--compiler/rustc_baked_icu_data/src/data/macros/list_and_v1.data.rs35
-rw-r--r--compiler/rustc_baked_icu_data/src/data/mod.rs57
-rw-r--r--compiler/rustc_baked_icu_data/src/lib.rs39
-rw-r--r--compiler/rustc_borrowck/Cargo.toml4
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml4
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs2
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml6
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs5
-rw-r--r--compiler/rustc_const_eval/Cargo.toml2
-rw-r--r--compiler/rustc_data_structures/Cargo.toml10
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0458.md4
-rw-r--r--compiler/rustc_error_messages/Cargo.toml7
-rw-r--r--compiler/rustc_error_messages/src/lib.rs25
-rw-r--r--compiler/rustc_errors/Cargo.toml2
-rw-r--r--compiler/rustc_errors/src/emitter.rs89
-rw-r--r--compiler/rustc_expand/Cargo.toml4
-rw-r--r--compiler/rustc_hir/Cargo.toml6
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs117
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs1
-rw-r--r--compiler/rustc_hir_analysis/Cargo.toml4
-rw-r--r--compiler/rustc_hir_typeck/Cargo.toml4
-rw-r--r--compiler/rustc_incremental/Cargo.toml4
-rw-r--r--compiler/rustc_infer/Cargo.toml4
-rw-r--r--compiler/rustc_interface/Cargo.toml2
-rw-r--r--compiler/rustc_interface/src/tests.rs3
-rw-r--r--compiler/rustc_lexer/Cargo.toml8
-rw-r--r--compiler/rustc_lint/Cargo.toml2
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--compiler/rustc_lint/src/transmute.rs30
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp15
-rw-r--r--compiler/rustc_log/Cargo.toml2
-rw-r--r--compiler/rustc_metadata/Cargo.toml4
-rw-r--r--compiler/rustc_metadata/messages.ftl95
-rw-r--r--compiler/rustc_metadata/src/errors.rs217
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs335
-rw-r--r--compiler/rustc_middle/Cargo.toml6
-rw-r--r--compiler/rustc_mir_build/Cargo.toml4
-rw-r--r--compiler/rustc_mir_dataflow/Cargo.toml2
-rw-r--r--compiler/rustc_mir_transform/Cargo.toml4
-rw-r--r--compiler/rustc_monomorphize/Cargo.toml2
-rw-r--r--compiler/rustc_next_trait_solver/Cargo.toml2
-rw-r--r--compiler/rustc_parse/Cargo.toml8
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse_format/Cargo.toml2
-rw-r--r--compiler/rustc_passes/Cargo.toml2
-rw-r--r--compiler/rustc_passes/messages.ftl14
-rw-r--r--compiler/rustc_passes/src/check_attr.rs87
-rw-r--r--compiler/rustc_passes/src/errors.rs19
-rw-r--r--compiler/rustc_pattern_analysis/Cargo.toml2
-rw-r--r--compiler/rustc_privacy/Cargo.toml2
-rw-r--r--compiler/rustc_proc_macro/Cargo.toml2
-rw-r--r--compiler/rustc_public/Cargo.toml2
-rw-r--r--compiler/rustc_query_impl/Cargo.toml2
-rw-r--r--compiler/rustc_query_system/Cargo.toml2
-rw-r--r--compiler/rustc_resolve/Cargo.toml8
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs15
-rw-r--r--compiler/rustc_sanitizers/Cargo.toml4
-rw-r--r--compiler/rustc_serialize/Cargo.toml2
-rw-r--r--compiler/rustc_session/Cargo.toml4
-rw-r--r--compiler/rustc_session/src/config/native_libs.rs3
-rw-r--r--compiler/rustc_session/src/cstore.rs24
-rw-r--r--compiler/rustc_session/src/errors.rs24
-rw-r--r--compiler/rustc_session/src/utils.rs64
-rw-r--r--compiler/rustc_span/Cargo.toml2
-rw-r--r--compiler/rustc_span/src/symbol.rs11
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml2
-rw-r--r--compiler/rustc_target/Cargo.toml11
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/Cargo.toml6
-rw-r--r--compiler/rustc_traits/Cargo.toml2
-rw-r--r--compiler/rustc_transmute/Cargo.toml4
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml4
-rw-r--r--compiler/rustc_type_ir/Cargo.toml6
-rw-r--r--library/alloc/src/string.rs73
-rw-r--r--library/core/src/hint.rs56
-rw-r--r--library/core/src/num/f128.rs23
-rw-r--r--library/core/src/num/f16.rs20
-rw-r--r--library/core/src/num/f32.rs20
-rw-r--r--library/core/src/num/f64.rs26
-rw-r--r--library/core/src/option.rs36
-rw-r--r--library/core/src/panic/location.rs4
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/std/src/sys/alloc/wasm.rs17
-rw-r--r--library/std/src/sys/fs/mod.rs13
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs2
-rw-r--r--src/bootstrap/src/utils/render_tests.rs8
-rw-r--r--src/doc/rustdoc/src/unstable-features.md19
-rw-r--r--src/librustdoc/Cargo.toml4
-rw-r--r--src/librustdoc/clean/inline.rs34
-rw-r--r--src/librustdoc/clean/types.rs49
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/fold.rs3
-rw-r--r--src/librustdoc/formats/cache.rs3
-rw-r--r--src/librustdoc/formats/item_type.rs3
-rw-r--r--src/librustdoc/html/render/context.rs2
-rw-r--r--src/librustdoc/html/render/mod.rs5
-rw-r--r--src/librustdoc/html/render/print_item.rs9
-rw-r--r--src/librustdoc/html/static/css/noscript.css2
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css7
-rw-r--r--src/librustdoc/html/static/js/main.js1
-rw-r--r--src/librustdoc/html/static/js/search.js5
-rw-r--r--src/librustdoc/json/conversions.rs14
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/librustdoc/passes/propagate_stability.rs3
-rw-r--r--src/librustdoc/passes/stripper.rs2
-rw-r--r--src/librustdoc/visit.rs3
m---------src/llvm-project0
-rw-r--r--src/rustdoc-json-types/lib.rs9
m---------src/tools/cargo0
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/common.rs10
-rw-r--r--src/tools/compiletest/src/executor.rs22
-rw-r--r--src/tools/compiletest/src/lib.rs105
-rw-r--r--src/tools/compiletest/src/runtest.rs2
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs29
-rw-r--r--src/tools/compiletest/src/runtest/run_make.rs2
-rw-r--r--src/tools/coverage-dump/Cargo.toml2
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs4
-rw-r--r--src/tools/llvm-bitcode-linker/Cargo.toml4
-rw-r--r--src/tools/tidy/src/deps.rs12
-rw-r--r--tests/assembly-llvm/reg-struct-return.rs143
-rw-r--r--tests/codegen-llvm/addr-of-mutate.rs6
-rw-r--r--tests/codegen-llvm/function-arguments.rs4
-rw-r--r--tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs4
-rw-r--r--tests/crashes/120175.rs3
-rw-r--r--tests/crashes/137580.rs4
-rw-r--r--tests/rustdoc-gui/links-color.goml6
-rw-r--r--tests/rustdoc-gui/module-items-font.goml9
-rw-r--r--tests/rustdoc-gui/search-result-color.goml11
-rw-r--r--tests/rustdoc-gui/sidebar-links-color.goml20
-rw-r--r--tests/rustdoc-gui/src/test_docs/lib.rs4
-rw-r--r--tests/rustdoc-json/doc_attribute.rs18
-rw-r--r--tests/rustdoc-ui/doc-attribute-unsupported.rs7
-rw-r--r--tests/rustdoc-ui/doc-attribute-unsupported.stderr10
-rw-r--r--tests/rustdoc-ui/invalid-attribute.rs10
-rw-r--r--tests/rustdoc-ui/invalid-attribute.stderr18
-rw-r--r--tests/rustdoc/doc-attribute.rs24
-rw-r--r--tests/ui/abi/c-zst.powerpc-linux.stderr2
-rw-r--r--tests/ui/abi/c-zst.s390x-linux.stderr2
-rw-r--r--tests/ui/abi/c-zst.sparc64-linux.stderr2
-rw-r--r--tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr2
-rw-r--r--tests/ui/abi/debug.generic.stderr4
-rw-r--r--tests/ui/abi/debug.loongarch64.stderr4
-rw-r--r--tests/ui/abi/debug.riscv64.stderr4
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr1
-rw-r--r--tests/ui/attributes/malformed-attrs.rs3
-rw-r--r--tests/ui/attributes/malformed-attrs.stderr147
-rw-r--r--tests/ui/c-variadic/issue-86053-1.stderr2
-rw-r--r--tests/ui/closures/issue-78720.stderr2
-rw-r--r--tests/ui/closures/issue-90871.stderr1
-rw-r--r--tests/ui/codegen/indirect-nocapture.rs15
-rw-r--r--tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr2
-rw-r--r--tests/ui/consts/issue-89088.stderr1
-rw-r--r--tests/ui/derives/deriving-meta-unknown-trait.stderr2
-rw-r--r--tests/ui/did_you_mean/println-typo.stderr1
-rw-r--r--tests/ui/error-codes/E0458.rs2
-rw-r--r--tests/ui/error-codes/E0458.stderr29
-rw-r--r--tests/ui/feature-gates/feature-gate-rustdoc_internals.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr16
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs16
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr34
-rw-r--r--tests/ui/impl-trait/call_method_without_import.no_import.stderr1
-rw-r--r--tests/ui/impl-trait/impl-generic-mismatch.stderr1
-rw-r--r--tests/ui/imports/suggest-remove-issue-121315.stderr5
-rw-r--r--tests/ui/issues/issue-17546.stderr4
-rw-r--r--tests/ui/issues/issue-27033.stderr1
-rw-r--r--tests/ui/link-native-libs/issue-43925.rs4
-rw-r--r--tests/ui/link-native-libs/issue-43925.stderr14
-rw-r--r--tests/ui/link-native-libs/issue-43926.rs2
-rw-r--r--tests/ui/link-native-libs/issue-43926.stderr26
-rw-r--r--tests/ui/link-native-libs/link-attr-validation-early.rs6
-rw-r--r--tests/ui/link-native-libs/link-attr-validation-early.stderr62
-rw-r--r--tests/ui/link-native-libs/link-attr-validation-late.rs40
-rw-r--r--tests/ui/link-native-libs/link-attr-validation-late.stderr467
-rw-r--r--tests/ui/link-native-libs/modifiers-override-4.rs12
-rw-r--r--tests/ui/link-native-libs/modifiers-override-4.stderr67
-rw-r--r--tests/ui/link-native-libs/modifiers-override.rs5
-rw-r--r--tests/ui/link-native-libs/modifiers-override.stderr24
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs13
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr26
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs13
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr26
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs13
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr26
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs11
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr4
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs11
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs2
-rw-r--r--tests/ui/lint/int_to_ptr-unsized.rs23
-rw-r--r--tests/ui/lint/int_to_ptr-unsized.stderr27
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr2
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr5
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr3
-rw-r--r--tests/ui/macros/format-foreign-dollar-without-spec.rs5
-rw-r--r--tests/ui/macros/format-foreign-dollar-without-spec.stderr16
-rw-r--r--tests/ui/macros/macro-name-typo.stderr1
-rw-r--r--tests/ui/macros/macro-path-prelude-fail-3.stderr1
-rw-r--r--tests/ui/macros/missing-writer-issue-139830.stderr2
-rw-r--r--tests/ui/malformed/malformed-regressions.rs6
-rw-r--r--tests/ui/malformed/malformed-regressions.stderr65
-rw-r--r--tests/ui/methods/method-call-lifetime-args-unresolved.stderr1
-rw-r--r--tests/ui/parser/bad-lit-suffixes.rs7
-rw-r--r--tests/ui/parser/bad-lit-suffixes.stderr23
-rw-r--r--tests/ui/parser/misspelled-keywords/ref.stderr1
-rw-r--r--tests/ui/parser/recover/recover-pat-exprs.stderr1
-rw-r--r--tests/ui/pattern/deref-patterns/implicit-const-deref.stderr1
-rw-r--r--tests/ui/pattern/issue-115599.stderr1
-rw-r--r--tests/ui/privacy/suggest-box-new.stderr2
-rw-r--r--tests/ui/proc-macro/parent-source-spans.stderr3
-rw-r--r--tests/ui/proc-macro/resolve-error.stderr2
-rw-r--r--tests/ui/resolve/levenshtein.stderr1
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs6
-rw-r--r--tests/ui/sanitizer/cfi/no_builtins.rs22
-rw-r--r--tests/ui/suggestions/attribute-typos.stderr1
-rw-r--r--tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr1
-rw-r--r--tests/ui/suggestions/enum-method-probe.stderr2
-rw-r--r--tests/ui/suggestions/import-trait-for-method-call.stderr1
-rw-r--r--tests/ui/suggestions/multi-suggestion.ascii.stderr2
-rw-r--r--tests/ui/suggestions/multi-suggestion.unicode.stderr4
-rw-r--r--tests/ui/suggestions/suggest-tryinto-edition-change.stderr1
-rw-r--r--tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr9
-rw-r--r--tests/ui/type/issue-7607-1.stderr1
-rw-r--r--tests/ui/typeck/issue-83693.stderr1
-rw-r--r--tests/ui/ufcs/ufcs-partially-resolved.stderr8
-rw-r--r--tests/ui/wasm/wasm-import-module.rs6
-rw-r--r--tests/ui/wasm/wasm-import-module.stderr76
263 files changed, 3173 insertions, 2088 deletions
diff --git a/Cargo.lock b/Cargo.lock
index af7c24abd13..8b9c243879c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1674,76 +1674,59 @@ checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
 dependencies = [
  "displaydoc",
  "potential_utf",
- "yoke 0.8.0",
+ "yoke",
  "zerofrom",
- "zerovec 0.11.4",
+ "zerovec",
 ]
 
 [[package]]
 name = "icu_list"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbfeda1d7775b6548edd4e8b7562304a559a91ed56ab56e18961a053f367c365"
-dependencies = [
- "displaydoc",
- "icu_list_data",
- "icu_locid_transform",
- "icu_provider 1.5.0",
- "regex-automata 0.2.0",
- "writeable 0.5.5",
-]
-
-[[package]]
-name = "icu_list_data"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52b1a7fbdbf3958f1be8354cb59ac73f165b7b7082d447ff2090355c9a069120"
-
-[[package]]
-name = "icu_locale_core"
 version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
+checksum = "e26f94ec776bb8b28cedc7dcf91033b822c5cb4c1783cf7a3f796fc168aa0c8b"
 dependencies = [
  "displaydoc",
- "litemap 0.8.0",
- "tinystr 0.8.1",
- "writeable 0.6.1",
- "zerovec 0.11.4",
+ "icu_provider",
+ "regex-automata 0.4.9",
+ "serde",
+ "writeable",
+ "zerovec",
 ]
 
 [[package]]
-name = "icu_locid"
-version = "1.5.0"
+name = "icu_locale"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+checksum = "6ae5921528335e91da1b6c695dbf1ec37df5ac13faa3f91e5640be93aa2fbefd"
 dependencies = [
  "displaydoc",
- "litemap 0.7.5",
- "tinystr 0.7.6",
- "writeable 0.5.5",
- "zerovec 0.10.4",
+ "icu_collections",
+ "icu_locale_core",
+ "icu_locale_data",
+ "icu_provider",
+ "potential_utf",
+ "tinystr",
+ "zerovec",
 ]
 
 [[package]]
-name = "icu_locid_transform"
-version = "1.5.0"
+name = "icu_locale_core"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
 dependencies = [
  "displaydoc",
- "icu_locid",
- "icu_locid_transform_data",
- "icu_provider 1.5.0",
- "tinystr 0.7.6",
- "zerovec 0.10.4",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
 ]
 
 [[package]]
-name = "icu_locid_transform_data"
-version = "1.5.1"
+name = "icu_locale_data"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
+checksum = "4fdef0c124749d06a743c69e938350816554eb63ac979166590e2b4ee4252765"
 
 [[package]]
 name = "icu_normalizer"
@@ -1755,9 +1738,9 @@ dependencies = [
  "icu_collections",
  "icu_normalizer_data",
  "icu_properties",
- "icu_provider 2.0.0",
+ "icu_provider",
  "smallvec",
- "zerovec 0.11.4",
+ "zerovec",
 ]
 
 [[package]]
@@ -1776,10 +1759,10 @@ dependencies = [
  "icu_collections",
  "icu_locale_core",
  "icu_properties_data",
- "icu_provider 2.0.0",
+ "icu_provider",
  "potential_utf",
  "zerotrie",
- "zerovec 0.11.4",
+ "zerovec",
 ]
 
 [[package]]
@@ -1790,23 +1773,6 @@ checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
 
 [[package]]
 name = "icu_provider"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_provider_macros",
- "stable_deref_trait",
- "tinystr 0.7.6",
- "writeable 0.5.5",
- "yoke 0.7.5",
- "zerofrom",
- "zerovec 0.10.4",
-]
-
-[[package]]
-name = "icu_provider"
 version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
@@ -1814,36 +1780,12 @@ dependencies = [
  "displaydoc",
  "icu_locale_core",
  "stable_deref_trait",
- "tinystr 0.8.1",
- "writeable 0.6.1",
- "yoke 0.8.0",
+ "tinystr",
+ "writeable",
+ "yoke",
  "zerofrom",
  "zerotrie",
- "zerovec 0.11.4",
-]
-
-[[package]]
-name = "icu_provider_adapters"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6324dfd08348a8e0374a447ebd334044d766b1839bb8d5ccf2482a99a77c0bc"
-dependencies = [
- "icu_locid",
- "icu_locid_transform",
- "icu_provider 1.5.0",
- "tinystr 0.7.6",
- "zerovec 0.10.4",
-]
-
-[[package]]
-name = "icu_provider_macros"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
+ "zerovec",
 ]
 
 [[package]]
@@ -2245,12 +2187,6 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
 
 [[package]]
 name = "litemap"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
-
-[[package]]
-name = "litemap"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
@@ -2959,7 +2895,8 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
 dependencies = [
- "zerovec 0.11.4",
+ "serde",
+ "zerovec",
 ]
 
 [[package]]
@@ -3207,15 +3144,6 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9368763f5a9b804326f3af749e16f9abf378d227bcdee7634b13d8f17793782"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "regex-automata"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
@@ -3480,6 +3408,7 @@ dependencies = [
  "rustc_parse",
  "rustc_session",
  "rustc_span",
+ "rustc_target",
  "thin-vec",
 ]
 
@@ -3488,10 +3417,9 @@ name = "rustc_baked_icu_data"
 version = "0.0.0"
 dependencies = [
  "icu_list",
- "icu_locid",
- "icu_locid_transform",
- "icu_provider 1.5.0",
- "zerovec 0.10.4",
+ "icu_locale",
+ "icu_provider",
+ "zerovec",
 ]
 
 [[package]]
@@ -3764,8 +3692,7 @@ dependencies = [
  "fluent-bundle",
  "fluent-syntax",
  "icu_list",
- "icu_locid",
- "icu_provider_adapters",
+ "icu_locale",
  "intl-memoizer",
  "rustc_ast",
  "rustc_ast_pretty",
@@ -5499,22 +5426,12 @@ dependencies = [
 
 [[package]]
 name = "tinystr"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
-dependencies = [
- "displaydoc",
- "zerovec 0.10.4",
-]
-
-[[package]]
-name = "tinystr"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
 dependencies = [
  "displaydoc",
- "zerovec 0.11.4",
+ "zerovec",
 ]
 
 [[package]]
@@ -5779,7 +5696,7 @@ version = "0.9.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
 dependencies = [
- "tinystr 0.8.1",
+ "tinystr",
 ]
 
 [[package]]
@@ -5789,7 +5706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d5957eb82e346d7add14182a3315a7e298f04e1ba4baac36f7f0dbfedba5fc25"
 dependencies = [
  "proc-macro-hack",
- "tinystr 0.8.1",
+ "tinystr",
  "unic-langid-impl",
  "unic-langid-macros-impl",
 ]
@@ -6685,12 +6602,6 @@ dependencies = [
 
 [[package]]
 name = "writeable"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
-
-[[package]]
-name = "writeable"
 version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
@@ -6729,42 +6640,18 @@ dependencies = [
 
 [[package]]
 name = "yoke"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
-dependencies = [
- "serde",
- "stable_deref_trait",
- "yoke-derive 0.7.5",
- "zerofrom",
-]
-
-[[package]]
-name = "yoke"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
 dependencies = [
  "serde",
  "stable_deref_trait",
- "yoke-derive 0.8.0",
+ "yoke-derive",
  "zerofrom",
 ]
 
 [[package]]
 name = "yoke-derive"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
- "synstructure",
-]
-
-[[package]]
-name = "yoke-derive"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
@@ -6823,41 +6710,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
 dependencies = [
  "displaydoc",
- "yoke 0.8.0",
+ "yoke",
  "zerofrom",
 ]
 
 [[package]]
 name = "zerovec"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
-dependencies = [
- "yoke 0.7.5",
- "zerofrom",
- "zerovec-derive 0.10.3",
-]
-
-[[package]]
-name = "zerovec"
 version = "0.11.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
 dependencies = [
- "yoke 0.8.0",
+ "yoke",
  "zerofrom",
- "zerovec-derive 0.11.1",
-]
-
-[[package]]
-name = "zerovec-derive"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.106",
+ "zerovec-derive",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 67c7a9d67ed..5003e107cc8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,6 +59,16 @@ exclude = [
   "obj",
 ]
 
+[workspace.dependencies]
+# tidy-alphabetical-start
+bitflags = "2.9.3"
+itertools = "0.12.1"
+memchr = "2.7.5"
+rustc-literal-escaper = "0.0.5"
+thin-vec = "0.2.14"
+tracing = "0.1.37"
+# tidy-alphabetical-end
+
 [profile.release.package.rustc_thread_pool]
 # The rustc fork of Rayon has deadlock detection code which intermittently
 # causes overflows in the CI (see https://github.com/rust-lang/rust/issues/90227)
diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml
index 83d96d8d04d..3de6d186b8a 100644
--- a/compiler/rustc_abi/Cargo.toml
+++ b/compiler/rustc_abi/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 rand = { version = "0.9.0", default-features = false, optional = true }
 rand_xoshiro = { version = "0.7.0", optional = true }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
@@ -15,7 +15,7 @@ rustc_index = { path = "../rustc_index", default-features = false }
 rustc_macros = { path = "../rustc_macros", optional = true }
 rustc_serialize = { path = "../rustc_serialize", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml
index 155e14a3796..0b8ab7c391c 100644
--- a/compiler/rustc_ast/Cargo.toml
+++ b/compiler/rustc_ast/Cargo.toml
@@ -5,9 +5,9 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
-memchr = "2.7.4"
-rustc-literal-escaper = "0.0.5"
+bitflags.workspace = true
+memchr.workspace = true
+rustc-literal-escaper.workspace = true
 rustc_ast_ir = { path = "../rustc_ast_ir" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_index = { path = "../rustc_index" }
@@ -15,6 +15,6 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
+thin-vec.workspace = true
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 6ac258155fe..317742a3bb8 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -24,6 +24,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 3e04f8b11ec..6d2bcbed22b 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
@@ -18,5 +18,5 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
-thin-vec = "0.2.12"
+thin-vec.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index e763c9d69fc..9ab5b0b3547 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -188,6 +188,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                         notable_trait => doc_notable_trait
                     }
                     "meant for internal use only" {
+                        attribute => rustdoc_internals
                         keyword => rustdoc_internals
                         fake_variadic => rustdoc_internals
                         search_unbox => rustdoc_internals
diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml
index b704040be96..0c7e55305b4 100644
--- a/compiler/rustc_ast_pretty/Cargo.toml
+++ b/compiler/rustc_ast_pretty/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_ast = { path = "../rustc_ast" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_span = { path = "../rustc_span" }
@@ -13,5 +13,5 @@ rustc_span = { path = "../rustc_span" }
 
 [dev-dependencies]
 # tidy-alphabetical-start
-thin-vec = "0.2.12"
+thin-vec.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml
index fd8f7ffb2ed..8bfde43fd33 100644
--- a/compiler/rustc_attr_parsing/Cargo.toml
+++ b/compiler/rustc_attr_parsing/Cargo.toml
@@ -17,5 +17,6 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.12"
+rustc_target = { path = "../rustc_target" }
+thin-vec.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index 8f24b51f1d9..b8a748563d5 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -195,3 +195,55 @@ attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`
 
 attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
     .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
+
+attr_parsing_as_needed_compatibility =
+    linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
+
+attr_parsing_bundle_needs_static =
+    linking modifier `bundle` is only compatible with `static` linking kind
+
+attr_parsing_empty_link_name =
+    link name must not be empty
+    .label = empty link name
+
+attr_parsing_import_name_type_raw =
+    import name type can only be used with link kind `raw-dylib`
+
+attr_parsing_import_name_type_x86 =
+    import name type is only supported on x86
+
+attr_parsing_incompatible_wasm_link =
+    `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
+
+attr_parsing_invalid_link_modifier =
+    invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
+
+attr_parsing_link_arg_unstable =
+    link kind `link-arg` is unstable
+
+attr_parsing_link_cfg_unstable =
+    link cfg is unstable
+
+attr_parsing_link_framework_apple =
+    link kind `framework` is only supported on Apple targets
+
+attr_parsing_link_requires_name =
+    `#[link]` attribute requires a `name = "string"` argument
+    .label = missing `name` argument
+
+attr_parsing_multiple_modifiers =
+    multiple `{$modifier}` modifiers in a single `modifiers` argument
+
+attr_parsing_multiple_renamings =
+    multiple renamings were specified for library `{$lib_name}`
+attr_parsing_raw_dylib_no_nul =
+    link name must not contain NUL characters if link kind is `raw-dylib`
+
+attr_parsing_raw_dylib_elf_unstable =
+    link kind `raw-dylib` is unstable on ELF platforms
+
+attr_parsing_raw_dylib_only_windows =
+    link kind `raw-dylib` is only supported on Windows targets
+
+attr_parsing_whole_archive_needs_static =
+    linking modifier `whole-archive` is only compatible with `static` linking kind
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs
index 695ee666476..70855611079 100644
--- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs
@@ -36,7 +36,7 @@ pub fn parse_cfg_attr<'c, S: Stage>(
     parse_cfg_entry(cx, single)
 }
 
-fn parse_cfg_entry<S: Stage>(
+pub(crate) fn parse_cfg_entry<S: Stage>(
     cx: &mut AcceptContext<'_, '_, S>,
     item: &MetaItemOrLitParser<'_>,
 ) -> Option<CfgEntry> {
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
index 5e4551ccd79..d4942e56f42 100644
--- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -1,9 +1,21 @@
+use rustc_feature::Features;
 use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
-use rustc_hir::attrs::Linkage;
+use rustc_hir::attrs::*;
+use rustc_session::Session;
+use rustc_session::parse::feature_err;
+use rustc_span::kw;
+use rustc_target::spec::BinaryFormat;
 
 use super::prelude::*;
 use super::util::parse_single_integer;
-use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection};
+use crate::attributes::cfg::parse_cfg_entry;
+use crate::fluent_generated;
+use crate::session_diagnostics::{
+    AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86,
+    IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange,
+    LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows,
+    WholeArchiveNeedsStatic,
+};
 
 pub(crate) struct LinkNameParser;
 
@@ -34,6 +46,409 @@ impl<S: Stage> SingleAttributeParser<S> for LinkNameParser {
     }
 }
 
+pub(crate) struct LinkParser;
+
+impl<S: Stage> CombineAttributeParser<S> for LinkParser {
+    type Item = LinkEntry;
+    const PATH: &[Symbol] = &[sym::link];
+    const CONVERT: ConvertFn<Self::Item> = AttributeKind::Link;
+    const TEMPLATE: AttributeTemplate = template!(List: &[
+            r#"name = "...""#,
+            r#"name = "...", kind = "dylib|static|...""#,
+            r#"name = "...", wasm_import_module = "...""#,
+            r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
+            r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
+        ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute");
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
+
+    fn extend<'c>(
+        cx: &'c mut AcceptContext<'_, '_, S>,
+        args: &'c ArgParser<'_>,
+    ) -> impl IntoIterator<Item = Self::Item> + 'c {
+        let mut result = None;
+        let Some(items) = args.list() else {
+            cx.expected_list(cx.attr_span);
+            return result;
+        };
+
+        let sess = cx.sess();
+        let features = cx.features();
+
+        let mut name = None;
+        let mut kind = None;
+        let mut modifiers = None;
+        let mut cfg = None;
+        let mut wasm_import_module = None;
+        let mut import_name_type = None;
+        for item in items.mixed() {
+            let Some(item) = item.meta_item() else {
+                cx.unexpected_literal(item.span());
+                continue;
+            };
+
+            let cont = match item.path().word().map(|ident| ident.name) {
+                Some(sym::name) => Self::parse_link_name(item, &mut name, cx),
+                Some(sym::kind) => Self::parse_link_kind(item, &mut kind, cx, sess, features),
+                Some(sym::modifiers) => Self::parse_link_modifiers(item, &mut modifiers, cx),
+                Some(sym::cfg) => Self::parse_link_cfg(item, &mut cfg, cx, sess, features),
+                Some(sym::wasm_import_module) => {
+                    Self::parse_link_wasm_import_module(item, &mut wasm_import_module, cx)
+                }
+                Some(sym::import_name_type) => {
+                    Self::parse_link_import_name_type(item, &mut import_name_type, cx)
+                }
+                _ => {
+                    cx.expected_specific_argument_strings(
+                        item.span(),
+                        &[
+                            sym::name,
+                            sym::kind,
+                            sym::modifiers,
+                            sym::cfg,
+                            sym::wasm_import_module,
+                            sym::import_name_type,
+                        ],
+                    );
+                    true
+                }
+            };
+            if !cont {
+                return result;
+            }
+        }
+
+        // Do this outside the above loop so we don't depend on modifiers coming after kinds
+        let mut verbatim = None;
+        if let Some((modifiers, span)) = modifiers {
+            for modifier in modifiers.as_str().split(',') {
+                let (modifier, value): (Symbol, bool) = match modifier.strip_prefix(&['+', '-']) {
+                    Some(m) => (Symbol::intern(m), modifier.starts_with('+')),
+                    None => {
+                        cx.emit_err(InvalidLinkModifier { span });
+                        continue;
+                    }
+                };
+
+                macro report_unstable_modifier($feature: ident) {
+                    if !features.$feature() {
+                        // FIXME: make this translatable
+                        #[expect(rustc::untranslatable_diagnostic)]
+                        feature_err(
+                            sess,
+                            sym::$feature,
+                            span,
+                            format!("linking modifier `{modifier}` is unstable"),
+                        )
+                        .emit();
+                    }
+                }
+                let assign_modifier = |dst: &mut Option<bool>| {
+                    if dst.is_some() {
+                        cx.emit_err(MultipleModifiers { span, modifier });
+                    } else {
+                        *dst = Some(value);
+                    }
+                };
+                match (modifier, &mut kind) {
+                    (sym::bundle, Some(NativeLibKind::Static { bundle, .. })) => {
+                        assign_modifier(bundle)
+                    }
+                    (sym::bundle, _) => {
+                        cx.emit_err(BundleNeedsStatic { span });
+                    }
+
+                    (sym::verbatim, _) => assign_modifier(&mut verbatim),
+
+                    (
+                        sym::whole_dash_archive,
+                        Some(NativeLibKind::Static { whole_archive, .. }),
+                    ) => assign_modifier(whole_archive),
+                    (sym::whole_dash_archive, _) => {
+                        cx.emit_err(WholeArchiveNeedsStatic { span });
+                    }
+
+                    (sym::as_dash_needed, Some(NativeLibKind::Dylib { as_needed }))
+                    | (sym::as_dash_needed, Some(NativeLibKind::Framework { as_needed })) => {
+                        report_unstable_modifier!(native_link_modifiers_as_needed);
+                        assign_modifier(as_needed)
+                    }
+                    (sym::as_dash_needed, _) => {
+                        cx.emit_err(AsNeededCompatibility { span });
+                    }
+
+                    _ => {
+                        cx.expected_specific_argument_strings(
+                            span,
+                            &[
+                                sym::bundle,
+                                sym::verbatim,
+                                sym::whole_dash_archive,
+                                sym::as_dash_needed,
+                            ],
+                        );
+                    }
+                }
+            }
+        }
+
+        if let Some((_, span)) = wasm_import_module {
+            if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
+                cx.emit_err(IncompatibleWasmLink { span });
+            }
+        }
+
+        if wasm_import_module.is_some() {
+            (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
+        }
+        let Some((name, name_span)) = name else {
+            cx.emit_err(LinkRequiresName { span: cx.attr_span });
+            return result;
+        };
+
+        // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
+        if let Some((_, span)) = import_name_type {
+            if kind != Some(NativeLibKind::RawDylib) {
+                cx.emit_err(ImportNameTypeRaw { span });
+            }
+        }
+
+        if let Some(NativeLibKind::RawDylib) = kind
+            && name.as_str().contains('\0')
+        {
+            cx.emit_err(RawDylibNoNul { span: name_span });
+        }
+
+        result = Some(LinkEntry {
+            span: cx.attr_span,
+            kind: kind.unwrap_or(NativeLibKind::Unspecified),
+            name,
+            cfg,
+            verbatim,
+            import_name_type,
+        });
+        result
+    }
+}
+
+impl LinkParser {
+    fn parse_link_name<S: Stage>(
+        item: &MetaItemParser<'_>,
+        name: &mut Option<(Symbol, Span)>,
+        cx: &mut AcceptContext<'_, '_, S>,
+    ) -> bool {
+        if name.is_some() {
+            cx.duplicate_key(item.span(), sym::name);
+            return true;
+        }
+        let Some(nv) = item.args().name_value() else {
+            cx.expected_name_value(item.span(), Some(sym::name));
+            return false;
+        };
+        let Some(link_name) = nv.value_as_str() else {
+            cx.expected_name_value(item.span(), Some(sym::name));
+            return false;
+        };
+
+        if link_name.is_empty() {
+            cx.emit_err(EmptyLinkName { span: nv.value_span });
+        }
+        *name = Some((link_name, nv.value_span));
+        true
+    }
+
+    fn parse_link_kind<S: Stage>(
+        item: &MetaItemParser<'_>,
+        kind: &mut Option<NativeLibKind>,
+        cx: &mut AcceptContext<'_, '_, S>,
+        sess: &Session,
+        features: &Features,
+    ) -> bool {
+        if kind.is_some() {
+            cx.duplicate_key(item.span(), sym::kind);
+            return true;
+        }
+        let Some(nv) = item.args().name_value() else {
+            cx.expected_name_value(item.span(), Some(sym::kind));
+            return true;
+        };
+        let Some(link_kind) = nv.value_as_str() else {
+            cx.expected_name_value(item.span(), Some(sym::kind));
+            return true;
+        };
+
+        let link_kind = match link_kind {
+            kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None },
+            sym::dylib => NativeLibKind::Dylib { as_needed: None },
+            sym::framework => {
+                if !sess.target.is_like_darwin {
+                    cx.emit_err(LinkFrameworkApple { span: nv.value_span });
+                }
+                NativeLibKind::Framework { as_needed: None }
+            }
+            sym::raw_dash_dylib => {
+                if sess.target.is_like_windows {
+                    // raw-dylib is stable and working on Windows
+                } else if sess.target.binary_format == BinaryFormat::Elf && features.raw_dylib_elf()
+                {
+                    // raw-dylib is unstable on ELF, but the user opted in
+                } else if sess.target.binary_format == BinaryFormat::Elf && sess.is_nightly_build()
+                {
+                    feature_err(
+                        sess,
+                        sym::raw_dylib_elf,
+                        nv.value_span,
+                        fluent_generated::attr_parsing_raw_dylib_elf_unstable,
+                    )
+                    .emit();
+                } else {
+                    cx.emit_err(RawDylibOnlyWindows { span: nv.value_span });
+                }
+
+                NativeLibKind::RawDylib
+            }
+            sym::link_dash_arg => {
+                if !features.link_arg_attribute() {
+                    feature_err(
+                        sess,
+                        sym::link_arg_attribute,
+                        nv.value_span,
+                        fluent_generated::attr_parsing_link_arg_unstable,
+                    )
+                    .emit();
+                }
+                NativeLibKind::LinkArg
+            }
+            _kind => {
+                cx.expected_specific_argument_strings(
+                    nv.value_span,
+                    &[
+                        kw::Static,
+                        sym::dylib,
+                        sym::framework,
+                        sym::raw_dash_dylib,
+                        sym::link_dash_arg,
+                    ],
+                );
+                return true;
+            }
+        };
+        *kind = Some(link_kind);
+        true
+    }
+
+    fn parse_link_modifiers<S: Stage>(
+        item: &MetaItemParser<'_>,
+        modifiers: &mut Option<(Symbol, Span)>,
+        cx: &mut AcceptContext<'_, '_, S>,
+    ) -> bool {
+        if modifiers.is_some() {
+            cx.duplicate_key(item.span(), sym::modifiers);
+            return true;
+        }
+        let Some(nv) = item.args().name_value() else {
+            cx.expected_name_value(item.span(), Some(sym::modifiers));
+            return true;
+        };
+        let Some(link_modifiers) = nv.value_as_str() else {
+            cx.expected_name_value(item.span(), Some(sym::modifiers));
+            return true;
+        };
+        *modifiers = Some((link_modifiers, nv.value_span));
+        true
+    }
+
+    fn parse_link_cfg<S: Stage>(
+        item: &MetaItemParser<'_>,
+        cfg: &mut Option<CfgEntry>,
+        cx: &mut AcceptContext<'_, '_, S>,
+        sess: &Session,
+        features: &Features,
+    ) -> bool {
+        if cfg.is_some() {
+            cx.duplicate_key(item.span(), sym::cfg);
+            return true;
+        }
+        let Some(link_cfg) = item.args().list() else {
+            cx.expected_list(item.span());
+            return true;
+        };
+        let Some(link_cfg) = link_cfg.single() else {
+            cx.expected_single_argument(item.span());
+            return true;
+        };
+        if !features.link_cfg() {
+            feature_err(
+                sess,
+                sym::link_cfg,
+                item.span(),
+                fluent_generated::attr_parsing_link_cfg_unstable,
+            )
+            .emit();
+        }
+        *cfg = parse_cfg_entry(cx, link_cfg);
+        true
+    }
+
+    fn parse_link_wasm_import_module<S: Stage>(
+        item: &MetaItemParser<'_>,
+        wasm_import_module: &mut Option<(Symbol, Span)>,
+        cx: &mut AcceptContext<'_, '_, S>,
+    ) -> bool {
+        if wasm_import_module.is_some() {
+            cx.duplicate_key(item.span(), sym::wasm_import_module);
+            return true;
+        }
+        let Some(nv) = item.args().name_value() else {
+            cx.expected_name_value(item.span(), Some(sym::wasm_import_module));
+            return true;
+        };
+        let Some(link_wasm_import_module) = nv.value_as_str() else {
+            cx.expected_name_value(item.span(), Some(sym::wasm_import_module));
+            return true;
+        };
+        *wasm_import_module = Some((link_wasm_import_module, item.span()));
+        true
+    }
+
+    fn parse_link_import_name_type<S: Stage>(
+        item: &MetaItemParser<'_>,
+        import_name_type: &mut Option<(PeImportNameType, Span)>,
+        cx: &mut AcceptContext<'_, '_, S>,
+    ) -> bool {
+        if import_name_type.is_some() {
+            cx.duplicate_key(item.span(), sym::import_name_type);
+            return true;
+        }
+        let Some(nv) = item.args().name_value() else {
+            cx.expected_name_value(item.span(), Some(sym::import_name_type));
+            return true;
+        };
+        let Some(link_import_name_type) = nv.value_as_str() else {
+            cx.expected_name_value(item.span(), Some(sym::import_name_type));
+            return true;
+        };
+        if cx.sess().target.arch != "x86" {
+            cx.emit_err(ImportNameTypeX86 { span: item.span() });
+            return true;
+        }
+
+        let link_import_name_type = match link_import_name_type {
+            sym::decorated => PeImportNameType::Decorated,
+            sym::noprefix => PeImportNameType::NoPrefix,
+            sym::undecorated => PeImportNameType::Undecorated,
+            _ => {
+                cx.expected_specific_argument_strings(
+                    item.span(),
+                    &[sym::decorated, sym::noprefix, sym::undecorated],
+                );
+                return true;
+            }
+        };
+        *import_name_type = Some((link_import_name_type, item.span()));
+        true
+    }
+}
+
 pub(crate) struct LinkSectionParser;
 
 impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index b16ef7edd64..7f5b810f244 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -30,7 +30,7 @@ use crate::attributes::dummy::DummyParser;
 use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
 use crate::attributes::link_attrs::{
     ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
-    LinkSectionParser, LinkageParser, StdInternalSymbolParser,
+    LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser,
 };
 use crate::attributes::lint_helpers::{
     AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
@@ -162,6 +162,7 @@ attribute_parsers!(
         Combine<AllowConstFnUnstableParser>,
         Combine<AllowInternalUnstableParser>,
         Combine<ForceTargetFeatureParser>,
+        Combine<LinkParser>,
         Combine<ReprParser>,
         Combine<TargetFeatureParser>,
         Combine<UnstableFeatureBoundParser>,
diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs
index a3558850ef3..0fe3c209421 100644
--- a/compiler/rustc_attr_parsing/src/interface.rs
+++ b/compiler/rustc_attr_parsing/src/interface.rs
@@ -273,14 +273,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
                             (accept.accept_fn)(&mut cx, args);
                             if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) {
                                 Self::check_type(accept.attribute_type, target, &mut cx);
-                                self.check_target(
-                                    path.get_attribute_path(),
-                                    attr.span,
-                                    &accept.allowed_targets,
-                                    target,
-                                    target_id,
-                                    &mut emit_lint,
-                                );
+                                Self::check_target(&accept.allowed_targets, target, &mut cx);
                             }
                         }
                     } else {
diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs
index 4dd908cdc40..f51cc8c4e8b 100644
--- a/compiler/rustc_attr_parsing/src/lib.rs
+++ b/compiler/rustc_attr_parsing/src/lib.rs
@@ -79,6 +79,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![doc(rust_logo)]
+#![feature(decl_macro)]
 #![feature(rustdoc_internals)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 6d3cf684296..4f903594225 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -10,11 +10,11 @@ use rustc_ast::token::{self, Delimiter, MetaVarKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path};
 use rustc_ast_pretty::pprust;
-use rustc_errors::PResult;
+use rustc_errors::{Diag, PResult};
 use rustc_hir::{self as hir, AttrPath};
 use rustc_parse::exp;
 use rustc_parse::parser::{Parser, PathStyle, token_descr};
-use rustc_session::errors::report_lit_error;
+use rustc_session::errors::{create_lit_error, report_lit_error};
 use rustc_session::parse::ParseSess;
 use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, sym};
 use thin_vec::ThinVec;
@@ -379,22 +379,23 @@ struct MetaItemListParserContext<'a, 'sess> {
 
 impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
     fn parse_unsuffixed_meta_item_lit(&mut self) -> PResult<'sess, MetaItemLit> {
-        let uninterpolated_span = self.parser.token_uninterpolated_span();
-        let Some(token_lit) = self.parser.eat_token_lit() else {
-            return self.parser.handle_missing_lit(Parser::mk_meta_item_lit_char);
-        };
+        let Some(token_lit) = self.parser.eat_token_lit() else { return Err(self.expected_lit()) };
+        self.unsuffixed_meta_item_from_lit(token_lit)
+    }
 
+    fn unsuffixed_meta_item_from_lit(
+        &mut self,
+        token_lit: token::Lit,
+    ) -> PResult<'sess, MetaItemLit> {
         let lit = match MetaItemLit::from_token_lit(token_lit, self.parser.prev_token.span) {
             Ok(lit) => lit,
             Err(err) => {
-                let guar =
-                    report_lit_error(&self.parser.psess, err, token_lit, uninterpolated_span);
-                // Pack possible quotes and prefixes from the original literal into
-                // the error literal's symbol so they can be pretty-printed faithfully.
-                let suffixless_lit = token::Lit::new(token_lit.kind, token_lit.symbol, None);
-                let symbol = Symbol::intern(&suffixless_lit.to_string());
-                let token_lit = token::Lit::new(token::Err(guar), symbol, token_lit.suffix);
-                MetaItemLit::from_token_lit(token_lit, uninterpolated_span).unwrap()
+                return Err(create_lit_error(
+                    &self.parser.psess,
+                    err,
+                    token_lit,
+                    self.parser.prev_token_uninterpolated_span(),
+                ));
             }
         };
 
@@ -448,16 +449,28 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
     }
 
     fn parse_meta_item_inner(&mut self) -> PResult<'sess, MetaItemOrLitParser<'static>> {
-        match self.parse_unsuffixed_meta_item_lit() {
-            Ok(lit) => return Ok(MetaItemOrLitParser::Lit(lit)),
-            Err(err) => err.cancel(), // we provide a better error below
-        }
-
-        match self.parse_attr_item() {
-            Ok(mi) => return Ok(MetaItemOrLitParser::MetaItemParser(mi)),
-            Err(err) => err.cancel(), // we provide a better error below
+        if let Some(token_lit) = self.parser.eat_token_lit() {
+            // If a literal token is parsed, we commit to parsing a MetaItemLit for better errors
+            Ok(MetaItemOrLitParser::Lit(self.unsuffixed_meta_item_from_lit(token_lit)?))
+        } else {
+            let prev_pros = self.parser.approx_token_stream_pos();
+            match self.parse_attr_item() {
+                Ok(item) => Ok(MetaItemOrLitParser::MetaItemParser(item)),
+                Err(err) => {
+                    // If `parse_attr_item` made any progress, it likely has a more precise error we should prefer
+                    // If it didn't make progress we use the `expected_lit` from below
+                    if self.parser.approx_token_stream_pos() != prev_pros {
+                        Err(err)
+                    } else {
+                        err.cancel();
+                        Err(self.expected_lit())
+                    }
+                }
+            }
         }
+    }
 
+    fn expected_lit(&mut self) -> Diag<'sess> {
         let mut err = InvalidMetaItem {
             span: self.parser.token.span,
             descr: token_descr(&self.parser.token),
@@ -492,7 +505,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
             self.parser.bump();
         }
 
-        Err(self.parser.dcx().create_err(err))
+        self.parser.dcx().create_err(err)
     }
 
     fn parse(
diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
index a639b55e81f..a9dee23bf6a 100644
--- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs
+++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs
@@ -836,3 +836,97 @@ pub(crate) struct InvalidAttrStyle {
     pub target_span: Option<Span>,
     pub target: Target,
 }
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_empty_link_name, code = E0454)]
+pub(crate) struct EmptyLinkName {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_link_framework_apple, code = E0455)]
+pub(crate) struct LinkFrameworkApple {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_incompatible_wasm_link)]
+pub(crate) struct IncompatibleWasmLink {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_link_requires_name, code = E0459)]
+pub(crate) struct LinkRequiresName {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_raw_dylib_no_nul)]
+pub(crate) struct RawDylibNoNul {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_raw_dylib_only_windows, code = E0455)]
+pub(crate) struct RawDylibOnlyWindows {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_invalid_link_modifier)]
+pub(crate) struct InvalidLinkModifier {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_multiple_modifiers)]
+pub(crate) struct MultipleModifiers {
+    #[primary_span]
+    pub span: Span,
+    pub modifier: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_import_name_type_x86)]
+pub(crate) struct ImportNameTypeX86 {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_bundle_needs_static)]
+pub(crate) struct BundleNeedsStatic {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_whole_archive_needs_static)]
+pub(crate) struct WholeArchiveNeedsStatic {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_as_needed_compatibility)]
+pub(crate) struct AsNeededCompatibility {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(attr_parsing_import_name_type_raw)]
+pub(crate) struct ImportNameTypeRaw {
+    #[primary_span]
+    pub span: Span,
+}
diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs
index 6f4dd76fa81..edc496b460c 100644
--- a/compiler/rustc_attr_parsing/src/target_checking.rs
+++ b/compiler/rustc_attr_parsing/src/target_checking.rs
@@ -3,9 +3,8 @@ use std::borrow::Cow;
 use rustc_ast::AttrStyle;
 use rustc_errors::DiagArgValue;
 use rustc_feature::{AttributeType, Features};
-use rustc_hir::lints::{AttributeLint, AttributeLintKind};
-use rustc_hir::{AttrPath, MethodKind, Target};
-use rustc_span::Span;
+use rustc_hir::lints::AttributeLintKind;
+use rustc_hir::{MethodKind, Target};
 
 use crate::AttributeParser;
 use crate::context::{AcceptContext, Stage};
@@ -71,38 +70,34 @@ pub(crate) enum Policy {
 
 impl<'sess, S: Stage> AttributeParser<'sess, S> {
     pub(crate) fn check_target(
-        &self,
-        attr_name: AttrPath,
-        attr_span: Span,
         allowed_targets: &AllowedTargets,
         target: Target,
-        target_id: S::Id,
-        mut emit_lint: impl FnMut(AttributeLint<S::Id>),
+        cx: &mut AcceptContext<'_, 'sess, S>,
     ) {
         match allowed_targets.is_allowed(target) {
             AllowedResult::Allowed => {}
             AllowedResult::Warn => {
                 let allowed_targets = allowed_targets.allowed_targets();
-                let (applied, only) =
-                    allowed_targets_applied(allowed_targets, target, self.features);
-                emit_lint(AttributeLint {
-                    id: target_id,
-                    span: attr_span,
-                    kind: AttributeLintKind::InvalidTarget {
-                        name: attr_name,
+                let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
+                let name = cx.attr_path.clone();
+                let attr_span = cx.attr_span;
+                cx.emit_lint(
+                    AttributeLintKind::InvalidTarget {
+                        name,
                         target,
                         only: if only { "only " } else { "" },
                         applied,
                     },
-                });
+                    attr_span,
+                );
             }
             AllowedResult::Error => {
                 let allowed_targets = allowed_targets.allowed_targets();
-                let (applied, only) =
-                    allowed_targets_applied(allowed_targets, target, self.features);
-                self.dcx().emit_err(InvalidTarget {
-                    span: attr_span,
-                    name: attr_name,
+                let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
+                let name = cx.attr_path.clone();
+                cx.dcx().emit_err(InvalidTarget {
+                    span: cx.attr_span.clone(),
+                    name,
                     target: target.plural_name(),
                     only: if only { "only " } else { "" },
                     applied: DiagArgValue::StrListSepByAnd(
diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml
index cb0e145386b..2f1ab7df379 100644
--- a/compiler/rustc_baked_icu_data/Cargo.toml
+++ b/compiler/rustc_baked_icu_data/Cargo.toml
@@ -5,9 +5,8 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-icu_list = "1.2"
-icu_locid = "1.2"
-icu_locid_transform = "1.3.2"
-icu_provider = { version = "1.2", features = ["sync"] }
-zerovec = "0.10.0"
+icu_list = { version = "2.0", default-features = false }
+icu_locale = { version = "2.0", default-features = false, features = ["compiled_data"] }
+icu_provider = { version = "2.0", features = ["baked", "sync"] }
+zerovec = "0.11.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_baked_icu_data/src/data/any.rs b/compiler/rustc_baked_icu_data/src/data/any.rs
deleted file mode 100644
index 23028876676..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/any.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-// @generated
-impl_any_provider!(BakedDataProvider);
diff --git a/compiler/rustc_baked_icu_data/src/data/list_and_v1.rs.data b/compiler/rustc_baked_icu_data/src/data/list_and_v1.rs.data
new file mode 100644
index 00000000000..1d60e0085fc
--- /dev/null
+++ b/compiler/rustc_baked_icu_data/src/data/list_and_v1.rs.data
@@ -0,0 +1,71 @@
+// @generated
+/// Implement `DataProvider<ListAndV1>` on the given struct using the data
+/// hardcoded in this file. This allows the struct to be used with
+/// `icu`'s `_unstable` constructors.
+///
+/// Using this implementation will embed the following data in the binary's data segment:
+/// * 179B for the lookup data structure (33 data identifiers)
+/// * 4183B[^1] for the actual data (11 unique structs)
+///
+/// [^1]: these numbers can be smaller in practice due to linker deduplication
+///
+/// This macro requires the following crates:
+/// * `icu_list`
+/// * `icu_locale/compiled_data`
+/// * `icu_provider`
+/// * `icu_provider/baked`
+/// * `zerovec`
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __impl_list_and_v1 {
+    ($ provider : ty) => {
+        #[clippy::msrv = "1.82"]
+        const _: () = <$provider>::MUST_USE_MAKE_PROVIDER_MACRO;
+        #[clippy::msrv = "1.82"]
+        impl $provider {
+            const DATA_LIST_AND_V1: icu_provider::baked::zerotrie::Data<icu_list::provider::ListAndV1> = {
+                const TRIE: icu_provider::baked::zerotrie::ZeroTrieSimpleAscii<&'static [u8]> = icu_provider::baked::zerotrie::ZeroTrieSimpleAscii { store: b"\xC8efijprtz\x18#.9DOZ\xC2ns\n\x1E\xC3NSW\x01\x02\x80\x85\x8A\x1E\xC3NSW\x01\x02\x81\x81\x81r\x1E\xC3NSW\x01\x02\x80\x86\x86t\x1E\xC3NSW\x01\x02\x82\x82\x82a\x1E\xC3NSW\x01\x02\x83\x83\x83t\x1E\xC3NSW\x01\x02\x80\x82\x82u\x1E\xC3NSW\x01\x02\x80\x87\x87r\x1E\xC3NSW\x01\x02\x80\x88\x88h\xC2\x1E-\t\xC3NSW\x01\x02\x83\x89\x89Han\xC2st\n\x1E\xC3NSW\x01\x02\x83\x89\x89\x1E\xC3NSW\x01\x02\x84\x89\x89" };
+                const VALUES: &'static [<icu_list::provider::ListAndV1 as icu_provider::baked::zerotrie::DynamicDataMarker>::DataStruct] = &[icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" y ") }, 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x02\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\x01\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF`\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\x12\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x02\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\x80\x01\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\x05\x05\x05\x06\x06\x0C\x0C\r\r\0\0\0\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\x02\0\x1B\0\0\0\0\0\x12\0\0\0\x12\0\0\x03\x06\x06\r\r\0\0\0\0\0h\0\0\0h\0\0\0\0\0\0\x0E\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\x01\n\0\0\x01\x19\0\0\0\x12\0\0\x02\x0F\x11\0\0\0\0\0D\0\0\0\0\0\0\x02\x11\x11\0\0\0\0\0\xBF\0\0\0\0\0\0\x02\x0F\x11\0\0\0\0\0\xBF\0\0\0\0\0\0\x02\x0F\x10\0\0\0\0\0\xBF\0\0\0\0\0\0\x02\x10\x11\0\0\0\0\0\xDD\0\0\0\0\0\0\x02\x0F\x11\0\0\0\0\0\xDD\0\0\0\0\0\0\x02\x0F\x0F\0\0\0\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\x03\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\0\0\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\x01\0\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0`\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\x12\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" e ") }, 3u8) }) }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" e ") }, 3u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, 3u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, 3u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, 3u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE5\x92\x8C") }, 3u8), special_case: None }, pair: Some(icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, 3u8), special_case: None }) }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", & ") }, 4u8), special_case: None }, pair: Some(icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" & ") }, 3u8), special_case: None }) }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" et ") }, 4u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" \xD0\xB8 ") }, 4u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" ve ") }, 4u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, 3u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE3\x80\x81") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b"\xE5\x92\x8C") }, 3u8), special_case: None }, pair: None }, icu_list::provider::ListFormatterPatterns { start: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, 2u8), middle: unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", ") }, end: icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b", and ") }, 6u8), special_case: None }, pair: Some(icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(unsafe { zerovec::VarZeroCow::from_bytes_unchecked(b" and ") }, 5u8), special_case: None }) }];
+                unsafe { icu_provider::baked::zerotrie::Data::from_trie_and_values_unchecked(TRIE, VALUES) }
+            };
+        }
+        #[clippy::msrv = "1.82"]
+        impl icu_provider::DataProvider<icu_list::provider::ListAndV1> for $provider {
+            fn load(&self, req: icu_provider::DataRequest) -> Result<icu_provider::DataResponse<icu_list::provider::ListAndV1>, icu_provider::DataError> {
+                let mut metadata = icu_provider::DataResponseMetadata::default();
+                let payload = if let Some(payload) = icu_provider::baked::DataStore::get(&Self::DATA_LIST_AND_V1, req.id, req.metadata.attributes_prefix_match) {
+                    payload
+                } else {
+                    const FALLBACKER: icu_locale::fallback::LocaleFallbackerWithConfig<'static> = icu_locale::fallback::LocaleFallbacker::new().for_config(<icu_list::provider::ListAndV1 as icu_provider::DataMarker>::INFO.fallback_config);
+                    let mut fallback_iterator = FALLBACKER.fallback_for(req.id.locale.clone());
+                    loop {
+                        if let Some(payload) = icu_provider::baked::DataStore::get(&Self::DATA_LIST_AND_V1, icu_provider::DataIdentifierBorrowed::for_marker_attributes_and_locale(req.id.marker_attributes, fallback_iterator.get()), req.metadata.attributes_prefix_match) {
+                            metadata.locale = Some(fallback_iterator.take());
+                            break payload;
+                        }
+                        if fallback_iterator.get().is_unknown() {
+                            return Err(icu_provider::DataErrorKind::IdentifierNotFound.with_req(<icu_list::provider::ListAndV1 as icu_provider::DataMarker>::INFO, req));
+                        }
+                        fallback_iterator.step();
+                    }
+                };
+                Ok(icu_provider::DataResponse { payload, metadata })
+            }
+        }
+    };
+    ($ provider : ty , ITER) => {
+        __impl_list_and_v1!($provider);
+        #[clippy::msrv = "1.82"]
+        impl icu_provider::IterableDataProvider<icu_list::provider::ListAndV1> for $provider {
+            fn iter_ids(&self) -> Result<std::collections::BTreeSet<icu_provider::DataIdentifierCow<'static>>, icu_provider::DataError> {
+                Ok(icu_provider::baked::DataStore::iter(&Self::DATA_LIST_AND_V1).collect())
+            }
+        }
+    };
+    ($ provider : ty , DRY) => {};
+    ($ provider : ty , DRY , ITER) => {
+        __impl_list_and_v1!($provider, ITER);
+    };
+}
+#[doc(inline)]
+pub use __impl_list_and_v1 as impl_list_and_v1;
diff --git a/compiler/rustc_baked_icu_data/src/data/macros.rs b/compiler/rustc_baked_icu_data/src/data/macros.rs
deleted file mode 100644
index bee309f9b81..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/macros.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// @generated
-/// Marks a type as a data provider. You can then use macros like
-/// `impl_core_helloworld_v1` to add implementations.
-///
-/// ```ignore
-/// struct MyProvider;
-/// const _: () = {
-///     include!("path/to/generated/macros.rs");
-///     make_provider!(MyProvider);
-///     impl_core_helloworld_v1!(MyProvider);
-/// }
-/// ```
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __make_provider {
-    ($ name : ty) => {
-        #[clippy::msrv = "1.66"]
-        impl $name {
-            #[doc(hidden)]
-            #[allow(dead_code)]
-            pub const MUST_USE_MAKE_PROVIDER_MACRO: () = ();
-        }
-    };
-}
-#[doc(inline)]
-pub use __make_provider as make_provider;
-#[macro_use]
-#[path = "macros/fallback_likelysubtags_v1.data.rs"]
-mod fallback_likelysubtags_v1;
-#[doc(inline)]
-pub use __impl_fallback_likelysubtags_v1 as impl_fallback_likelysubtags_v1;
-#[macro_use]
-#[path = "macros/fallback_parents_v1.data.rs"]
-mod fallback_parents_v1;
-#[doc(inline)]
-pub use __impl_fallback_parents_v1 as impl_fallback_parents_v1;
-#[macro_use]
-#[path = "macros/fallback_supplement_co_v1.data.rs"]
-mod fallback_supplement_co_v1;
-#[doc(inline)]
-pub use __impl_fallback_supplement_co_v1 as impl_fallback_supplement_co_v1;
-#[macro_use]
-#[path = "macros/list_and_v1.data.rs"]
-mod list_and_v1;
-#[doc(inline)]
-pub use __impl_list_and_v1 as impl_list_and_v1;
diff --git a/compiler/rustc_baked_icu_data/src/data/macros/fallback_likelysubtags_v1.data.rs b/compiler/rustc_baked_icu_data/src/data/macros/fallback_likelysubtags_v1.data.rs
deleted file mode 100644
index 1adb58743f7..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/macros/fallback_likelysubtags_v1.data.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// @generated
-/// Implement `DataProvider<LocaleFallbackLikelySubtagsV1Marker>` on the given struct using the data
-/// hardcoded in this file. This allows the struct to be used with
-/// `icu`'s `_unstable` constructors.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __impl_fallback_likelysubtags_v1 {
-    ($ provider : ty) => {
-        #[clippy::msrv = "1.66"]
-        const _: () = <$provider>::MUST_USE_MAKE_PROVIDER_MACRO;
-        #[clippy::msrv = "1.66"]
-        impl $provider {
-            #[doc(hidden)]
-            pub const SINGLETON_FALLBACK_LIKELYSUBTAGS_V1: &'static <icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker as icu_provider::DataMarker>::Yokeable = &icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1 {
-                l2s: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"am\0ar\0as\0be\0bg\0bgcbhobn\0brxchrcv\0doiel\0fa\0gu\0he\0hi\0hy\0ja\0ka\0kk\0km\0kn\0ko\0kokks\0ky\0lo\0maimk\0ml\0mn\0mnimr\0my\0ne\0or\0pa\0ps\0rajru\0sa\0satsd\0si\0sr\0ta\0te\0tg\0th\0ti\0tt\0uk\0ur\0yuezh\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"EthiArabBengCyrlCyrlDevaDevaBengDevaCherCyrlDevaGrekArabGujrHebrDevaArmnJpanGeorCyrlKhmrKndaKoreDevaArabCyrlLaooDevaCyrlMlymCyrlBengDevaMymrDevaOryaGuruArabDevaCyrlDevaOlckArabSinhCyrlTamlTeluCyrlThaiEthiCyrlCyrlArabHantHans") })
-                },
-                lr2s: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap2d::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"az\0ha\0kk\0ky\0mn\0ms\0pa\0sd\0sr\0tg\0uz\0yuezh\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"\x03\0\0\0\x05\0\0\0\t\0\0\0\x0B\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x0F\0\0\0\x13\0\0\0\x14\0\0\0\x16\0\0\0\x17\0\0\0&\0\0\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"IQ\0IR\0RU\0CM\0SD\0AF\0CN\0IR\0MN\0CN\0TR\0CN\0CC\0PK\0IN\0ME\0RO\0RU\0TR\0PK\0AF\0CN\0CN\0AU\0BN\0GB\0GF\0HK\0ID\0MO\0PA\0PF\0PH\0SR\0TH\0TW\0US\0VN\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"ArabArabCyrlArabArabArabArabArabArabArabLatnMongArabArabDevaLatnLatnLatnLatnArabArabCyrlHansHantHantHantHantHantHantHantHantHantHantHantHantHantHantHant") })
-                },
-                l2r: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"af\0am\0ar\0as\0astaz\0be\0bg\0bgcbhobn\0br\0brxbs\0ca\0cebchrcs\0cv\0cy\0da\0de\0doidsbel\0en\0es\0et\0eu\0fa\0ff\0fi\0filfo\0fr\0ga\0gd\0gl\0gu\0ha\0he\0hi\0hr\0hsbhu\0hy\0ia\0id\0ig\0is\0it\0ja\0jv\0ka\0keakgpkk\0km\0kn\0ko\0kokks\0ky\0lo\0lt\0lv\0maimi\0mk\0ml\0mn\0mnimr\0ms\0my\0ne\0nl\0nn\0no\0or\0pa\0pcmpl\0ps\0pt\0qu\0rajrm\0ro\0ru\0sa\0satsc\0sd\0si\0sk\0sl\0so\0sq\0sr\0su\0sv\0sw\0ta\0te\0tg\0th\0ti\0tk\0to\0tr\0tt\0uk\0ur\0uz\0vi\0wo\0xh\0yo\0yrlyuezh\0zu\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"ZA\0ET\0EG\0IN\0ES\0AZ\0BY\0BG\0IN\0IN\0BD\0FR\0IN\0BA\0ES\0PH\0US\0CZ\0RU\0GB\0DK\0DE\0IN\0DE\0GR\0US\0ES\0EE\0ES\0IR\0SN\0FI\0PH\0FO\0FR\0IE\0GB\0ES\0IN\0NG\0IL\0IN\0HR\0DE\0HU\0AM\x00001ID\0NG\0IS\0IT\0JP\0ID\0GE\0CV\0BR\0KZ\0KH\0IN\0KR\0IN\0IN\0KG\0LA\0LT\0LV\0IN\0NZ\0MK\0IN\0MN\0IN\0IN\0MY\0MM\0NP\0NL\0NO\0NO\0IN\0IN\0NG\0PL\0AF\0BR\0PE\0IN\0CH\0RO\0RU\0IN\0IN\0IT\0PK\0LK\0SK\0SI\0SO\0AL\0RS\0ID\0SE\0TZ\0IN\0IN\0TJ\0TH\0ET\0TM\0TO\0TR\0RU\0UA\0PK\0UZ\0VN\0SN\0ZA\0NG\0BR\0HK\0CN\0ZA\0") })
-                },
-                ls2r: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap2d::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"az\0en\0ff\0kk\0ky\0mn\0pa\0sd\0tg\0uz\0yuezh\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04\0\0\0\x06\0\0\0\x07\0\0\0\x08\0\0\0\x0B\0\0\0\x0C\0\0\0\r\0\0\0\x0E\0\0\0\x11\0\0\0") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"ArabShawAdlmArabArabLatnMongArabDevaKhojSindArabArabHansBopoHanbHant") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"IR\0GB\0GN\0CN\0CN\0TR\0CN\0PK\0IN\0IN\0IN\0PK\0AF\0CN\0TW\0TW\0TW\0") })
-                },
-            };
-        }
-        #[clippy::msrv = "1.66"]
-        impl icu_provider::DataProvider<icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker> for $provider {
-            fn load(&self, req: icu_provider::DataRequest) -> Result<icu_provider::DataResponse<icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker>, icu_provider::DataError> {
-                if req.locale.is_empty() { Ok(icu_provider::DataResponse { payload: Some(icu_provider::DataPayload::from_static_ref(Self::SINGLETON_FALLBACK_LIKELYSUBTAGS_V1)), metadata: Default::default() }) } else { Err(icu_provider::DataErrorKind::ExtraneousLocale.with_req(<icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker as icu_provider::KeyedDataMarker>::KEY, req)) }
-            }
-        }
-    };
-}
diff --git a/compiler/rustc_baked_icu_data/src/data/macros/fallback_parents_v1.data.rs b/compiler/rustc_baked_icu_data/src/data/macros/fallback_parents_v1.data.rs
deleted file mode 100644
index 6f8d6590b08..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/macros/fallback_parents_v1.data.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// @generated
-/// Implement `DataProvider<LocaleFallbackParentsV1Marker>` on the given struct using the data
-/// hardcoded in this file. This allows the struct to be used with
-/// `icu`'s `_unstable` constructors.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __impl_fallback_parents_v1 {
-    ($ provider : ty) => {
-        #[clippy::msrv = "1.66"]
-        const _: () = <$provider>::MUST_USE_MAKE_PROVIDER_MACRO;
-        #[clippy::msrv = "1.66"]
-        impl $provider {
-            #[doc(hidden)]
-            pub const SINGLETON_FALLBACK_PARENTS_V1: &'static <icu_locid_transform::provider::LocaleFallbackParentsV1Marker as icu_provider::DataMarker>::Yokeable = &icu_locid_transform::provider::LocaleFallbackParentsV1 {
-                parents: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap::from_parts_unchecked(unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x84\0\0\0\0\0\x06\0\x0B\0\x10\0\x15\0\x1A\0\x1F\0$\0)\0.\x003\08\0=\0B\0G\0L\0Q\0V\0[\0`\0e\0j\0o\0t\0y\0~\0\x83\0\x88\0\x8D\0\x92\0\x97\0\x9C\0\xA1\0\xA6\0\xAB\0\xB0\0\xB5\0\xBA\0\xBF\0\xC4\0\xC9\0\xCE\0\xD3\0\xD8\0\xDD\0\xE2\0\xE7\0\xEC\0\xF1\0\xF6\0\xFB\0\0\x01\x05\x01\n\x01\x0F\x01\x14\x01\x19\x01\x1E\x01#\x01(\x01-\x012\x017\x01<\x01A\x01F\x01K\x01P\x01U\x01Z\x01_\x01d\x01i\x01n\x01s\x01x\x01}\x01\x82\x01\x87\x01\x8C\x01\x91\x01\x96\x01\x9B\x01\xA0\x01\xA5\x01\xAA\x01\xAF\x01\xB4\x01\xB9\x01\xBE\x01\xC3\x01\xC8\x01\xCD\x01\xD2\x01\xD7\x01\xDC\x01\xE1\x01\xE6\x01\xEB\x01\xF0\x01\xF5\x01\xFA\x01\xFF\x01\x04\x02\t\x02\x0E\x02\x13\x02\x18\x02\x1D\x02\"\x02'\x02,\x021\x026\x02;\x02@\x02G\x02I\x02K\x02M\x02R\x02W\x02\\\x02a\x02f\x02k\x02p\x02u\x02z\x02\x7F\x02\x84\x02\x89\x02en-150en-AGen-AIen-ATen-AUen-BBen-BEen-BMen-BSen-BWen-BZen-CCen-CHen-CKen-CMen-CXen-CYen-DEen-DGen-DKen-DMen-ERen-FIen-FJen-FKen-FMen-GBen-GDen-GGen-GHen-GIen-GMen-GYen-HKen-IEen-ILen-IMen-INen-IOen-JEen-JMen-KEen-KIen-KNen-KYen-LCen-LRen-LSen-MGen-MOen-MSen-MTen-MUen-MVen-MWen-MYen-NAen-NFen-NGen-NLen-NRen-NUen-NZen-PGen-PKen-PNen-PWen-RWen-SBen-SCen-SDen-SEen-SGen-SHen-SIen-SLen-SSen-SXen-SZen-TCen-TKen-TOen-TTen-TVen-TZen-UGen-VCen-VGen-VUen-WSen-ZAen-ZMen-ZWes-ARes-BOes-BRes-BZes-CLes-COes-CRes-CUes-DOes-ECes-GTes-HNes-MXes-NIes-PAes-PEes-PRes-PYes-SVes-USes-UYes-VEhi-Latnhtnbnnno-NOpt-AOpt-CHpt-CVpt-FRpt-GQpt-GWpt-LUpt-MOpt-MZpt-STpt-TLzh-Hant-MO") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01150en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001en\0\0\0\0\0\0\x01001es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419es\0\0\0\0\0\0\x01419en\0\0\0\0\0\0\x01IN\0fr\0\0\0\0\0\0\x01HT\0no\0\0\0\0\0\0\0\0\0\0no\0\0\0\0\0\0\0\0\0\0no\0\0\0\0\0\0\0\0\0\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0pt\0\0\0\0\0\0\x01PT\0zh\0\x01Hant\x01HK\0") })
-                },
-            };
-        }
-        #[clippy::msrv = "1.66"]
-        impl icu_provider::DataProvider<icu_locid_transform::provider::LocaleFallbackParentsV1Marker> for $provider {
-            fn load(&self, req: icu_provider::DataRequest) -> Result<icu_provider::DataResponse<icu_locid_transform::provider::LocaleFallbackParentsV1Marker>, icu_provider::DataError> {
-                if req.locale.is_empty() { Ok(icu_provider::DataResponse { payload: Some(icu_provider::DataPayload::from_static_ref(Self::SINGLETON_FALLBACK_PARENTS_V1)), metadata: Default::default() }) } else { Err(icu_provider::DataErrorKind::ExtraneousLocale.with_req(<icu_locid_transform::provider::LocaleFallbackParentsV1Marker as icu_provider::KeyedDataMarker>::KEY, req)) }
-            }
-        }
-    };
-}
diff --git a/compiler/rustc_baked_icu_data/src/data/macros/fallback_supplement_co_v1.data.rs b/compiler/rustc_baked_icu_data/src/data/macros/fallback_supplement_co_v1.data.rs
deleted file mode 100644
index 02eec37ee09..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/macros/fallback_supplement_co_v1.data.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// @generated
-/// Implement `DataProvider<CollationFallbackSupplementV1Marker>` on the given struct using the data
-/// hardcoded in this file. This allows the struct to be used with
-/// `icu`'s `_unstable` constructors.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __impl_fallback_supplement_co_v1 {
-    ($ provider : ty) => {
-        #[clippy::msrv = "1.66"]
-        const _: () = <$provider>::MUST_USE_MAKE_PROVIDER_MACRO;
-        #[clippy::msrv = "1.66"]
-        impl $provider {
-            #[doc(hidden)]
-            pub const SINGLETON_FALLBACK_SUPPLEMENT_CO_V1: &'static <icu_locid_transform::provider::CollationFallbackSupplementV1Marker as icu_provider::DataMarker>::Yokeable = &icu_locid_transform::provider::LocaleFallbackSupplementV1 {
-                parents: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap::from_parts_unchecked(unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0yue") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"zh\0\x01Hant\0\0\0\0") })
-                },
-                unicode_extension_defaults: unsafe {
-                    #[allow(unused_unsafe)]
-                    zerovec::ZeroMap2d::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"co") }, unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"\x02\0\0\0") }, unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\x02\0zhzh-Hant") }, unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\x06\0pinyinstroke") })
-                },
-            };
-        }
-        #[clippy::msrv = "1.66"]
-        impl icu_provider::DataProvider<icu_locid_transform::provider::CollationFallbackSupplementV1Marker> for $provider {
-            fn load(&self, req: icu_provider::DataRequest) -> Result<icu_provider::DataResponse<icu_locid_transform::provider::CollationFallbackSupplementV1Marker>, icu_provider::DataError> {
-                if req.locale.is_empty() { Ok(icu_provider::DataResponse { payload: Some(icu_provider::DataPayload::from_static_ref(Self::SINGLETON_FALLBACK_SUPPLEMENT_CO_V1)), metadata: Default::default() }) } else { Err(icu_provider::DataErrorKind::ExtraneousLocale.with_req(<icu_locid_transform::provider::CollationFallbackSupplementV1Marker as icu_provider::KeyedDataMarker>::KEY, req)) }
-            }
-        }
-    };
-}
diff --git a/compiler/rustc_baked_icu_data/src/data/macros/list_and_v1.data.rs b/compiler/rustc_baked_icu_data/src/data/macros/list_and_v1.data.rs
deleted file mode 100644
index 186f706cdb2..00000000000
--- a/compiler/rustc_baked_icu_data/src/data/macros/list_and_v1.data.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// @generated
-/// Implement `DataProvider<AndListV1Marker>` on the given struct using the data
-/// hardcoded in this file. This allows the struct to be used with
-/// `icu`'s `_unstable` constructors.
-#[doc(hidden)]
-#[macro_export]
-macro_rules! __impl_list_and_v1 {
-    ($ provider : ty) => {
-        #[clippy::msrv = "1.66"]
-        const _: () = <$provider>::MUST_USE_MAKE_PROVIDER_MACRO;
-        #[clippy::msrv = "1.66"]
-        impl icu_provider::DataProvider<icu_list::provider::AndListV1Marker> for $provider {
-            fn load(&self, req: icu_provider::DataRequest) -> Result<icu_provider::DataResponse<icu_list::provider::AndListV1Marker>, icu_provider::DataError> {
-                static EN_001: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static EN_IN: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", and ", 6u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static IT: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }]);
-                static PT: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static FR: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" et ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static TR: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" ve ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static ES: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" y ", 3u8), special_case: Some(icu_list::provider::SpecialCasePattern { condition: unsafe { icu_list::provider::SerdeDFA::from_dfa_bytes_unchecked(if cfg!(target_endian = "little") { b"rust-regex-automata-dfa-sparse\0\0\xFF\xFE\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B(\x01\0\0\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#\0\0\0" } else { b"rust-regex-automata-dfa-sparse\0\0\0\0\xFE\xFF\0\0\0\x02\0\0\0\0\0\0\0\x0E\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x02\x02\x02\x03\x04\x04\x05\x06\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x08\t\t\t\n\x0B\x0B\x0C\r\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0E\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12\x12\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x13\x14\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x16\x17\x17\x18\x19\x19\x19\x1A\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\x1B\0\0\x01(\x01\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x01\x80\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\x05\0\x05\x05\x06\x06\x0C\x0C\r\r\0\0S\0\0\0D\0\0\0S\0\0\0D\0\0\0\0\0\0\0\0\x02\0\0\x1B\0\0\x12\0\0\0\x12\0\0\0\0\x03\0\x06\x06\r\r\0\0h\0\0\0h\0\0\0\0\0\0\0\0\x0E\0\0\0\x02\x02\x04\x07\t\t\x0B\x0E\x13\x13\x14\x14\x15\x15\x16\x16\x17\x17\x18\x18\x19\x19\x1A\x1A\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0D\0\0\0\xBF\0\0\0\xCE\0\0\0\xDD\0\0\0\xEC\0\0\0\xDD\0\0\0\xFB\0\0\0\n\x01\0\0\x19\x01\0\0\x12\0\0\0\0\x02\0\x0F\x11\0\0D\0\0\0\0\0\0\0\0\x02\0\x11\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x0F\x10\0\0\xBF\0\0\0\0\0\0\0\0\x02\0\x10\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x11\0\0\xDD\0\0\0\0\0\0\0\0\x02\0\x0F\x0F\0\0\xDD\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0#\0\0\0#\0\0\0#\0\0\0#\0\0\0\0\0\0#\0\0\0\t\0\0\0\x12\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0#\0\0\0#" }) }, pattern: icu_list::provider::ListJoinerPattern::from_parts(" e ", 3u8) }) }]);
-                static RU: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" и ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static UND: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static EN: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", and ", 6u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" and ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", & ", 4u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" & ", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }]);
-                static HI_LATN: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", aur ", 6u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" aur ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", aur ", 6u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" aur ", 5u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(", ", 2u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts(" aur ", 5u8), special_case: None }]);
-                static JA: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }]);
-                static ZH_HK: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("及", 3u8), special_case: None }]);
-                static ZH: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }]);
-                static ZH_HANT: <icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable = icu_list::provider::ListFormatterPatternsV1([icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("、", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }, icu_list::provider::ConditionalListJoinerPattern { default: icu_list::provider::ListJoinerPattern::from_parts("和", 3u8), special_case: None }]);
-                static VALUES: [&<icu_list::provider::AndListV1Marker as icu_provider::DataMarker>::Yokeable; 215usize] = [&EN, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_IN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN, &EN_001, &EN_001, &EN_001, &EN_001, &EN_001, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &ES, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &FR, &HI_LATN, &IT, &IT, &IT, &IT, &JA, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &PT, &RU, &RU, &RU, &RU, &RU, &RU, &TR, &TR, &UND, &ZH, &ZH_HK, &ZH, &ZH, &ZH, &ZH_HANT, &ZH_HK, &ZH];
-                static KEYS: [&str; 215usize] = ["en", "en-001", "en-150", "en-AE", "en-AG", "en-AI", "en-AS", "en-AT", "en-AU", "en-BB", "en-BE", "en-BI", "en-BM", "en-BS", "en-BW", "en-BZ", "en-CA", "en-CC", "en-CH", "en-CK", "en-CM", "en-CX", "en-CY", "en-DE", "en-DG", "en-DK", "en-DM", "en-ER", "en-FI", "en-FJ", "en-FK", "en-FM", "en-GB", "en-GD", "en-GG", "en-GH", "en-GI", "en-GM", "en-GU", "en-GY", "en-HK", "en-IE", "en-IL", "en-IM", "en-IN", "en-IO", "en-JE", "en-JM", "en-KE", "en-KI", "en-KN", "en-KY", "en-LC", "en-LR", "en-LS", "en-MG", "en-MH", "en-MO", "en-MP", "en-MS", "en-MT", "en-MU", "en-MV", "en-MW", "en-MY", "en-NA", "en-NF", "en-NG", "en-NL", "en-NR", "en-NU", "en-NZ", "en-PG", "en-PH", "en-PK", "en-PN", "en-PR", "en-PW", "en-RW", "en-SB", "en-SC", "en-SD", "en-SE", "en-SG", "en-SH", "en-SI", "en-SL", "en-SS", "en-SX", "en-SZ", "en-TC", "en-TK", "en-TO", "en-TT", "en-TV", "en-TZ", "en-UG", "en-UM", "en-VC", "en-VG", "en-VI", "en-VU", "en-WS", "en-ZA", "en-ZM", "en-ZW", "es", "es-419", "es-AR", "es-BO", "es-BR", "es-BZ", "es-CL", "es-CO", "es-CR", "es-CU", "es-DO", "es-EA", "es-EC", "es-GQ", "es-GT", "es-HN", "es-IC", "es-MX", "es-NI", "es-PA", "es-PE", "es-PH", "es-PR", "es-PY", "es-SV", "es-US", "es-UY", "es-VE", "fr", "fr-BE", "fr-BF", "fr-BI", "fr-BJ", "fr-BL", "fr-CA", "fr-CD", "fr-CF", "fr-CG", "fr-CH", "fr-CI", "fr-CM", "fr-DJ", "fr-DZ", "fr-GA", "fr-GF", "fr-GN", "fr-GP", "fr-GQ", "fr-HT", "fr-KM", "fr-LU", "fr-MA", "fr-MC", "fr-MF", "fr-MG", "fr-ML", "fr-MQ", "fr-MR", "fr-MU", "fr-NC", "fr-NE", "fr-PF", "fr-PM", "fr-RE", "fr-RW", "fr-SC", "fr-SN", "fr-SY", "fr-TD", "fr-TG", "fr-TN", "fr-VU", "fr-WF", "fr-YT", "hi-Latn", "it", "it-CH", "it-SM", "it-VA", "ja", "pt", "pt-AO", "pt-CH", "pt-CV", "pt-GQ", "pt-GW", "pt-LU", "pt-MO", "pt-MZ", "pt-PT", "pt-ST", "pt-TL", "ru", "ru-BY", "ru-KG", "ru-KZ", "ru-MD", "ru-UA", "tr", "tr-CY", "und", "zh", "zh-HK", "zh-Hans", "zh-Hans-HK", "zh-Hans-MO", "zh-Hant", "zh-MO", "zh-SG"];
-                if let Ok(payload) = KEYS.binary_search_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).map(|i| *unsafe { VALUES.get_unchecked(i) }) { Ok(icu_provider::DataResponse { payload: Some(icu_provider::DataPayload::from_static_ref(payload)), metadata: Default::default() }) } else { Err(icu_provider::DataErrorKind::MissingLocale.with_req(<icu_list::provider::AndListV1Marker as icu_provider::KeyedDataMarker>::KEY, req)) }
-            }
-        }
-    };
-}
diff --git a/compiler/rustc_baked_icu_data/src/data/mod.rs b/compiler/rustc_baked_icu_data/src/data/mod.rs
index 465689f0cb8..3146188a8e7 100644
--- a/compiler/rustc_baked_icu_data/src/data/mod.rs
+++ b/compiler/rustc_baked_icu_data/src/data/mod.rs
@@ -1,31 +1,40 @@
 // @generated
-include!("macros.rs");
-macro_rules! impl_data_provider {
-    ($ provider : ty) => {
-        make_provider!($provider);
-        impl_fallback_likelysubtags_v1!($provider);
-        impl_fallback_parents_v1!($provider);
-        impl_fallback_supplement_co_v1!($provider);
-        impl_list_and_v1!($provider);
+include!("list_and_v1.rs.data");
+/// Marks a type as a data provider. You can then use macros like
+/// `impl_core_helloworld_v1` to add implementations.
+///
+/// ```ignore
+/// struct MyProvider;
+/// const _: () = {
+///     include!("path/to/generated/macros.rs");
+///     make_provider!(MyProvider);
+///     impl_core_helloworld_v1!(MyProvider);
+/// }
+/// ```
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __make_provider {
+    ($ name : ty) => {
+        #[clippy::msrv = "1.82"]
+        impl $name {
+            #[allow(dead_code)]
+            pub(crate) const MUST_USE_MAKE_PROVIDER_MACRO: () = ();
+        }
+        icu_provider::marker::impl_data_provider_never_marker!($name);
     };
 }
+#[doc(inline)]
+pub use __make_provider as make_provider;
+/// This macro requires the following crates:
+/// * `icu_list`
+/// * `icu_locale/compiled_data`
+/// * `icu_provider`
+/// * `icu_provider/baked`
+/// * `zerovec`
 #[allow(unused_macros)]
-macro_rules! impl_any_provider {
+macro_rules! impl_data_provider {
     ($ provider : ty) => {
-        #[clippy::msrv = "1.66"]
-        impl icu_provider::AnyProvider for $provider {
-            fn load_any(&self, key: icu_provider::DataKey, req: icu_provider::DataRequest) -> Result<icu_provider::AnyResponse, icu_provider::DataError> {
-                match key.hashed() {
-                    h if h == <icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker as icu_provider::KeyedDataMarker>::KEY.hashed() => icu_provider::DataProvider::<icu_locid_transform::provider::LocaleFallbackLikelySubtagsV1Marker>::load(self, req).map(icu_provider::DataResponse::wrap_into_any_response),
-                    h if h == <icu_locid_transform::provider::LocaleFallbackParentsV1Marker as icu_provider::KeyedDataMarker>::KEY.hashed() => icu_provider::DataProvider::<icu_locid_transform::provider::LocaleFallbackParentsV1Marker>::load(self, req).map(icu_provider::DataResponse::wrap_into_any_response),
-                    h if h == <icu_locid_transform::provider::CollationFallbackSupplementV1Marker as icu_provider::KeyedDataMarker>::KEY.hashed() => icu_provider::DataProvider::<icu_locid_transform::provider::CollationFallbackSupplementV1Marker>::load(self, req).map(icu_provider::DataResponse::wrap_into_any_response),
-                    h if h == <icu_list::provider::AndListV1Marker as icu_provider::KeyedDataMarker>::KEY.hashed() => icu_provider::DataProvider::<icu_list::provider::AndListV1Marker>::load(self, req).map(icu_provider::DataResponse::wrap_into_any_response),
-                    _ => Err(icu_provider::DataErrorKind::MissingDataKey.with_req(key, req)),
-                }
-            }
-        }
+        make_provider!($provider);
+        impl_list_and_v1!($provider);
     };
 }
-#[clippy::msrv = "1.66"]
-pub struct BakedDataProvider;
-impl_data_provider!(BakedDataProvider);
diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs
index f3f6522f575..ea4c8242c62 100644
--- a/compiler/rustc_baked_icu_data/src/lib.rs
+++ b/compiler/rustc_baked_icu_data/src/lib.rs
@@ -14,10 +14,9 @@
 //! To regenerate the data, run this command:
 //!
 //! ```text
-//! icu4x-datagen -W --pretty --fingerprint --use-separate-crates \
-//! --format mod -l en es fr it ja pt ru tr zh zh-Hans zh-Hant \
-//! -k list/and@1 fallback/likelysubtags@1 fallback/parents@1 fallback/supplement/co@1 \
-//! --cldr-tag latest --icuexport-tag latest -o src/data
+//! icu4x-datagen -W --pretty --use-separate-crates \
+//! --format baked --locales @en @es @fr @it @ja @pt @ru @tr @zh @zh-Hans @zh-Hant \
+//! -m ListAndV1 -o src/data
 //! ```
 
 // tidy-alphabetical-start
@@ -29,26 +28,26 @@
 // #![warn(unreachable_pub)] // don't use because this crate is mostly generated code
 // tidy-alphabetical-end
 
-mod data {
-    include!("data/mod.rs");
-    include!("data/any.rs");
-}
+pub struct BakedDataProvider;
 
-pub use data::BakedDataProvider;
+include!("data/mod.rs");
+const _: () = {
+    impl_data_provider!(BakedDataProvider);
+};
 
 pub const fn baked_data_provider() -> BakedDataProvider {
-    data::BakedDataProvider
+    BakedDataProvider
 }
 
 pub mod supported_locales {
-    pub const EN: icu_locid::Locale = icu_locid::locale!("en");
-    pub const ES: icu_locid::Locale = icu_locid::locale!("es");
-    pub const FR: icu_locid::Locale = icu_locid::locale!("fr");
-    pub const IT: icu_locid::Locale = icu_locid::locale!("it");
-    pub const JA: icu_locid::Locale = icu_locid::locale!("ja");
-    pub const PT: icu_locid::Locale = icu_locid::locale!("pt");
-    pub const RU: icu_locid::Locale = icu_locid::locale!("ru");
-    pub const TR: icu_locid::Locale = icu_locid::locale!("tr");
-    pub const ZH_HANS: icu_locid::Locale = icu_locid::locale!("zh-Hans");
-    pub const ZH_HANT: icu_locid::Locale = icu_locid::locale!("zh-Hant");
+    pub const EN: icu_locale::Locale = icu_locale::locale!("en");
+    pub const ES: icu_locale::Locale = icu_locale::locale!("es");
+    pub const FR: icu_locale::Locale = icu_locale::locale!("fr");
+    pub const IT: icu_locale::Locale = icu_locale::locale!("it");
+    pub const JA: icu_locale::Locale = icu_locale::locale!("ja");
+    pub const PT: icu_locale::Locale = icu_locale::locale!("pt");
+    pub const RU: icu_locale::Locale = icu_locale::locale!("ru");
+    pub const TR: icu_locale::Locale = icu_locale::locale!("tr");
+    pub const ZH_HANS: icu_locale::Locale = icu_locale::locale!("zh-Hans");
+    pub const ZH_HANT: icu_locale::Locale = icu_locale::locale!("zh-Hant");
 }
diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml
index 9e7d55180a2..3162e9da1ba 100644
--- a/compiler/rustc_borrowck/Cargo.toml
+++ b/compiler/rustc_borrowck/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 either = "1.5.0"
-itertools = "0.12"
+itertools.workspace = true
 polonius-engine = "0.13.0"
 rustc_abi = { path = "../rustc_abi" }
 rustc_data_structures = { path = "../rustc_data_structures" }
@@ -25,5 +25,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_traits = { path = "../rustc_traits" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index e56b9e641a1..9ca44d67150 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -30,6 +30,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 3e5a26c0556..cf563a53973 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -416,7 +416,7 @@ pub(crate) mod printf {
                         // Yes, this *is* the parameter.
                         Some(('$', end2)) => {
                             state = Flags;
-                            parameter = Some(at.slice_between(end).unwrap().parse().unwrap());
+                            parameter = at.slice_between(end).unwrap().parse().ok();
                             move_to!(end2);
                         }
                         // Wait, no, actually, it's the width.
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 2d11628250c..26d20acbe28 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -8,11 +8,11 @@ test = false
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 # To avoid duplicate dependencies, this should match the version of gimli used
 # by `rustc_codegen_ssa` via its `thorin-dwp` dependency.
 gimli = "0.31"
-itertools = "0.12"
+itertools.workspace = true
 libc = "0.2"
 measureme = "12.0.1"
 object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
@@ -40,7 +40,7 @@ rustc_target = { path = "../rustc_target" }
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index 399f8b6e762..ac7583f5666 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -44,7 +44,7 @@ const ABI_AFFECTING_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 1] =
 
 const OPTIMIZATION_ATTRIBUTES: [(ArgAttribute, llvm::AttributeKind); 6] = [
     (ArgAttribute::NoAlias, llvm::AttributeKind::NoAlias),
-    (ArgAttribute::NoCapture, llvm::AttributeKind::NoCapture),
+    (ArgAttribute::CapturesAddress, llvm::AttributeKind::CapturesAddress),
     (ArgAttribute::NonNull, llvm::AttributeKind::NonNull),
     (ArgAttribute::ReadOnly, llvm::AttributeKind::ReadOnly),
     (ArgAttribute::NoUndef, llvm::AttributeKind::NoUndef),
@@ -84,8 +84,10 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
         }
         for (attr, llattr) in OPTIMIZATION_ATTRIBUTES {
             if regular.contains(attr) {
-                // captures(address, read_provenance) is only available since LLVM 21.
-                if attr == ArgAttribute::CapturesReadOnly && llvm_util::get_version() < (21, 0, 0) {
+                // captures(...) is only available since LLVM 21.
+                if (attr == ArgAttribute::CapturesReadOnly || attr == ArgAttribute::CapturesAddress)
+                    && llvm_util::get_version() < (21, 0, 0)
+                {
                     continue;
                 }
                 attrs.push(llattr.create_attr(cx.llcx));
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 7c79cba2273..ba590851dbd 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -263,7 +263,7 @@ pub(crate) enum AttributeKind {
     MinSize = 4,
     Naked = 5,
     NoAlias = 6,
-    NoCapture = 7,
+    CapturesAddress = 7,
     NoInline = 8,
     NonNull = 9,
     NoRedZone = 10,
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 6a8971de746..6b989a96488 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -6,12 +6,12 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 ar_archive_writer = "0.4.2"
-bitflags = "2.4.1"
+bitflags.workspace = true
 bstr = "1.11.3"
 # `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version
 # per crate", so if you change this, you need to also change it in `rustc_llvm`.
 cc = "=1.2.16"
-itertools = "0.12"
+itertools.workspace = true
 pathdiff = "0.2.0"
 regex = "1.4"
 rustc_abi = { path = "../rustc_abi" }
@@ -40,9 +40,9 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
 serde_json = "1.0.59"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tempfile = "3.2"
-thin-vec = "0.2.12"
+thin-vec.workspace = true
 thorin-dwp = "0.9"
-tracing = "0.1"
+tracing.workspace = true
 wasm-encoder = "0.219"
 # tidy-alphabetical-end
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index c3777f64e9e..19c919c0e4e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -14,11 +14,13 @@ use itertools::Itertools;
 use regex::Regex;
 use rustc_arena::TypedArena;
 use rustc_ast::CRATE_NODE_ID;
+use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{DiagCtxtHandle, LintDiagnostic};
 use rustc_fs_util::{TempDirBuilder, fix_windows_verbatim_for_gcc, try_canonicalize};
+use rustc_hir::attrs::NativeLibKind;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_macros::LintDiagnostic;
 use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
@@ -38,7 +40,6 @@ use rustc_session::config::{
 use rustc_session::lint::builtin::LINKER_MESSAGES;
 use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
 use rustc_session::search_paths::PathKind;
-use rustc_session::utils::NativeLibKind;
 /// For all the linkers we support, and information they might
 /// need out of the shared crate context before we get rid of it.
 use rustc_session::{Session, filesearch};
@@ -3019,7 +3020,9 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
 
 fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
     match lib.cfg {
-        Some(ref cfg) => rustc_attr_parsing::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
+        Some(ref cfg) => {
+            eval_config_entry(sess, cfg, CRATE_NODE_ID, None, ShouldEmit::ErrorsAndLints).as_bool()
+        }
         None => true,
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
index 509168b2cd2..9f42991d4c0 100644
--- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
@@ -7,9 +7,9 @@ use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_hashes::Hash128;
+use rustc_hir::attrs::NativeLibKind;
 use rustc_session::Session;
 use rustc_session::cstore::DllImport;
-use rustc_session::utils::NativeLibKind;
 use rustc_span::Symbol;
 
 use crate::back::archive::ImportLibraryItem;
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 9f22859ba81..92582dcc399 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -138,23 +138,12 @@ impl ModuleConfig {
 
         let emit_obj = if !should_emit_obj {
             EmitObj::None
-        } else if sess.target.obj_is_bitcode
-            || (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
-        {
+        } else if sess.target.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled() {
             // This case is selected if the target uses objects as bitcode, or
             // if linker plugin LTO is enabled. In the linker plugin LTO case
             // the assumption is that the final link-step will read the bitcode
             // and convert it to object code. This may be done by either the
             // native linker or rustc itself.
-            //
-            // Note, however, that the linker-plugin-lto requested here is
-            // explicitly ignored for `#![no_builtins]` crates. These crates are
-            // specifically ignored by rustc's LTO passes and wouldn't work if
-            // loaded into the linker. These crates define symbols that LLVM
-            // lowers intrinsics to, and these symbol dependencies aren't known
-            // until after codegen. As a result any crate marked
-            // `#![no_builtins]` is assumed to not participate in LTO and
-            // instead goes on to generate object code.
             EmitObj::Bitcode
         } else if need_bitcode_in_object(tcx) {
             EmitObj::ObjectCode(BitcodeSection::Full)
@@ -1957,10 +1946,13 @@ impl<B: ExtraBackendMethods> Drop for Coordinator<B> {
 pub struct OngoingCodegen<B: ExtraBackendMethods> {
     pub backend: B,
     pub crate_info: CrateInfo,
-    pub codegen_worker_receive: Receiver<CguMessage>,
-    pub shared_emitter_main: SharedEmitterMain,
     pub output_filenames: Arc<OutputFilenames>,
+    // Field order below is intended to terminate the coordinator thread before two fields below
+    // drop and prematurely close channels used by coordinator thread. See `Coordinator`'s
+    // `Drop` implementation for more info.
     pub coordinator: Coordinator<B>,
+    pub codegen_worker_receive: Receiver<CguMessage>,
+    pub shared_emitter_main: SharedEmitterMain,
 }
 
 impl<B: ExtraBackendMethods> OngoingCodegen<B> {
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index a6fd6c763ed..08e2f355953 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -1,10 +1,11 @@
 #![allow(non_camel_case_types)]
 
 use rustc_hir::LangItem;
+use rustc_hir::attrs::PeImportNameType;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{self, Instance, TyCtxt};
 use rustc_middle::{bug, mir, span_bug};
-use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
+use rustc_session::cstore::{DllCallingConvention, DllImport};
 use rustc_span::Span;
 use rustc_target::spec::Target;
 
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 23ed387a3ff..fe0500a5d4c 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -25,10 +25,10 @@ use std::io;
 use std::path::{Path, PathBuf};
 use std::sync::Arc;
 
-use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::unord::UnordMap;
 use rustc_hir::CRATE_HIR_ID;
+use rustc_hir::attrs::{CfgEntry, NativeLibKind};
 use rustc_hir::def_id::CrateNum;
 use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_metadata::EncodedMetadata;
@@ -45,7 +45,6 @@ use rustc_session::Session;
 use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
 use rustc_session::cstore::{self, CrateSource};
 use rustc_session::lint::builtin::LINKER_MESSAGES;
-use rustc_session::utils::NativeLibKind;
 use rustc_span::Symbol;
 
 pub mod assert_module_sources;
@@ -187,7 +186,7 @@ pub struct NativeLib {
     pub kind: NativeLibKind,
     pub name: Symbol,
     pub filename: Option<Symbol>,
-    pub cfg: Option<ast::MetaItemInner>,
+    pub cfg: Option<CfgEntry>,
     pub verbatim: bool,
     pub dll_imports: Vec<cstore::DllImport>,
 }
diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml
index 51dcee8d882..88dfc83f7fc 100644
--- a/compiler/rustc_const_eval/Cargo.toml
+++ b/compiler/rustc_const_eval/Cargo.toml
@@ -22,5 +22,5 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 17204883fb0..0ac9e02508a 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -6,13 +6,14 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 arrayvec = { version = "0.7", default-features = false }
-bitflags = "2.4.1"
+bitflags.workspace = true
 either = "1.0"
 elsa = "1.11.0"
 ena = "0.14.3"
 indexmap = "2.4.0"
 jobserver_crate = { version = "0.1.28", package = "jobserver" }
 measureme = "12.0.1"
+parking_lot = "0.12"
 rustc-hash = "2.0.0"
 rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
 rustc_arena = { path = "../rustc_arena" }
@@ -25,8 +26,8 @@ rustc_thread_pool = { path = "../rustc_thread_pool" }
 smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] }
 stacker = "0.1.17"
 tempfile = "3.2"
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [dependencies.hashbrown]
@@ -34,9 +35,6 @@ version = "0.15.2"
 default-features = false
 features = ["nightly"] # for may_dangle
 
-[dependencies.parking_lot]
-version = "0.12"
-
 [target.'cfg(windows)'.dependencies.windows]
 version = "0.61.0"
 features = [
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index ae1dbd2cf51..7e9af054aff 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -51,7 +51,7 @@ rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
 serde_json = "1.0.59"
 shlex = "1.0"
-tracing = { version = "0.1.35" }
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [target.'cfg(all(unix, any(target_env = "gnu", target_os = "macos")))'.dependencies]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0458.md b/compiler/rustc_error_codes/src/error_codes/E0458.md
index 1b280cba44f..651bc378879 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0458.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0458.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 An unknown "kind" was specified for a link attribute.
 
 Erroneous code example:
 
-```compile_fail,E0458
+```ignore (no longer emitted)
 #[link(kind = "wonderful_unicorn")] extern "C" {}
 // error: unknown kind: `wonderful_unicorn`
 ```
diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml
index 552ad672752..7d2dc20e136 100644
--- a/compiler/rustc_error_messages/Cargo.toml
+++ b/compiler/rustc_error_messages/Cargo.toml
@@ -7,9 +7,8 @@ edition = "2024"
 # tidy-alphabetical-start
 fluent-bundle = "0.16"
 fluent-syntax = "0.12"
-icu_list = "1.2"
-icu_locid = "1.2"
-icu_provider_adapters = "1.2"
+icu_list = { version = "2.0", default-features = false, features = ["alloc"] }
+icu_locale = { version = "2.0", default-features = false }
 intl-memoizer = "0.5.1"
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
@@ -18,6 +17,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
-tracing = "0.1"
+tracing.workspace = true
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index d8bacbe762b..7b7843f6cf3 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -15,7 +15,6 @@ use fluent_bundle::FluentResource;
 pub use fluent_bundle::types::FluentType;
 pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
 use fluent_syntax::parser::ParserError;
-use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
 use intl_memoizer::concurrent::IntlLangMemoizer;
 use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
 use rustc_macros::{Decodable, Encodable};
@@ -515,8 +514,8 @@ impl From<Vec<Span>> for MultiSpan {
     }
 }
 
-fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locid::Locale> {
-    icu_locid::Locale::try_from_bytes(lang.to_string().as_bytes()).ok()
+fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locale::Locale> {
+    icu_locale::Locale::try_from_str(&lang.to_string()).ok()
 }
 
 pub fn fluent_value_from_str_list_sep_by_and(l: Vec<Cow<'_, str>>) -> FluentValue<'_> {
@@ -568,21 +567,15 @@ pub fn fluent_value_from_str_list_sep_by_and(l: Vec<Cow<'_, str>>) -> FluentValu
         where
             Self: Sized,
         {
-            let baked_data_provider = rustc_baked_icu_data::baked_data_provider();
-            let locale_fallbacker =
-                LocaleFallbacker::try_new_with_any_provider(&baked_data_provider)
-                    .expect("Failed to create fallback provider");
-            let data_provider =
-                LocaleFallbackProvider::new_with_fallbacker(baked_data_provider, locale_fallbacker);
             let locale = icu_locale_from_unic_langid(lang)
                 .unwrap_or_else(|| rustc_baked_icu_data::supported_locales::EN);
-            let list_formatter =
-                icu_list::ListFormatter::try_new_and_with_length_with_any_provider(
-                    &data_provider,
-                    &locale.into(),
-                    icu_list::ListLength::Wide,
-                )
-                .expect("Failed to create list formatter");
+            let list_formatter = icu_list::ListFormatter::try_new_and_unstable(
+                &rustc_baked_icu_data::BakedDataProvider,
+                locale.into(),
+                icu_list::options::ListFormatterOptions::default()
+                    .with_length(icu_list::options::ListLength::Wide),
+            )
+            .expect("Failed to create list formatter");
 
             Ok(MemoizableListFormatter(list_formatter))
         }
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 7912b8e6098..f5853855673 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -24,7 +24,7 @@ serde = { version = "1.0.125", features = ["derive"] }
 serde_json = "1.0.59"
 termcolor = "1.2.0"
 termize = "0.2"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [target.'cfg(windows)'.dependencies.windows]
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 749bba5de12..b94370e8e9b 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1462,7 +1462,7 @@ impl HumanEmitter {
         max_line_num_len: usize,
         is_secondary: bool,
         is_cont: bool,
-    ) -> io::Result<()> {
+    ) -> io::Result<CodeWindowStatus> {
         let mut buffer = StyledBuffer::new();
 
         if !msp.has_primary_spans() && !msp.has_span_labels() && is_secondary && !self.short_message
@@ -1575,12 +1575,14 @@ impl HumanEmitter {
         }
         let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp);
         trace!("{annotated_files:#?}");
+        let mut code_window_status = CodeWindowStatus::Open;
 
         // Make sure our primary file comes first
         let primary_span = msp.primary_span().unwrap_or_default();
         let (Some(sm), false) = (self.sm.as_ref(), primary_span.is_dummy()) else {
             // If we don't have span information, emit and exit
-            return emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message);
+            return emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)
+                .map(|_| code_window_status);
         };
         let primary_lo = sm.lookup_char_pos(primary_span.lo());
         if let Ok(pos) =
@@ -1589,6 +1591,9 @@ impl HumanEmitter {
             annotated_files.swap(0, pos);
         }
 
+        // An end column separator should be emitted when a file with with a
+        // source, is followed by one without a source
+        let mut col_sep_before_no_show_source = false;
         let annotated_files_len = annotated_files.len();
         // Print out the annotate source lines that correspond with the error
         for (file_idx, annotated_file) in annotated_files.into_iter().enumerate() {
@@ -1599,6 +1604,26 @@ impl HumanEmitter {
                 &annotated_file.file,
             ) {
                 if !self.short_message {
+                    // Add an end column separator when a file without a source
+                    // comes after one with a source
+                    //    ╭▸ $DIR/deriving-meta-unknown-trait.rs:1:10
+                    //    │
+                    // LL │ #[derive(Eqr)]
+                    //    │          ━━━
+                    //    ╰╴ (<- It prints *this* line)
+                    //    ╭▸ $SRC_DIR/core/src/cmp.rs:356:0
+                    //    │
+                    //    ╰╴note: similarly named derive macro `Eq` defined here
+                    if col_sep_before_no_show_source {
+                        let buffer_msg_line_offset = buffer.num_lines();
+                        self.draw_col_separator_end(
+                            &mut buffer,
+                            buffer_msg_line_offset,
+                            max_line_num_len + 1,
+                        );
+                    }
+                    col_sep_before_no_show_source = false;
+
                     // We'll just print an unannotated message.
                     for (annotation_id, line) in annotated_file.lines.iter().enumerate() {
                         let mut annotations = line.annotations.clone();
@@ -1639,29 +1664,42 @@ impl HumanEmitter {
                             }
                             line_idx += 1;
                         }
-                        for (label, is_primary) in labels.into_iter() {
+                        if is_cont
+                            && file_idx == annotated_files_len - 1
+                            && annotation_id == annotated_file.lines.len() - 1
+                            && !labels.is_empty()
+                        {
+                            code_window_status = CodeWindowStatus::Closed;
+                        }
+                        let labels_len = labels.len();
+                        for (label_idx, (label, is_primary)) in labels.into_iter().enumerate() {
                             let style = if is_primary {
                                 Style::LabelPrimary
                             } else {
                                 Style::LabelSecondary
                             };
-                            let pipe = self.col_separator();
-                            buffer.prepend(line_idx, &format!(" {pipe}"), Style::LineNumber);
-                            for _ in 0..max_line_num_len {
-                                buffer.prepend(line_idx, " ", Style::NoStyle);
-                            }
+                            self.draw_col_separator_no_space(
+                                &mut buffer,
+                                line_idx,
+                                max_line_num_len + 1,
+                            );
                             line_idx += 1;
-                            let chr = self.note_separator();
-                            buffer.append(line_idx, &format!(" {chr} note: "), style);
-                            for _ in 0..max_line_num_len {
-                                buffer.prepend(line_idx, " ", Style::NoStyle);
-                            }
+                            self.draw_note_separator(
+                                &mut buffer,
+                                line_idx,
+                                max_line_num_len + 1,
+                                label_idx != labels_len - 1,
+                            );
+                            buffer.append(line_idx, "note", Style::MainHeaderMsg);
+                            buffer.append(line_idx, ": ", Style::NoStyle);
                             buffer.append(line_idx, label, style);
                             line_idx += 1;
                         }
                     }
                 }
                 continue;
+            } else {
+                col_sep_before_no_show_source = true;
             }
 
             // print out the span location and spacer before we print the annotated source
@@ -1976,7 +2014,7 @@ impl HumanEmitter {
         // final step: take our styled buffer, render it, then output it
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
 
-        Ok(())
+        Ok(code_window_status)
     }
 
     fn column_width(&self, code_offset: usize) -> usize {
@@ -2491,7 +2529,7 @@ impl HumanEmitter {
             !children.is_empty()
                 || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden),
         ) {
-            Ok(()) => {
+            Ok(code_window_status) => {
                 if !children.is_empty()
                     || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden)
                 {
@@ -2502,7 +2540,7 @@ impl HumanEmitter {
                         {
                             // We'll continue the vertical bar to point into the next note.
                             self.draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
-                        } else {
+                        } else if matches!(code_window_status, CodeWindowStatus::Open) {
                             // We'll close the vertical bar to visually end the code window.
                             self.draw_col_separator_end(&mut buffer, 0, max_line_num_len + 1);
                         }
@@ -2829,10 +2867,11 @@ impl HumanEmitter {
         }
     }
 
-    fn note_separator(&self) -> char {
+    fn note_separator(&self, is_cont: bool) -> &'static str {
         match self.theme {
-            OutputTheme::Ascii => '=',
-            OutputTheme::Unicode => '╰',
+            OutputTheme::Ascii => "= ",
+            OutputTheme::Unicode if is_cont => "├ ",
+            OutputTheme::Unicode => "╰ ",
         }
     }
 
@@ -2945,11 +2984,7 @@ impl HumanEmitter {
         col: usize,
         is_cont: bool,
     ) {
-        let chr = match self.theme {
-            OutputTheme::Ascii => "= ",
-            OutputTheme::Unicode if is_cont => "├ ",
-            OutputTheme::Unicode => "╰ ",
-        };
+        let chr = self.note_separator(is_cont);
         buffer.puts(line, col, chr, Style::LineNumber);
     }
 
@@ -3050,6 +3085,12 @@ enum DisplaySuggestion {
     Add,
 }
 
+#[derive(Clone, Copy, Debug)]
+enum CodeWindowStatus {
+    Closed,
+    Open,
+}
+
 impl FileWithAnnotatedLines {
     /// Preprocess all the annotations so that they are grouped by file and by line number
     /// This helps us quickly iterate over the whole message (including secondary file spans)
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml
index f897833d85c..9bb7143af51 100644
--- a/compiler/rustc_expand/Cargo.toml
+++ b/compiler/rustc_expand/Cargo.toml
@@ -29,6 +29,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml
index 1008a3e787d..ea72ed68c5e 100644
--- a/compiler/rustc_hir/Cargo.toml
+++ b/compiler/rustc_hir/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.9.1"
+bitflags.workspace = true
 odht = { version = "0.3.1", features = ["nightly"] }
 rustc_abi = { path = "../rustc_abi" }
 rustc_arena = { path = "../rustc_arena" }
@@ -21,6 +21,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index 09da5772d23..dd5565d6f90 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -248,6 +248,120 @@ impl IntoDiagArg for MirPhase {
     }
 }
 
+/// Different ways that the PE Format can decorate a symbol name.
+/// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type>
+#[derive(
+    Copy,
+    Clone,
+    Debug,
+    Encodable,
+    Decodable,
+    HashStable_Generic,
+    PartialEq,
+    Eq,
+    PrintAttribute
+)]
+pub enum PeImportNameType {
+    /// IMPORT_ORDINAL
+    /// Uses the ordinal (i.e., a number) rather than the name.
+    Ordinal(u16),
+    /// Same as IMPORT_NAME
+    /// Name is decorated with all prefixes and suffixes.
+    Decorated,
+    /// Same as IMPORT_NAME_NOPREFIX
+    /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept.
+    NoPrefix,
+    /// Same as IMPORT_NAME_UNDECORATE
+    /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all
+    /// trailing characters) are skipped.
+    Undecorated,
+}
+
+#[derive(
+    Copy,
+    Clone,
+    Debug,
+    PartialEq,
+    Eq,
+    PartialOrd,
+    Ord,
+    Hash,
+    Encodable,
+    Decodable,
+    PrintAttribute
+)]
+#[derive(HashStable_Generic)]
+pub enum NativeLibKind {
+    /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
+    Static {
+        /// Whether to bundle objects from static library into produced rlib
+        bundle: Option<bool>,
+        /// Whether to link static library without throwing any object files away
+        whole_archive: Option<bool>,
+    },
+    /// Dynamic library (e.g. `libfoo.so` on Linux)
+    /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
+    Dylib {
+        /// Whether the dynamic library will be linked only if it satisfies some undefined symbols
+        as_needed: Option<bool>,
+    },
+    /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
+    /// On Linux, it refers to a generated shared library stub.
+    RawDylib,
+    /// A macOS-specific kind of dynamic libraries.
+    Framework {
+        /// Whether the framework will be linked only if it satisfies some undefined symbols
+        as_needed: Option<bool>,
+    },
+    /// Argument which is passed to linker, relative order with libraries and other arguments
+    /// is preserved
+    LinkArg,
+
+    /// Module imported from WebAssembly
+    WasmImportModule,
+
+    /// The library kind wasn't specified, `Dylib` is currently used as a default.
+    Unspecified,
+}
+
+impl NativeLibKind {
+    pub fn has_modifiers(&self) -> bool {
+        match self {
+            NativeLibKind::Static { bundle, whole_archive } => {
+                bundle.is_some() || whole_archive.is_some()
+            }
+            NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
+                as_needed.is_some()
+            }
+            NativeLibKind::RawDylib
+            | NativeLibKind::Unspecified
+            | NativeLibKind::LinkArg
+            | NativeLibKind::WasmImportModule => false,
+        }
+    }
+
+    pub fn is_statically_included(&self) -> bool {
+        matches!(self, NativeLibKind::Static { .. })
+    }
+
+    pub fn is_dllimport(&self) -> bool {
+        matches!(
+            self,
+            NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified
+        )
+    }
+}
+
+#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
+pub struct LinkEntry {
+    pub span: Span,
+    pub kind: NativeLibKind,
+    pub name: Symbol,
+    pub cfg: Option<CfgEntry>,
+    pub verbatim: Option<bool>,
+    pub import_name_type: Option<(PeImportNameType, Span)>,
+}
+
 /// Represents parsed *built-in* inert attributes.
 ///
 /// ## Overview
@@ -418,6 +532,9 @@ pub enum AttributeKind {
     /// Represents `#[inline]` and `#[rustc_force_inline]`.
     Inline(InlineAttr, Span),
 
+    /// Represents `#[link]`.
+    Link(ThinVec<LinkEntry>, Span),
+
     /// Represents `#[link_name]`.
     LinkName { name: Symbol, span: Span },
 
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index e5329c104bb..3810bb6d003 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -50,6 +50,7 @@ impl AttributeKind {
             Fundamental { .. } => Yes,
             Ignore { .. } => No,
             Inline(..) => No,
+            Link(..) => No,
             LinkName { .. } => Yes, // Needed for rustdoc
             LinkOrdinal { .. } => No,
             LinkSection { .. } => Yes, // Needed for rustdoc
diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml
index e5017794d8f..bb86beb2251 100644
--- a/compiler/rustc_hir_analysis/Cargo.toml
+++ b/compiler/rustc_hir_analysis/Cargo.toml
@@ -9,7 +9,7 @@ doctest = false
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
@@ -29,5 +29,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml
index f00125c3e09..5af0c6134ca 100644
--- a/compiler/rustc_hir_typeck/Cargo.toml
+++ b/compiler/rustc_hir_typeck/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr_parsing = { path = "../rustc_attr_parsing" }
@@ -25,5 +25,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml
index db0a5841887..8d7f2eb8414 100644
--- a/compiler/rustc_incremental/Cargo.toml
+++ b/compiler/rustc_incremental/Cargo.toml
@@ -19,6 +19,6 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
index 08c03614884..6d97fa6af1f 100644
--- a/compiler/rustc_infer/Cargo.toml
+++ b/compiler/rustc_infer/Cargo.toml
@@ -18,6 +18,6 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 473ac5e0cea..40152e78f8a 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -46,7 +46,7 @@ rustc_thread_pool = { path = "../rustc_thread_pool" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_traits = { path = "../rustc_traits" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [dev-dependencies]
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 4425877308a..7730bddc0f1 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -8,6 +8,7 @@ use rustc_abi::Align;
 use rustc_data_structures::profiling::TimePassesFormat;
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, registry};
+use rustc_hir::attrs::NativeLibKind;
 use rustc_session::config::{
     AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel,
     CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation,
@@ -20,7 +21,7 @@ use rustc_session::config::{
 };
 use rustc_session::lint::Level;
 use rustc_session::search_paths::SearchPath;
-use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
+use rustc_session::utils::{CanonicalizedPath, NativeLib};
 use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, getopts};
 use rustc_span::edition::{DEFAULT_EDITION, Edition};
 use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index 448a50faf45..e0019fb1821 100644
--- a/compiler/rustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -14,13 +14,9 @@ Rust lexer used by rustc. No stability guarantees are provided.
 
 # Note that this crate purposefully does not depend on other rustc crates
 [dependencies]
-memchr = "2.7.4"
+memchr.workspace = true
+unicode-properties = { version = "0.1.0", default-features = false, features = ["emoji"] }
 unicode-xid = "0.2.0"
 
-[dependencies.unicode-properties]
-version = "0.1.0"
-default-features = false
-features = ["emoji"]
-
 [dev-dependencies]
 expect-test = "1.4.0"
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index 7718f16984d..7900e4b9ab2 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -24,6 +24,6 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 unicode-security = "0.1.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 426500dda4a..56d65ed08f9 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1554,7 +1554,7 @@ impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
 #[help(lint_help_exposed_provenance)]
 pub(crate) struct IntegerToPtrTransmutes<'tcx> {
     #[subdiagnostic]
-    pub suggestion: IntegerToPtrTransmutesSuggestion<'tcx>,
+    pub suggestion: Option<IntegerToPtrTransmutesSuggestion<'tcx>>,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_lint/src/transmute.rs b/compiler/rustc_lint/src/transmute.rs
index 239c8649041..98510eea73b 100644
--- a/compiler/rustc_lint/src/transmute.rs
+++ b/compiler/rustc_lint/src/transmute.rs
@@ -169,19 +169,25 @@ fn check_int_to_ptr_transmute<'tcx>(
         expr.hir_id,
         expr.span,
         IntegerToPtrTransmutes {
-            suggestion: if dst.is_ref() {
-                IntegerToPtrTransmutesSuggestion::ToRef {
-                    dst: *inner_ty,
-                    suffix,
-                    ref_mutbl: mutbl.prefix_str(),
-                    start_call: expr.span.shrink_to_lo().until(arg.span),
-                }
+            suggestion: if layout_inner_ty.is_sized() {
+                Some(if dst.is_ref() {
+                    IntegerToPtrTransmutesSuggestion::ToRef {
+                        dst: *inner_ty,
+                        suffix,
+                        ref_mutbl: mutbl.prefix_str(),
+                        start_call: expr.span.shrink_to_lo().until(arg.span),
+                    }
+                } else {
+                    IntegerToPtrTransmutesSuggestion::ToPtr {
+                        dst: *inner_ty,
+                        suffix,
+                        start_call: expr.span.shrink_to_lo().until(arg.span),
+                    }
+                })
             } else {
-                IntegerToPtrTransmutesSuggestion::ToPtr {
-                    dst: *inner_ty,
-                    suffix,
-                    start_call: expr.span.shrink_to_lo().until(arg.span),
-                }
+                // We can't suggest using `with_exposed_provenance` for unsized type
+                // so don't suggest anything.
+                None
             },
         },
     );
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index cce40da354d..361a5f76551 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -242,7 +242,7 @@ enum class LLVMRustAttributeKind {
   MinSize = 4,
   Naked = 5,
   NoAlias = 6,
-  NoCapture = 7,
+  CapturesAddress = 7,
   NoInline = 8,
   NonNull = 9,
   NoRedZone = 10,
@@ -297,12 +297,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
     return Attribute::Naked;
   case LLVMRustAttributeKind::NoAlias:
     return Attribute::NoAlias;
-  case LLVMRustAttributeKind::NoCapture:
-#if LLVM_VERSION_GE(21, 0)
-    report_fatal_error("NoCapture doesn't exist in LLVM 21");
-#else
-    return Attribute::NoCapture;
-#endif
   case LLVMRustAttributeKind::NoCfCheck:
     return Attribute::NoCfCheck;
   case LLVMRustAttributeKind::NoInline:
@@ -377,6 +371,7 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
 #else
     report_fatal_error("DeadOnReturn attribute requires LLVM 21 or later");
 #endif
+  case LLVMRustAttributeKind::CapturesAddress:
   case LLVMRustAttributeKind::CapturesReadOnly:
     report_fatal_error("Should be handled separately");
   }
@@ -429,9 +424,9 @@ extern "C" void LLVMRustEraseInstFromParent(LLVMValueRef Instr) {
 extern "C" LLVMAttributeRef
 LLVMRustCreateAttrNoValue(LLVMContextRef C, LLVMRustAttributeKind RustAttr) {
 #if LLVM_VERSION_GE(21, 0)
-  // LLVM 21 replaced the NoCapture attribute with Captures(none).
-  if (RustAttr == LLVMRustAttributeKind::NoCapture) {
-    return wrap(Attribute::getWithCaptureInfo(*unwrap(C), CaptureInfo::none()));
+  if (RustAttr == LLVMRustAttributeKind::CapturesAddress) {
+    return wrap(Attribute::getWithCaptureInfo(
+        *unwrap(C), CaptureInfo(CaptureComponents::Address)));
   }
   if (RustAttr == LLVMRustAttributeKind::CapturesReadOnly) {
     return wrap(Attribute::getWithCaptureInfo(
diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml
index c673d51a1d4..e9d7b4723f8 100644
--- a/compiler/rustc_log/Cargo.toml
+++ b/compiler/rustc_log/Cargo.toml
@@ -5,10 +5,10 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-tracing = "0.1.28"
 tracing-core = "=0.1.30" # FIXME(Nilstrieb) tracing has a deadlock: https://github.com/tokio-rs/tracing/issues/2635
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 tracing-tree = "0.3.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index 1b40d9f684e..4bb9e49ccce 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 libloading = "0.8.0"
 odht = { version = "0.3.1", features = ["nightly"] }
 rustc_abi = { path = "../rustc_abi" }
@@ -31,7 +31,7 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 tempfile = "3.7.1"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [target.'cfg(target_os = "aix")'.dependencies]
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index 4d3e879a098..e104be2c466 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -1,6 +1,3 @@
-metadata_as_needed_compatibility =
-    linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
-
 metadata_async_drop_types_in_dependency =
     found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
     .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
@@ -11,9 +8,6 @@ metadata_bad_panic_strategy =
 metadata_binary_output_to_tty =
     option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty
 
-metadata_bundle_needs_static =
-    linking modifier `bundle` is only compatible with `static` linking kind
-
 metadata_cannot_find_crate =
     can't find crate for `{$crate_name}`{$add_info}
 
@@ -60,10 +54,6 @@ metadata_crate_not_panic_runtime =
 metadata_dl_error =
     {$path}{$err}
 
-metadata_empty_link_name =
-    link name must not be empty
-    .label = empty link name
-
 metadata_empty_renaming_target =
     an empty renaming target was specified for library `{$lib_name}`
 
@@ -108,15 +98,6 @@ metadata_full_metadata_not_found =
 metadata_global_alloc_required =
     no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
 
-metadata_import_name_type_form =
-    import name type must be of the form `import_name_type = "string"`
-
-metadata_import_name_type_raw =
-    import name type can only be used with link kind `raw-dylib`
-
-metadata_import_name_type_x86 =
-    import name type is only supported on x86
-
 metadata_incompatible_panic_in_drop_strategy =
     the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
 
@@ -143,15 +124,10 @@ metadata_incompatible_target_modifiers_r_missed =
     mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
     .note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`
     .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
-metadata_incompatible_wasm_link =
-    `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
 
 metadata_install_missing_components =
     maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
 
-metadata_invalid_link_modifier =
-    invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
-
 metadata_invalid_meta_files =
     found invalid metadata files for crate `{$crate_name}`{$add_info}
 
@@ -164,67 +140,18 @@ metadata_lib_framework_apple =
 metadata_lib_required =
     crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
 
-metadata_link_arg_unstable =
-    link kind `link-arg` is unstable
-
-metadata_link_cfg_form =
-    link cfg must be of the form `cfg(/* predicate */)`
-
-metadata_link_cfg_single_predicate =
-    link cfg must have a single predicate argument
-
-metadata_link_cfg_unstable =
-    link cfg is unstable
-
-metadata_link_framework_apple =
-    link kind `framework` is only supported on Apple targets
-
-metadata_link_kind_form =
-    link kind must be of the form `kind = "string"`
-
-metadata_link_modifiers_form =
-    link modifiers must be of the form `modifiers = "string"`
-
-metadata_link_name_form =
-    link name must be of the form `name = "string"`
-
 metadata_link_ordinal_raw_dylib =
     `#[link_ordinal]` is only supported if link kind is `raw-dylib`
 
-metadata_link_requires_name =
-    `#[link]` attribute requires a `name = "string"` argument
-    .label = missing `name` argument
-
 metadata_missing_native_library =
     could not find native static library `{$libname}`, perhaps an -L flag is missing?
 
 metadata_multiple_candidates =
     multiple candidates for `{$flavor}` dependency `{$crate_name}` found
 
-metadata_multiple_cfgs =
-    multiple `cfg` arguments in a single `#[link]` attribute
-
-metadata_multiple_import_name_type =
-    multiple `import_name_type` arguments in a single `#[link]` attribute
-
-metadata_multiple_kinds_in_link =
-    multiple `kind` arguments in a single `#[link]` attribute
-
-metadata_multiple_link_modifiers =
-    multiple `modifiers` arguments in a single `#[link]` attribute
-
-metadata_multiple_modifiers =
-    multiple `{$modifier}` modifiers in a single `modifiers` argument
-
-metadata_multiple_names_in_link =
-    multiple `name` arguments in a single `#[link]` attribute
-
 metadata_multiple_renamings =
     multiple renamings were specified for library `{$lib_name}`
 
-metadata_multiple_wasm_import =
-    multiple `wasm_import_module` arguments in a single `#[link]` attribute
-
 metadata_newer_crate_version =
     found possibly newer version of crate `{$crate_name}`{$add_info}
     .note = perhaps that crate needs to be recompiled?
@@ -263,15 +190,6 @@ metadata_prev_alloc_error_handler =
 metadata_prev_global_alloc =
     previous global allocator defined here
 
-metadata_raw_dylib_elf_unstable =
-    link kind `raw-dylib` is unstable on ELF platforms
-
-metadata_raw_dylib_no_nul =
-    link name must not contain NUL characters if link kind is `raw-dylib`
-
-metadata_raw_dylib_only_windows =
-    link kind `raw-dylib` is only supported on Windows targets
-
 metadata_raw_dylib_unsupported_abi =
     ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
 
@@ -307,19 +225,6 @@ metadata_target_not_installed =
 metadata_two_panic_runtimes =
     cannot link together two panic runtimes: {$prev_name} and {$cur_name}
 
-metadata_unexpected_link_arg =
-    unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
-
-metadata_unknown_import_name_type =
-    unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated
-
-metadata_unknown_link_kind =
-    unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib, link-arg
-    .label = unknown link kind
-
-metadata_unknown_link_modifier =
-    unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed
-
 metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`
 
 metadata_wasm_c_abi =
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 0332dba1077..e5a4fd48353 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -84,187 +84,6 @@ pub struct IncompatiblePanicInDropStrategy {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_multiple_names_in_link)]
-pub struct MultipleNamesInLink {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_multiple_kinds_in_link)]
-pub struct MultipleKindsInLink {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_name_form)]
-pub struct LinkNameForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_kind_form)]
-pub struct LinkKindForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_modifiers_form)]
-pub struct LinkModifiersForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_cfg_form)]
-pub struct LinkCfgForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_wasm_import_form)]
-pub struct WasmImportForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_empty_link_name, code = E0454)]
-pub struct EmptyLinkName {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_framework_apple, code = E0455)]
-pub struct LinkFrameworkApple {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_raw_dylib_only_windows, code = E0455)]
-pub struct RawDylibOnlyWindows {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_unknown_link_kind, code = E0458)]
-pub struct UnknownLinkKind<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub kind: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_multiple_link_modifiers)]
-pub struct MultipleLinkModifiers {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_multiple_cfgs)]
-pub struct MultipleCfgs {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_cfg_single_predicate)]
-pub struct LinkCfgSinglePredicate {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_multiple_wasm_import)]
-pub struct MultipleWasmImport {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_unexpected_link_arg)]
-pub struct UnexpectedLinkArg {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_invalid_link_modifier)]
-pub struct InvalidLinkModifier {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_multiple_modifiers)]
-pub struct MultipleModifiers<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub modifier: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_bundle_needs_static)]
-pub struct BundleNeedsStatic {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_whole_archive_needs_static)]
-pub struct WholeArchiveNeedsStatic {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_as_needed_compatibility)]
-pub struct AsNeededCompatibility {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_unknown_link_modifier)]
-pub struct UnknownLinkModifier<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub modifier: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_incompatible_wasm_link)]
-pub struct IncompatibleWasmLink {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_link_requires_name, code = E0459)]
-pub struct LinkRequiresName {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_raw_dylib_no_nul)]
-pub struct RawDylibNoNul {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(metadata_link_ordinal_raw_dylib)]
 pub struct LinkOrdinalRawDylib {
     #[primary_span]
@@ -707,42 +526,6 @@ pub struct LibFilenameForm<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_multiple_import_name_type)]
-pub struct MultipleImportNameType {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_import_name_type_form)]
-pub struct ImportNameTypeForm {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_import_name_type_x86)]
-pub struct ImportNameTypeX86 {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_unknown_import_name_type)]
-pub struct UnknownImportNameType<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub import_name_type: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(metadata_import_name_type_raw)]
-pub struct ImportNameTypeRaw {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(metadata_wasm_c_abi)]
 pub(crate) struct WasmCAbi {
     #[primary_span]
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 63f1b51df1c..82738c68c59 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -3,25 +3,21 @@ use std::path::{Path, PathBuf};
 
 use rustc_abi::ExternAbi;
 use rustc_ast::CRATE_NODE_ID;
-use rustc_attr_parsing as attr;
+use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::attrs::AttributeKind;
+use rustc_hir::attrs::{AttributeKind, NativeLibKind, PeImportNameType};
 use rustc_hir::find_attr;
 use rustc_middle::query::LocalCrate;
 use rustc_middle::ty::{self, List, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_session::config::CrateType;
-use rustc_session::cstore::{
-    DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType,
-};
-use rustc_session::parse::feature_err;
+use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, NativeLib};
 use rustc_session::search_paths::PathKind;
-use rustc_session::utils::NativeLibKind;
+use rustc_span::Symbol;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
-use rustc_span::{Symbol, sym};
 use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents};
 
-use crate::{errors, fluent_generated};
+use crate::errors;
 
 /// The fallback directories are passed to linker, but not used when rustc does the search,
 /// because in the latter case the set of fallback directories cannot always be determined
@@ -192,7 +188,9 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>
 
 pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
     match lib.cfg {
-        Some(ref cfg) => attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
+        Some(ref cfg) => {
+            eval_config_entry(sess, cfg, CRATE_NODE_ID, None, ShouldEmit::ErrorsAndLints).as_bool()
+        }
         None => true,
     }
 }
@@ -213,289 +211,23 @@ impl<'tcx> Collector<'tcx> {
             return;
         }
 
-        // Process all of the #[link(..)]-style arguments
-        let features = self.tcx.features();
-
-        for m in self.tcx.get_attrs(def_id, sym::link) {
-            let Some(items) = m.meta_item_list() else {
-                continue;
-            };
-
-            let mut name = None;
-            let mut kind = None;
-            let mut modifiers = None;
-            let mut cfg = None;
-            let mut wasm_import_module = None;
-            let mut import_name_type = None;
-            for item in items.iter() {
-                match item.name() {
-                    Some(sym::name) => {
-                        if name.is_some() {
-                            sess.dcx().emit_err(errors::MultipleNamesInLink { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_name) = item.value_str() else {
-                            sess.dcx().emit_err(errors::LinkNameForm { span: item.span() });
-                            continue;
-                        };
-                        let span = item.name_value_literal_span().unwrap();
-                        if link_name.is_empty() {
-                            sess.dcx().emit_err(errors::EmptyLinkName { span });
-                        }
-                        name = Some((link_name, span));
-                    }
-                    Some(sym::kind) => {
-                        if kind.is_some() {
-                            sess.dcx().emit_err(errors::MultipleKindsInLink { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_kind) = item.value_str() else {
-                            sess.dcx().emit_err(errors::LinkKindForm { span: item.span() });
-                            continue;
-                        };
-
-                        let span = item.name_value_literal_span().unwrap();
-                        let link_kind = match link_kind.as_str() {
-                            "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
-                            "dylib" => NativeLibKind::Dylib { as_needed: None },
-                            "framework" => {
-                                if !sess.target.is_like_darwin {
-                                    sess.dcx().emit_err(errors::LinkFrameworkApple { span });
-                                }
-                                NativeLibKind::Framework { as_needed: None }
-                            }
-                            "raw-dylib" => {
-                                if sess.target.is_like_windows {
-                                    // raw-dylib is stable and working on Windows
-                                } else if sess.target.binary_format == BinaryFormat::Elf
-                                    && features.raw_dylib_elf()
-                                {
-                                    // raw-dylib is unstable on ELF, but the user opted in
-                                } else if sess.target.binary_format == BinaryFormat::Elf
-                                    && sess.is_nightly_build()
-                                {
-                                    feature_err(
-                                        sess,
-                                        sym::raw_dylib_elf,
-                                        span,
-                                        fluent_generated::metadata_raw_dylib_elf_unstable,
-                                    )
-                                    .emit();
-                                } else {
-                                    sess.dcx().emit_err(errors::RawDylibOnlyWindows { span });
-                                }
-
-                                NativeLibKind::RawDylib
-                            }
-                            "link-arg" => {
-                                if !features.link_arg_attribute() {
-                                    feature_err(
-                                        sess,
-                                        sym::link_arg_attribute,
-                                        span,
-                                        fluent_generated::metadata_link_arg_unstable,
-                                    )
-                                    .emit();
-                                }
-                                NativeLibKind::LinkArg
-                            }
-                            kind => {
-                                sess.dcx().emit_err(errors::UnknownLinkKind { span, kind });
-                                continue;
-                            }
-                        };
-                        kind = Some(link_kind);
-                    }
-                    Some(sym::modifiers) => {
-                        if modifiers.is_some() {
-                            sess.dcx()
-                                .emit_err(errors::MultipleLinkModifiers { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_modifiers) = item.value_str() else {
-                            sess.dcx().emit_err(errors::LinkModifiersForm { span: item.span() });
-                            continue;
-                        };
-                        modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
-                    }
-                    Some(sym::cfg) => {
-                        if cfg.is_some() {
-                            sess.dcx().emit_err(errors::MultipleCfgs { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_cfg) = item.meta_item_list() else {
-                            sess.dcx().emit_err(errors::LinkCfgForm { span: item.span() });
-                            continue;
-                        };
-                        let [link_cfg] = link_cfg else {
-                            sess.dcx()
-                                .emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
-                            continue;
-                        };
-                        let Some(link_cfg) = link_cfg.meta_item_or_bool() else {
-                            sess.dcx()
-                                .emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
-                            continue;
-                        };
-                        if !features.link_cfg() {
-                            feature_err(
-                                sess,
-                                sym::link_cfg,
-                                item.span(),
-                                fluent_generated::metadata_link_cfg_unstable,
-                            )
-                            .emit();
-                        }
-                        cfg = Some(link_cfg.clone());
-                    }
-                    Some(sym::wasm_import_module) => {
-                        if wasm_import_module.is_some() {
-                            sess.dcx().emit_err(errors::MultipleWasmImport { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_wasm_import_module) = item.value_str() else {
-                            sess.dcx().emit_err(errors::WasmImportForm { span: item.span() });
-                            continue;
-                        };
-                        wasm_import_module = Some((link_wasm_import_module, item.span()));
-                    }
-                    Some(sym::import_name_type) => {
-                        if import_name_type.is_some() {
-                            sess.dcx()
-                                .emit_err(errors::MultipleImportNameType { span: item.span() });
-                            continue;
-                        }
-                        let Some(link_import_name_type) = item.value_str() else {
-                            sess.dcx().emit_err(errors::ImportNameTypeForm { span: item.span() });
-                            continue;
-                        };
-                        if self.tcx.sess.target.arch != "x86" {
-                            sess.dcx().emit_err(errors::ImportNameTypeX86 { span: item.span() });
-                            continue;
-                        }
-
-                        let link_import_name_type = match link_import_name_type.as_str() {
-                            "decorated" => PeImportNameType::Decorated,
-                            "noprefix" => PeImportNameType::NoPrefix,
-                            "undecorated" => PeImportNameType::Undecorated,
-                            import_name_type => {
-                                sess.dcx().emit_err(errors::UnknownImportNameType {
-                                    span: item.span(),
-                                    import_name_type,
-                                });
-                                continue;
-                            }
-                        };
-                        import_name_type = Some((link_import_name_type, item.span()));
-                    }
-                    _ => {
-                        sess.dcx().emit_err(errors::UnexpectedLinkArg { span: item.span() });
-                    }
-                }
-            }
-
-            // Do this outside the above loop so we don't depend on modifiers coming after kinds
-            let mut verbatim = None;
-            if let Some((modifiers, span)) = modifiers {
-                for modifier in modifiers.as_str().split(',') {
-                    let (modifier, value) = match modifier.strip_prefix(&['+', '-']) {
-                        Some(m) => (m, modifier.starts_with('+')),
-                        None => {
-                            sess.dcx().emit_err(errors::InvalidLinkModifier { span });
-                            continue;
-                        }
-                    };
-
-                    macro report_unstable_modifier($feature: ident) {
-                        if !features.$feature() {
-                            // FIXME: make this translatable
-                            #[expect(rustc::untranslatable_diagnostic)]
-                            feature_err(
-                                sess,
-                                sym::$feature,
-                                span,
-                                format!("linking modifier `{modifier}` is unstable"),
-                            )
-                            .emit();
-                        }
-                    }
-                    let assign_modifier = |dst: &mut Option<bool>| {
-                        if dst.is_some() {
-                            sess.dcx().emit_err(errors::MultipleModifiers { span, modifier });
-                        } else {
-                            *dst = Some(value);
-                        }
-                    };
-                    match (modifier, &mut kind) {
-                        ("bundle", Some(NativeLibKind::Static { bundle, .. })) => {
-                            assign_modifier(bundle)
-                        }
-                        ("bundle", _) => {
-                            sess.dcx().emit_err(errors::BundleNeedsStatic { span });
-                        }
-
-                        ("verbatim", _) => assign_modifier(&mut verbatim),
-
-                        ("whole-archive", Some(NativeLibKind::Static { whole_archive, .. })) => {
-                            assign_modifier(whole_archive)
-                        }
-                        ("whole-archive", _) => {
-                            sess.dcx().emit_err(errors::WholeArchiveNeedsStatic { span });
-                        }
-
-                        ("as-needed", Some(NativeLibKind::Dylib { as_needed }))
-                        | ("as-needed", Some(NativeLibKind::Framework { as_needed })) => {
-                            report_unstable_modifier!(native_link_modifiers_as_needed);
-                            assign_modifier(as_needed)
-                        }
-                        ("as-needed", _) => {
-                            sess.dcx().emit_err(errors::AsNeededCompatibility { span });
-                        }
-
-                        _ => {
-                            sess.dcx().emit_err(errors::UnknownLinkModifier { span, modifier });
-                        }
-                    }
-                }
-            }
-
-            if let Some((_, span)) = wasm_import_module {
-                if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
-                    sess.dcx().emit_err(errors::IncompatibleWasmLink { span });
-                }
-            }
-
-            if wasm_import_module.is_some() {
-                (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
-            }
-            let Some((name, name_span)) = name else {
-                sess.dcx().emit_err(errors::LinkRequiresName { span: m.span() });
-                continue;
-            };
-
-            // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
-            if let Some((_, span)) = import_name_type {
-                if kind != Some(NativeLibKind::RawDylib) {
-                    sess.dcx().emit_err(errors::ImportNameTypeRaw { span });
-                }
-            }
-
-            let dll_imports = match kind {
-                Some(NativeLibKind::RawDylib) => {
-                    if name.as_str().contains('\0') {
-                        sess.dcx().emit_err(errors::RawDylibNoNul { span: name_span });
-                    }
-                    foreign_items
-                        .iter()
-                        .map(|&child_item| {
-                            self.build_dll_import(
-                                abi,
-                                import_name_type.map(|(import_name_type, _)| import_name_type),
-                                child_item,
-                            )
-                        })
-                        .collect()
-                }
+        for attr in
+            find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::Link(links, _) => links)
+                .iter()
+                .map(|v| v.iter())
+                .flatten()
+        {
+            let dll_imports = match attr.kind {
+                NativeLibKind::RawDylib => foreign_items
+                    .iter()
+                    .map(|&child_item| {
+                        self.build_dll_import(
+                            abi,
+                            attr.import_name_type.map(|(import_name_type, _)| import_name_type),
+                            child_item,
+                        )
+                    })
+                    .collect(),
                 _ => {
                     for &child_item in foreign_items {
                         if let Some(span) = find_attr!(self.tcx.get_all_attrs(child_item), AttributeKind::LinkOrdinal {span, ..} => *span)
@@ -508,15 +240,20 @@ impl<'tcx> Collector<'tcx> {
                 }
             };
 
-            let kind = kind.unwrap_or(NativeLibKind::Unspecified);
-            let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), self.tcx);
+            let filename = find_bundled_library(
+                attr.name,
+                attr.verbatim,
+                attr.kind,
+                attr.cfg.is_some(),
+                self.tcx,
+            );
             self.libs.push(NativeLib {
-                name,
+                name: attr.name,
                 filename,
-                kind,
-                cfg,
+                kind: attr.kind,
+                cfg: attr.cfg.clone(),
                 foreign_module: Some(def_id.to_def_id()),
-                verbatim,
+                verbatim: attr.verbatim,
                 dll_imports,
             });
         }
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index fbcce16cedc..782066981c9 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 either = "1.5.0"
 gsgdt = "0.1.2"
 polonius-engine = "0.13.0"
@@ -34,8 +34,8 @@ rustc_target = { path = "../rustc_target" }
 rustc_thread_pool = { path = "../rustc_thread_pool" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
index f756f0a19ee..c3f7fdfcb00 100644
--- a/compiler/rustc_mir_build/Cargo.toml
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
@@ -23,5 +23,5 @@ rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml
index 9621f9f20bd..e422f69c7ca 100644
--- a/compiler/rustc_mir_dataflow/Cargo.toml
+++ b/compiler/rustc_mir_dataflow/Cargo.toml
@@ -18,5 +18,5 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
index 08c43a4648c..16acec15e92 100644
--- a/compiler/rustc_mir_transform/Cargo.toml
+++ b/compiler/rustc_mir_transform/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 either = "1"
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
@@ -26,5 +26,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml
index 09a55f0b5f8..b11084cf169 100644
--- a/compiler/rustc_monomorphize/Cargo.toml
+++ b/compiler/rustc_monomorphize/Cargo.toml
@@ -17,5 +17,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 serde = "1"
 serde_json = "1"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml
index 05bcabad02f..8b66f30cf0e 100644
--- a/compiler/rustc_next_trait_solver/Cargo.toml
+++ b/compiler/rustc_next_trait_solver/Cargo.toml
@@ -11,7 +11,7 @@ rustc_index = { path = "../rustc_index", default-features = false }
 rustc_macros = { path = "../rustc_macros", optional = true }
 rustc_type_ir = { path = "../rustc_type_ir", default-features = false }
 rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml
index 6d738a10371..7cb4ae7ff5f 100644
--- a/compiler/rustc_parse/Cargo.toml
+++ b/compiler/rustc_parse/Cargo.toml
@@ -5,8 +5,8 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
-rustc-literal-escaper = "0.0.5"
+bitflags.workspace = true
+rustc-literal-escaper.workspace = true
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
@@ -18,8 +18,8 @@ rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 unicode-normalization = "0.1.11"
 unicode-width = "0.2.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f0f58e901a9..7de4f6efd0b 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2077,7 +2077,7 @@ impl<'a> Parser<'a> {
         (token::Lit { symbol: name, suffix: None, kind: token::Char }, span)
     }
 
-    pub fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
+    fn mk_meta_item_lit_char(name: Symbol, span: Span) -> MetaItemLit {
         ast::MetaItemLit {
             symbol: name,
             suffix: None,
@@ -2086,7 +2086,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    pub fn handle_missing_lit<L>(
+    fn handle_missing_lit<L>(
         &mut self,
         mk_lit_char: impl FnOnce(Symbol, Span) -> L,
     ) -> PResult<'a, L> {
diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml
index d178fcda1fb..645e34b6e32 100644
--- a/compiler/rustc_parse_format/Cargo.toml
+++ b/compiler/rustc_parse_format/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-rustc-literal-escaper = "0.0.5"
+rustc-literal-escaper.workspace = true
 rustc_lexer = { path = "../rustc_lexer" }
 # tidy-alphabetical-end
 
diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml
index ba81ef3103b..c74608a6146 100644
--- a/compiler/rustc_passes/Cargo.toml
+++ b/compiler/rustc_passes/Cargo.toml
@@ -24,5 +24,5 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 3be06a3704c..498d9a405fa 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -145,6 +145,10 @@ passes_doc_alias_start_end =
 passes_doc_attr_not_crate_level =
     `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
 
+passes_doc_attribute_not_attribute =
+    nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]`
+    .help = only existing builtin attributes are allowed in core/std
+
 passes_doc_cfg_hide_takes_list =
     `#[doc(cfg_hide(...))]` takes a list of attributes
 
@@ -173,16 +177,16 @@ passes_doc_inline_only_use =
 passes_doc_invalid =
     invalid `doc` attribute
 
-passes_doc_keyword_empty_mod =
-    `#[doc(keyword = "...")]` should be used on empty modules
+passes_doc_keyword_attribute_empty_mod =
+    `#[doc({$attr_name} = "...")]` should be used on empty modules
+
+passes_doc_keyword_attribute_not_mod =
+    `#[doc({$attr_name} = "...")]` should be used on modules
 
 passes_doc_keyword_not_keyword =
     nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]`
     .help = only existing keywords are allowed in core/std
 
-passes_doc_keyword_not_mod =
-    `#[doc(keyword = "...")]` should be used on modules
-
 passes_doc_keyword_only_impl =
     `#[doc(keyword = "...")]` should be used on impl blocks
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 3a79176f914..2cd4830b5d9 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -99,6 +99,21 @@ impl IntoDiagArg for ProcMacroKind {
     }
 }
 
+#[derive(Clone, Copy)]
+enum DocFakeItemKind {
+    Attribute,
+    Keyword,
+}
+
+impl DocFakeItemKind {
+    fn name(self) -> &'static str {
+        match self {
+            Self::Attribute => "attribute",
+            Self::Keyword => "keyword",
+        }
+    }
+}
+
 struct CheckAttrVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
 
@@ -200,6 +215,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 &Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, span: attr_span}) => {
                     self.check_sanitize(attr_span, on_set | off_set, span, target);
                 },
+                Attribute::Parsed(AttributeKind::Link(_, attr_span)) => {
+                    self.check_link(hir_id, *attr_span, span, target)
+                }
                 Attribute::Parsed(
                     AttributeKind::BodyStability { .. }
                     | AttributeKind::ConstStabilityIndirect
@@ -305,7 +323,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::rustc_has_incoherent_inherent_impls, ..] => {
                             self.check_has_incoherent_inherent_impls(attr, span, target)
                         }
-                        [sym::link, ..] => self.check_link(hir_id, attr, span, target),
                         [sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
                         [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
                             self.check_autodiff(hir_id, attr, span, target)
@@ -851,7 +868,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_doc_keyword(&self, meta: &MetaItemInner, hir_id: HirId) {
+    fn check_doc_keyword_and_attribute(
+        &self,
+        meta: &MetaItemInner,
+        hir_id: HirId,
+        attr_kind: DocFakeItemKind,
+    ) {
         fn is_doc_keyword(s: Symbol) -> bool {
             // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we
             // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the
@@ -859,9 +881,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             s.is_reserved(|| edition::LATEST_STABLE_EDITION) || s.is_weak() || s == sym::SelfTy
         }
 
-        let doc_keyword = match meta.value_str() {
+        // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`.
+        fn is_builtin_attr(s: Symbol) -> bool {
+            rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains_key(&s)
+        }
+
+        let value = match meta.value_str() {
             Some(value) if value != sym::empty => value,
-            _ => return self.doc_attr_str_error(meta, "keyword"),
+            _ => return self.doc_attr_str_error(meta, attr_kind.name()),
         };
 
         let item_kind = match self.tcx.hir_node(hir_id) {
@@ -871,20 +898,38 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match item_kind {
             Some(ItemKind::Mod(_, module)) => {
                 if !module.item_ids.is_empty() {
-                    self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
+                    self.dcx().emit_err(errors::DocKeywordAttributeEmptyMod {
+                        span: meta.span(),
+                        attr_name: attr_kind.name(),
+                    });
                     return;
                 }
             }
             _ => {
-                self.dcx().emit_err(errors::DocKeywordNotMod { span: meta.span() });
+                self.dcx().emit_err(errors::DocKeywordAttributeNotMod {
+                    span: meta.span(),
+                    attr_name: attr_kind.name(),
+                });
                 return;
             }
         }
-        if !is_doc_keyword(doc_keyword) {
-            self.dcx().emit_err(errors::DocKeywordNotKeyword {
-                span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
-                keyword: doc_keyword,
-            });
+        match attr_kind {
+            DocFakeItemKind::Keyword => {
+                if !is_doc_keyword(value) {
+                    self.dcx().emit_err(errors::DocKeywordNotKeyword {
+                        span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
+                        keyword: value,
+                    });
+                }
+            }
+            DocFakeItemKind::Attribute => {
+                if !is_builtin_attr(value) {
+                    self.dcx().emit_err(errors::DocAttributeNotAttribute {
+                        span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()),
+                        attribute: value,
+                    });
+                }
+            }
         }
     }
 
@@ -1144,7 +1189,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
                         Some(sym::keyword) => {
                             if self.check_attr_not_crate_level(meta, hir_id, "keyword") {
-                                self.check_doc_keyword(meta, hir_id);
+                                self.check_doc_keyword_and_attribute(
+                                    meta,
+                                    hir_id,
+                                    DocFakeItemKind::Keyword,
+                                );
+                            }
+                        }
+
+                        Some(sym::attribute) => {
+                            if self.check_attr_not_crate_level(meta, hir_id, "attribute") {
+                                self.check_doc_keyword_and_attribute(
+                                    meta,
+                                    hir_id,
+                                    DocFakeItemKind::Attribute,
+                                );
                             }
                         }
 
@@ -1324,7 +1383,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     /// Checks if `#[link]` is applied to an item other than a foreign module.
-    fn check_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
+    fn check_link(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
         if target == Target::ForeignMod
             && let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
             && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
@@ -1336,7 +1395,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         self.tcx.emit_node_span_lint(
             UNUSED_ATTRIBUTES,
             hir_id,
-            attr.span(),
+            attr_span,
             errors::Link { span: (target != Target::ForeignMod).then_some(span) },
         );
     }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 01972067978..680e2a26d84 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -195,10 +195,11 @@ pub(crate) struct DocAliasMalformed {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_doc_keyword_empty_mod)]
-pub(crate) struct DocKeywordEmptyMod {
+#[diag(passes_doc_keyword_attribute_empty_mod)]
+pub(crate) struct DocKeywordAttributeEmptyMod {
     #[primary_span]
     pub span: Span,
+    pub attr_name: &'static str,
 }
 
 #[derive(Diagnostic)]
@@ -211,10 +212,20 @@ pub(crate) struct DocKeywordNotKeyword {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_doc_keyword_not_mod)]
-pub(crate) struct DocKeywordNotMod {
+#[diag(passes_doc_attribute_not_attribute)]
+#[help]
+pub(crate) struct DocAttributeNotAttribute {
+    #[primary_span]
+    pub span: Span,
+    pub attribute: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(passes_doc_keyword_attribute_not_mod)]
+pub(crate) struct DocKeywordAttributeNotMod {
     #[primary_span]
     pub span: Span,
+    pub attr_name: &'static str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml
index a59f7bbeb9e..39f660c8771 100644
--- a/compiler/rustc_pattern_analysis/Cargo.toml
+++ b/compiler/rustc_pattern_analysis/Cargo.toml
@@ -19,7 +19,7 @@ rustc_middle = { path = "../rustc_middle", optional = true }
 rustc_session = { path = "../rustc_session", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
 smallvec = { version = "1.8.1", features = ["union"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [dev-dependencies]
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index c8bfdb91304..7de58132e13 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -15,5 +15,5 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_proc_macro/Cargo.toml b/compiler/rustc_proc_macro/Cargo.toml
index beb95aa3b52..99e7fc7abc6 100644
--- a/compiler/rustc_proc_macro/Cargo.toml
+++ b/compiler/rustc_proc_macro/Cargo.toml
@@ -16,7 +16,7 @@ doctest = false
 
 [dependencies]
 # tidy-alphabetical-start
-rustc-literal-escaper = "0.0.5"
+rustc-literal-escaper.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_public/Cargo.toml b/compiler/rustc_public/Cargo.toml
index 70af30c1a5f..71d339b5792 100644
--- a/compiler/rustc_public/Cargo.toml
+++ b/compiler/rustc_public/Cargo.toml
@@ -14,7 +14,7 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 scoped-tls = "1.0"
 serde = { version = "1.0.125", features = [ "derive" ] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index e5cceacf15d..2005b8b9eca 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -15,5 +15,5 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 7480ba03474..0df933bc81c 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -21,7 +21,7 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_thread_pool = { path = "../rustc_thread_pool" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [dependencies.hashbrown]
diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml
index eb98a6e85c0..7c5332c1662 100644
--- a/compiler/rustc_resolve/Cargo.toml
+++ b/compiler/rustc_resolve/Cargo.toml
@@ -5,9 +5,9 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 indexmap = "2.4.0"
-itertools = "0.12"
+itertools.workspace = true
 pulldown-cmark = { version = "0.11", features = ["html"], default-features = false }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
@@ -27,6 +27,6 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 679e663f886..d4f7fb276a9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -5016,7 +5016,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             }
             ResolveDocLinks::Exported
                 if !maybe_exported.eval(self.r)
-                    && !rustdoc::has_primitive_or_keyword_docs(attrs) =>
+                    && !rustdoc::has_primitive_or_keyword_or_attribute_docs(attrs) =>
             {
                 return;
             }
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 6450f63472c..804792c6f28 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -207,8 +207,10 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>(
     attrs: impl Iterator<Item = (&'a A, Option<DefId>)>,
     doc_only: bool,
 ) -> (Vec<DocFragment>, ThinVec<A>) {
-    let mut doc_fragments = Vec::new();
-    let mut other_attrs = ThinVec::<A>::new();
+    let (min_size, max_size) = attrs.size_hint();
+    let size_hint = max_size.unwrap_or(min_size);
+    let mut doc_fragments = Vec::with_capacity(size_hint);
+    let mut other_attrs = ThinVec::<A>::with_capacity(if doc_only { 0 } else { size_hint });
     for (attr, item_id) in attrs {
         if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
             let doc = beautify_doc_string(doc_str, comment_kind);
@@ -230,6 +232,9 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>(
         }
     }
 
+    doc_fragments.shrink_to_fit();
+    other_attrs.shrink_to_fit();
+
     unindent_doc_fragments(&mut doc_fragments);
 
     (doc_fragments, other_attrs)
@@ -368,8 +373,8 @@ pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
     true
 }
 
-/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
-pub fn has_primitive_or_keyword_docs(attrs: &[impl AttributeExt]) -> bool {
+/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]` or `#[doc(attribute)]`.
+pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[impl AttributeExt]) -> bool {
     for attr in attrs {
         if attr.has_name(sym::rustc_doc_primitive) {
             return true;
@@ -377,7 +382,7 @@ pub fn has_primitive_or_keyword_docs(attrs: &[impl AttributeExt]) -> bool {
             && let Some(items) = attr.meta_item_list()
         {
             for item in items {
-                if item.has_name(sym::keyword) {
+                if item.has_name(sym::keyword) || item.has_name(sym::attribute) {
                     return true;
                 }
             }
diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml
index 9069d2c233d..3dbeaa435f3 100644
--- a/compiler/rustc_sanitizers/Cargo.toml
+++ b/compiler/rustc_sanitizers/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.5.0"
+bitflags.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
@@ -13,6 +13,6 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 twox-hash = "1.6.3"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml
index 948242352e7..e9959735f9f 100644
--- a/compiler/rustc_serialize/Cargo.toml
+++ b/compiler/rustc_serialize/Cargo.toml
@@ -8,7 +8,7 @@ edition = "2024"
 indexmap = "2.0.0"
 rustc_hashes = { path = "../rustc_hashes" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
+thin-vec.workspace = true
 # tidy-alphabetical-end
 
 [dev-dependencies]
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 60d56b1b808..97789b198a4 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 getopts = "0.2"
 rand = "0.9.0"
 rustc_abi = { path = "../rustc_abi" }
@@ -23,7 +23,7 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 termize = "0.2"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [target.'cfg(unix)'.dependencies]
diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs
index f1f0aeb5e59..50a0593f887 100644
--- a/compiler/rustc_session/src/config/native_libs.rs
+++ b/compiler/rustc_session/src/config/native_libs.rs
@@ -5,10 +5,11 @@
 //! which have their own parser in `rustc_metadata`.)
 
 use rustc_feature::UnstableFeatures;
+use rustc_hir::attrs::NativeLibKind;
 
 use crate::EarlyDiagCtxt;
 use crate::config::UnstableOptions;
-use crate::utils::{NativeLib, NativeLibKind};
+use crate::utils::NativeLib;
 
 #[cfg(test)]
 mod tests;
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 4cfc745dec2..30f6256a75e 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -6,8 +6,8 @@ use std::any::Any;
 use std::path::PathBuf;
 
 use rustc_abi::ExternAbi;
-use rustc_ast as ast;
 use rustc_data_structures::sync::{self, AppendOnlyIndexVec, FreezeLock};
+use rustc_hir::attrs::{CfgEntry, NativeLibKind, PeImportNameType};
 use rustc_hir::def_id::{
     CrateNum, DefId, LOCAL_CRATE, LocalDefId, StableCrateId, StableCrateIdMap,
 };
@@ -16,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::{Span, Symbol};
 
 use crate::search_paths::PathKind;
-use crate::utils::NativeLibKind;
 
 // lonely orphan structs and enums looking for a better home
 
@@ -72,7 +71,7 @@ pub struct NativeLib {
     pub name: Symbol,
     /// If packed_bundled_libs enabled, actual filename of library is stored.
     pub filename: Option<Symbol>,
-    pub cfg: Option<ast::MetaItemInner>,
+    pub cfg: Option<CfgEntry>,
     pub foreign_module: Option<DefId>,
     pub verbatim: Option<bool>,
     pub dll_imports: Vec<DllImport>,
@@ -88,25 +87,6 @@ impl NativeLib {
     }
 }
 
-/// Different ways that the PE Format can decorate a symbol name.
-/// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type>
-#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq, Eq)]
-pub enum PeImportNameType {
-    /// IMPORT_ORDINAL
-    /// Uses the ordinal (i.e., a number) rather than the name.
-    Ordinal(u16),
-    /// Same as IMPORT_NAME
-    /// Name is decorated with all prefixes and suffixes.
-    Decorated,
-    /// Same as IMPORT_NAME_NOPREFIX
-    /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept.
-    NoPrefix,
-    /// Same as IMPORT_NAME_UNDECORATE
-    /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all
-    /// trailing characters) are skipped.
-    Undecorated,
-}
-
 #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct DllImport {
     pub name: Symbol,
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 34da54a20bf..50bc7348dc9 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -384,6 +384,10 @@ pub fn report_lit_error(
     lit: token::Lit,
     span: Span,
 ) -> ErrorGuaranteed {
+    create_lit_error(psess, err, lit, span).emit()
+}
+
+pub fn create_lit_error(psess: &ParseSess, err: LitError, lit: token::Lit, span: Span) -> Diag<'_> {
     // Checks if `s` looks like i32 or u1234 etc.
     fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
         s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
@@ -414,32 +418,32 @@ pub fn report_lit_error(
     let dcx = psess.dcx();
     match err {
         LitError::InvalidSuffix(suffix) => {
-            dcx.emit_err(InvalidLiteralSuffix { span, kind: lit.kind.descr(), suffix })
+            dcx.create_err(InvalidLiteralSuffix { span, kind: lit.kind.descr(), suffix })
         }
         LitError::InvalidIntSuffix(suffix) => {
             let suf = suffix.as_str();
             if looks_like_width_suffix(&['i', 'u'], suf) {
                 // If it looks like a width, try to be helpful.
-                dcx.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() })
+                dcx.create_err(InvalidIntLiteralWidth { span, width: suf[1..].into() })
             } else if let Some(fixed) = fix_base_capitalisation(lit.symbol.as_str(), suf) {
-                dcx.emit_err(InvalidNumLiteralBasePrefix { span, fixed })
+                dcx.create_err(InvalidNumLiteralBasePrefix { span, fixed })
             } else {
-                dcx.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() })
+                dcx.create_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() })
             }
         }
         LitError::InvalidFloatSuffix(suffix) => {
             let suf = suffix.as_str();
             if looks_like_width_suffix(&['f'], suf) {
                 // If it looks like a width, try to be helpful.
-                dcx.emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() })
+                dcx.create_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() })
             } else {
-                dcx.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() })
+                dcx.create_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() })
             }
         }
         LitError::NonDecimalFloat(base) => match base {
-            16 => dcx.emit_err(HexadecimalFloatLiteralNotSupported { span }),
-            8 => dcx.emit_err(OctalFloatLiteralNotSupported { span }),
-            2 => dcx.emit_err(BinaryFloatLiteralNotSupported { span }),
+            16 => dcx.create_err(HexadecimalFloatLiteralNotSupported { span }),
+            8 => dcx.create_err(OctalFloatLiteralNotSupported { span }),
+            2 => dcx.create_err(BinaryFloatLiteralNotSupported { span }),
             _ => unreachable!(),
         },
         LitError::IntTooLarge(base) => {
@@ -450,7 +454,7 @@ pub fn report_lit_error(
                 16 => format!("{max:#x}"),
                 _ => format!("{max}"),
             };
-            dcx.emit_err(IntLiteralTooLarge { span, limit })
+            dcx.create_err(IntLiteralTooLarge { span, limit })
         }
     }
 }
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index e9ddd66b5e8..c64d9bc1efe 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -3,6 +3,7 @@ use std::sync::OnceLock;
 
 use rustc_data_structures::profiling::VerboseTimingGuard;
 use rustc_fs_util::try_canonicalize;
+use rustc_hir::attrs::NativeLibKind;
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 
 use crate::session::Session;
@@ -17,69 +18,6 @@ impl Session {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
-#[derive(HashStable_Generic)]
-pub enum NativeLibKind {
-    /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
-    Static {
-        /// Whether to bundle objects from static library into produced rlib
-        bundle: Option<bool>,
-        /// Whether to link static library without throwing any object files away
-        whole_archive: Option<bool>,
-    },
-    /// Dynamic library (e.g. `libfoo.so` on Linux)
-    /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
-    Dylib {
-        /// Whether the dynamic library will be linked only if it satisfies some undefined symbols
-        as_needed: Option<bool>,
-    },
-    /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
-    /// On Linux, it refers to a generated shared library stub.
-    RawDylib,
-    /// A macOS-specific kind of dynamic libraries.
-    Framework {
-        /// Whether the framework will be linked only if it satisfies some undefined symbols
-        as_needed: Option<bool>,
-    },
-    /// Argument which is passed to linker, relative order with libraries and other arguments
-    /// is preserved
-    LinkArg,
-
-    /// Module imported from WebAssembly
-    WasmImportModule,
-
-    /// The library kind wasn't specified, `Dylib` is currently used as a default.
-    Unspecified,
-}
-
-impl NativeLibKind {
-    pub fn has_modifiers(&self) -> bool {
-        match self {
-            NativeLibKind::Static { bundle, whole_archive } => {
-                bundle.is_some() || whole_archive.is_some()
-            }
-            NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
-                as_needed.is_some()
-            }
-            NativeLibKind::RawDylib
-            | NativeLibKind::Unspecified
-            | NativeLibKind::LinkArg
-            | NativeLibKind::WasmImportModule => false,
-        }
-    }
-
-    pub fn is_statically_included(&self) -> bool {
-        matches!(self, NativeLibKind::Static { .. })
-    }
-
-    pub fn is_dllimport(&self) -> bool {
-        matches!(
-            self,
-            NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified
-        )
-    }
-}
-
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
 #[derive(HashStable_Generic)]
 pub struct NativeLib {
diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml
index 43a2d692577..2e45177e3b7 100644
--- a/compiler/rustc_span/Cargo.toml
+++ b/compiler/rustc_span/Cargo.toml
@@ -19,6 +19,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 scoped-tls = "1.0"
 sha1 = "0.10.0"
 sha2 = "0.10.1"
-tracing = "0.1"
+tracing.workspace = true
 unicode-width = "0.2.0"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 585968044bf..77260d07c99 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -466,6 +466,7 @@ symbols! {
         arm,
         arm_target_feature,
         array,
+        as_dash_needed: "as-needed",
         as_ptr,
         as_ref,
         as_str,
@@ -540,6 +541,7 @@ symbols! {
         att_syntax,
         attr,
         attr_literals,
+        attribute,
         attributes,
         audit_that,
         augmented_assignments,
@@ -592,6 +594,7 @@ symbols! {
         btreeset_iter,
         built,
         builtin_syntax,
+        bundle,
         c,
         c_dash_variadic,
         c_str,
@@ -817,6 +820,7 @@ symbols! {
         decl_macro,
         declare_lint_pass,
         decode,
+        decorated,
         default_alloc_error_handler,
         default_field_values,
         default_fn,
@@ -1075,6 +1079,7 @@ symbols! {
         format_macro,
         format_placeholder,
         format_unsafe_arg,
+        framework,
         freeze,
         freeze_impls,
         freg,
@@ -1295,6 +1300,7 @@ symbols! {
         link_arg_attribute,
         link_args,
         link_cfg,
+        link_dash_arg: "link-arg",
         link_llvm_intrinsics,
         link_name,
         link_ordinal,
@@ -1528,6 +1534,7 @@ symbols! {
         noop_method_borrow,
         noop_method_clone,
         noop_method_deref,
+        noprefix,
         noreturn,
         nostack,
         not,
@@ -1741,6 +1748,7 @@ symbols! {
         quote,
         range_inclusive_new,
         range_step,
+        raw_dash_dylib: "raw-dylib",
         raw_dylib,
         raw_dylib_elf,
         raw_eq,
@@ -2277,6 +2285,7 @@ symbols! {
         unchecked_shl,
         unchecked_shr,
         unchecked_sub,
+        undecorated,
         underscore_const_names,
         underscore_imports,
         underscore_lifetimes,
@@ -2365,6 +2374,7 @@ symbols! {
         vecdeque_iter,
         vecdeque_reserve,
         vector,
+        verbatim,
         version,
         vfp2,
         vis,
@@ -2389,6 +2399,7 @@ symbols! {
         weak_odr,
         where_clause_attrs,
         while_let,
+        whole_dash_archive: "whole-archive",
         width,
         windows,
         windows_subsystem,
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
index 0df9c7682bf..48e02dabdde 100644
--- a/compiler/rustc_symbol_mangling/Cargo.toml
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -15,5 +15,5 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 57c90a703f1..3c257bf38a5 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -5,7 +5,8 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
+object = { version = "0.37.0", default-features = false, features = ["elf", "macho"] }
 rustc_abi = { path = "../rustc_abi" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_error_messages = { path = "../rustc_error_messages" }
@@ -17,12 +18,6 @@ serde = "1.0.219"
 serde_derive = "1.0.219"
 serde_json = "1.0.59"
 serde_path_to_error = "0.1.17"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
-[dependencies.object]
-# tidy-alphabetical-start
-default-features = false
-features = ["elf", "macho"]
-version = "0.37.0"
-# tidy-alphabetical-end
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs
index 5f2a6f7ba38..7a7c63c475b 100644
--- a/compiler/rustc_target/src/callconv/mod.rs
+++ b/compiler/rustc_target/src/callconv/mod.rs
@@ -114,7 +114,7 @@ mod attr_impl {
     bitflags::bitflags! {
         impl ArgAttribute: u8 {
             const NoAlias   = 1 << 1;
-            const NoCapture = 1 << 2;
+            const CapturesAddress = 1 << 2;
             const NonNull   = 1 << 3;
             const ReadOnly  = 1 << 4;
             const InReg     = 1 << 5;
@@ -400,11 +400,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
         let mut attrs = ArgAttributes::new();
 
         // For non-immediate arguments the callee gets its own copy of
-        // the value on the stack, so there are no aliases. It's also
-        // program-invisible so can't possibly capture
+        // the value on the stack, so there are no aliases. The function
+        // can capture the address of the argument, but not the provenance.
         attrs
             .set(ArgAttribute::NoAlias)
-            .set(ArgAttribute::NoCapture)
+            .set(ArgAttribute::CapturesAddress)
             .set(ArgAttribute::NonNull)
             .set(ArgAttribute::NoUndef);
         attrs.pointee_size = layout.size;
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
index 1071105522d..6b79b98d1bf 100644
--- a/compiler/rustc_trait_selection/Cargo.toml
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
@@ -21,6 +21,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml
index 9f40f4d5c23..24360a94cc7 100644
--- a/compiler/rustc_traits/Cargo.toml
+++ b/compiler/rustc_traits/Cargo.toml
@@ -10,5 +10,5 @@ rustc_infer = { path = "../rustc_infer" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_span = { path = "../rustc_span" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml
index e61717e5e9c..2ac2b46cc58 100644
--- a/compiler/rustc_transmute/Cargo.toml
+++ b/compiler/rustc_transmute/Cargo.toml
@@ -11,12 +11,12 @@ rustc_hir = { path = "../rustc_hir", optional = true }
 rustc_middle = { path = "../rustc_middle", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
 smallvec = "1.8.1"
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [dev-dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index ce08b300cc8..394cde5a323 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-itertools = "0.12"
+itertools.workspace = true
 rustc_abi = { path = "../rustc_abi" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
@@ -20,5 +20,5 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
-tracing = "0.1"
+tracing.workspace = true
 # tidy-alphabetical-end
diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml
index d55e9b3b1be..1dba7fe4269 100644
--- a/compiler/rustc_type_ir/Cargo.toml
+++ b/compiler/rustc_type_ir/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-bitflags = "2.4.1"
+bitflags.workspace = true
 derive-where = "1.2.7"
 ena = "0.14.3"
 indexmap = "2.0.0"
@@ -19,8 +19,8 @@ rustc_serialize = { path = "../rustc_serialize", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
 rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
 smallvec = { version = "1.8.1", default-features = false, features = ["const_generics"] }
-thin-vec = "0.2.12"
-tracing = "0.1"
+thin-vec.workspace = true
+tracing.workspace = true
 # tidy-alphabetical-end
 
 [features]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 11fd4346ff5..1d0dd4be1b6 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2939,68 +2939,41 @@ impl SpecToString for i8 {
     }
 }
 
-// Generic/generated code can sometimes have multiple, nested references
-// for strings, including `&&&str`s that would never be written
-// by hand. This macro generates twelve layers of nested `&`-impl
-// for primitive strings.
-#[cfg(not(no_global_oom_handling))]
-macro_rules! to_string_str_wrap_in_ref {
-    {x $($x:ident)*} => {
-        &to_string_str_wrap_in_ref! { $($x)* }
-    };
-    {} => { str };
-}
-#[cfg(not(no_global_oom_handling))]
-macro_rules! to_string_expr_wrap_in_deref {
-    {$self:expr ; x $($x:ident)*} => {
-        *(to_string_expr_wrap_in_deref! { $self ; $($x)* })
-    };
-    {$self:expr ;} => { $self };
-}
 #[cfg(not(no_global_oom_handling))]
 macro_rules! to_string_str {
-    {$($($x:ident)*),+} => {
+    {$($type:ty,)*} => {
         $(
-            impl SpecToString for to_string_str_wrap_in_ref!($($x)*) {
+            impl SpecToString for $type {
                 #[inline]
                 fn spec_to_string(&self) -> String {
-                    String::from(to_string_expr_wrap_in_deref!(self ; $($x)*))
+                    let s: &str = self;
+                    String::from(s)
                 }
             }
-        )+
+        )*
     };
 }
 
 #[cfg(not(no_global_oom_handling))]
 to_string_str! {
-    x x x x x x x x x x x x,
-    x x x x x x x x x x x,
-    x x x x x x x x x x,
-    x x x x x x x x x,
-    x x x x x x x x,
-    x x x x x x x,
-    x x x x x x,
-    x x x x x,
-    x x x x,
-    x x x,
-    x x,
-    x,
-}
-
-#[cfg(not(no_global_oom_handling))]
-impl SpecToString for Cow<'_, str> {
-    #[inline]
-    fn spec_to_string(&self) -> String {
-        self[..].to_owned()
-    }
-}
-
-#[cfg(not(no_global_oom_handling))]
-impl SpecToString for String {
-    #[inline]
-    fn spec_to_string(&self) -> String {
-        self.to_owned()
-    }
+    Cow<'_, str>,
+    String,
+    // Generic/generated code can sometimes have multiple, nested references
+    // for strings, including `&&&str`s that would never be written
+    // by hand.
+    &&&&&&&&&&&&str,
+    &&&&&&&&&&&str,
+    &&&&&&&&&&str,
+    &&&&&&&&&str,
+    &&&&&&&&str,
+    &&&&&&&str,
+    &&&&&&str,
+    &&&&&str,
+    &&&&str,
+    &&&str,
+    &&str,
+    &str,
+    str,
 }
 
 #[cfg(not(no_global_oom_handling))]
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index c72eeb9a9c9..535c5a8e77b 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -267,39 +267,29 @@ pub const unsafe fn assert_unchecked(cond: bool) {
 #[inline(always)]
 #[stable(feature = "renamed_spin_loop", since = "1.49.0")]
 pub fn spin_loop() {
-    #[cfg(target_arch = "x86")]
-    {
-        // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
-        unsafe { crate::arch::x86::_mm_pause() };
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    {
-        // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
-        unsafe { crate::arch::x86_64::_mm_pause() };
-    }
-
-    #[cfg(target_arch = "riscv32")]
-    {
-        crate::arch::riscv32::pause();
-    }
-
-    #[cfg(target_arch = "riscv64")]
-    {
-        crate::arch::riscv64::pause();
-    }
-
-    #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
-    {
-        // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
-        unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) };
-    }
-
-    #[cfg(all(target_arch = "arm", target_feature = "v6"))]
-    {
-        // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
-        // with support for the v6 feature.
-        unsafe { crate::arch::arm::__yield() };
+    crate::cfg_select! {
+        target_arch = "x86" => {
+            // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
+            unsafe { crate::arch::x86::_mm_pause() }
+        }
+        target_arch = "x86_64" => {
+            // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
+            unsafe { crate::arch::x86_64::_mm_pause() }
+        }
+        target_arch = "riscv32" => crate::arch::riscv32::pause(),
+        target_arch = "riscv64" => crate::arch::riscv64::pause(),
+        any(target_arch = "aarch64", target_arch = "arm64ec") => {
+            // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
+            unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) }
+        }
+        all(target_arch = "arm", target_feature = "v6") => {
+            // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
+            // with support for the v6 feature.
+            unsafe { crate::arch::arm::__yield() }
+        }
+        target_arch = "loongarch32" => crate::arch::loongarch32::ibar::<0>(),
+        target_arch = "loongarch64" => crate::arch::loongarch64::ibar::<0>(),
+        _ => { /* do nothing */ }
     }
 }
 
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 69e6c100e76..4282b1af9f2 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -630,6 +630,13 @@ impl f128 {
 
     /// Converts radians to degrees.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// #![feature(f128)]
     /// # // FIXME(f16_f128): remove when `eqtf2` is available
@@ -645,13 +652,22 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_degrees(self) -> Self {
-        // Use a literal for better precision.
-        const PIS_IN_180: f128 = 57.2957795130823208767981548141051703324054724665643215491602_f128;
+        // The division here is correctly rounded with respect to the true value of 180/π.
+        // Although π is irrational and already rounded, the double rounding happens
+        // to produce correct result for f128.
+        const PIS_IN_180: f128 = 180.0 / consts::PI;
         self * PIS_IN_180
     }
 
     /// Converts degrees to radians.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// #![feature(f128)]
     /// # // FIXME(f16_f128): remove when `eqtf2` is available
@@ -668,7 +684,8 @@ impl f128 {
     #[unstable(feature = "f128", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_radians(self) -> f128 {
-        // Use a literal for better precision.
+        // Use a literal to avoid double rounding, consts::PI is already rounded,
+        // and dividing would round again.
         const RADS_PER_DEG: f128 =
             0.0174532925199432957692369076848861271344287188854172545609719_f128;
         self * RADS_PER_DEG
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index b66cef03d20..23a8661c14b 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -625,6 +625,13 @@ impl f16 {
 
     /// Converts radians to degrees.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// #![feature(f16)]
     /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@@ -640,13 +647,21 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_degrees(self) -> Self {
-        // Use a literal for better precision.
+        // Use a literal to avoid double rounding, consts::PI is already rounded,
+        // and dividing would round again.
         const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16;
         self * PIS_IN_180
     }
 
     /// Converts degrees to radians.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// #![feature(f16)]
     /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms
@@ -663,7 +678,8 @@ impl f16 {
     #[unstable(feature = "f16", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_radians(self) -> f16 {
-        // Use a literal for better precision.
+        // Use a literal to avoid double rounding, consts::PI is already rounded,
+        // and dividing would round again.
         const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16;
         self * RADS_PER_DEG
     }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index f8344da79ad..da08bfc5950 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -839,6 +839,13 @@ impl f32 {
 
     /// Converts radians to degrees.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// let angle = std::f32::consts::PI;
     ///
@@ -852,13 +859,21 @@ impl f32 {
     #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_degrees(self) -> f32 {
-        // Use a constant for better precision.
+        // Use a literal to avoid double rounding, consts::PI is already rounded,
+        // and dividing would round again.
         const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
         self * PIS_IN_180
     }
 
     /// Converts degrees to radians.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// let angle = 180.0f32;
     ///
@@ -872,6 +887,9 @@ impl f32 {
     #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_radians(self) -> f32 {
+        // The division here is correctly rounded with respect to the true value of π/180.
+        // Although π is irrational and already rounded, the double rounding happens
+        // to produce correct result for f32.
         const RADS_PER_DEG: f32 = consts::PI / 180.0;
         self * RADS_PER_DEG
     }
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 93da63c896e..dc0977cb147 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -856,6 +856,13 @@ impl f64 {
 
     /// Converts radians to degrees.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// let angle = std::f64::consts::PI;
     ///
@@ -869,14 +876,22 @@ impl f64 {
     #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_degrees(self) -> f64 {
-        // The division here is correctly rounded with respect to the true
-        // value of 180/π. (This differs from f32, where a constant must be
-        // used to ensure a correctly rounded result.)
-        self * (180.0f64 / consts::PI)
+        // The division here is correctly rounded with respect to the true value of 180/π.
+        // Although π is irrational and already rounded, the double rounding happens
+        // to produce correct result for f64.
+        const PIS_IN_180: f64 = 180.0 / consts::PI;
+        self * PIS_IN_180
     }
 
     /// Converts degrees to radians.
     ///
+    /// # Unspecified precision
+    ///
+    /// The precision of this function is non-deterministic. This means it varies by platform,
+    /// Rust version, and can even differ within the same execution from one invocation to the next.
+    ///
+    /// # Examples
+    ///
     /// ```
     /// let angle = 180.0_f64;
     ///
@@ -890,6 +905,9 @@ impl f64 {
     #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_radians(self) -> f64 {
+        // The division here is correctly rounded with respect to the true value of π/180.
+        // Although π is irrational and already rounded, the double rounding happens
+        // to produce correct result for f64.
         const RADS_PER_DEG: f64 = consts::PI / 180.0;
         self * RADS_PER_DEG
     }
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index e83e77344cf..fa09409b6da 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1961,6 +1961,42 @@ impl<T> Option<T> {
             _ => None,
         }
     }
+
+    /// Reduces two options into one, using the provided function if both are `Some`.
+    ///
+    /// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some(f(s, o))`.
+    /// Otherwise, if only one of `self` and `other` is `Some`, that one is returned.
+    /// If both `self` and `other` are `None`, `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(option_reduce)]
+    ///
+    /// let s12 = Some(12);
+    /// let s17 = Some(17);
+    /// let n = None;
+    /// let f = |a, b| a + b;
+    ///
+    /// assert_eq!(s12.reduce(s17, f), Some(29));
+    /// assert_eq!(s12.reduce(n, f), Some(12));
+    /// assert_eq!(n.reduce(s17, f), Some(17));
+    /// assert_eq!(n.reduce(n, f), None);
+    /// ```
+    #[unstable(feature = "option_reduce", issue = "144273")]
+    pub fn reduce<U, R, F>(self, other: Option<U>, f: F) -> Option<R>
+    where
+        T: Into<R>,
+        U: Into<R>,
+        F: FnOnce(T, U) -> R,
+    {
+        match (self, other) {
+            (Some(a), Some(b)) => Some(f(a, b)),
+            (Some(a), _) => Some(a.into()),
+            (_, Some(b)) => Some(b.into()),
+            _ => None,
+        }
+    }
 }
 
 impl<T, U> Option<(T, U)> {
diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs
index cafdcfa2c2e..7a68d393906 100644
--- a/library/core/src/panic/location.rs
+++ b/library/core/src/panic/location.rs
@@ -39,7 +39,7 @@ use crate::ptr::NonNull;
 pub struct Location<'a> {
     // A raw pointer is used rather than a reference because the pointer is valid for one more byte
     // than the length stored in this pointer; the additional byte is the NUL-terminator used by
-    // `Location::file_with_nul`.
+    // `Location::file_as_c_str`.
     filename: NonNull<str>,
     line: u32,
     col: u32,
@@ -195,7 +195,7 @@ impl<'a> Location<'a> {
     #[must_use]
     #[unstable(feature = "file_with_nul", issue = "141727")]
     #[inline]
-    pub const fn file_with_nul(&self) -> &'a CStr {
+    pub const fn file_as_c_str(&self) -> &'a CStr {
         let filename = self.filename.as_ptr();
 
         // SAFETY: The filename is valid for `filename_len+1` bytes, so this addition can't
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 1b6e84175b9..1a055a0a5ad 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -3072,7 +3072,7 @@ impl str {
     /// for example references to `Box<str>` or `Arc<str>`.
     #[inline]
     #[unstable(feature = "str_as_str", issue = "130366")]
-    pub fn as_str(&self) -> &str {
+    pub const fn as_str(&self) -> &str {
         self
     }
 }
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 4415b614817..b9b768f29d7 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -80,6 +80,7 @@
 #![feature(next_index)]
 #![feature(non_exhaustive_omitted_patterns_lint)]
 #![feature(numfmt)]
+#![feature(option_reduce)]
 #![feature(pattern)]
 #![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
diff --git a/library/std/src/sys/alloc/wasm.rs b/library/std/src/sys/alloc/wasm.rs
index c8fab992a88..48e2fdd4ecc 100644
--- a/library/std/src/sys/alloc/wasm.rs
+++ b/library/std/src/sys/alloc/wasm.rs
@@ -16,12 +16,15 @@
 //! The crate itself provides a global allocator which on wasm has no
 //! synchronization as there are no threads!
 
-// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
-#![allow(static_mut_refs)]
+use core::cell::SyncUnsafeCell;
 
 use crate::alloc::{GlobalAlloc, Layout, System};
 
-static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();
+struct SyncDlmalloc(dlmalloc::Dlmalloc);
+unsafe impl Sync for SyncDlmalloc {}
+
+static DLMALLOC: SyncUnsafeCell<SyncDlmalloc> =
+    SyncUnsafeCell::new(SyncDlmalloc(dlmalloc::Dlmalloc::new()));
 
 #[stable(feature = "alloc_system_type", since = "1.28.0")]
 unsafe impl GlobalAlloc for System {
@@ -30,7 +33,7 @@ unsafe impl GlobalAlloc for System {
         // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
         // Calling malloc() is safe because preconditions on this function match the trait method preconditions.
         let _lock = lock::lock();
-        unsafe { DLMALLOC.malloc(layout.size(), layout.align()) }
+        unsafe { (*DLMALLOC.get()).0.malloc(layout.size(), layout.align()) }
     }
 
     #[inline]
@@ -38,7 +41,7 @@ unsafe impl GlobalAlloc for System {
         // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
         // Calling calloc() is safe because preconditions on this function match the trait method preconditions.
         let _lock = lock::lock();
-        unsafe { DLMALLOC.calloc(layout.size(), layout.align()) }
+        unsafe { (*DLMALLOC.get()).0.calloc(layout.size(), layout.align()) }
     }
 
     #[inline]
@@ -46,7 +49,7 @@ unsafe impl GlobalAlloc for System {
         // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
         // Calling free() is safe because preconditions on this function match the trait method preconditions.
         let _lock = lock::lock();
-        unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) }
+        unsafe { (*DLMALLOC.get()).0.free(ptr, layout.size(), layout.align()) }
     }
 
     #[inline]
@@ -54,7 +57,7 @@ unsafe impl GlobalAlloc for System {
         // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
         // Calling realloc() is safe because preconditions on this function match the trait method preconditions.
         let _lock = lock::lock();
-        unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) }
+        unsafe { (*DLMALLOC.get()).0.realloc(ptr, layout.size(), layout.align(), new_size) }
     }
 }
 
diff --git a/library/std/src/sys/fs/mod.rs b/library/std/src/sys/fs/mod.rs
index dbd782f5018..0276bf6e64c 100644
--- a/library/std/src/sys/fs/mod.rs
+++ b/library/std/src/sys/fs/mod.rs
@@ -117,9 +117,18 @@ pub fn set_permissions(path: &Path, perm: FilePermissions) -> io::Result<()> {
 #[cfg(unix)]
 pub fn set_permissions_nofollow(path: &Path, perm: crate::fs::Permissions) -> io::Result<()> {
     use crate::fs::OpenOptions;
-    use crate::os::unix::fs::OpenOptionsExt;
 
-    OpenOptions::new().custom_flags(libc::O_NOFOLLOW).open(path)?.set_permissions(perm)
+    let mut options = OpenOptions::new();
+
+    // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it.
+    // Their filesystems do not have symbolic links, so no special handling is required.
+    #[cfg(not(any(target_os = "espidf", target_os = "horizon")))]
+    {
+        use crate::os::unix::fs::OpenOptionsExt;
+        options.custom_flags(libc::O_NOFOLLOW);
+    }
+
+    options.open(path)?.set_permissions(perm)
 }
 
 #[cfg(not(unix))]
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index abe79405984..26b4aaa8b5b 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -2025,8 +2025,6 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?}
             cmd.arg("--verbose");
         }
 
-        cmd.arg("--json");
-
         if builder.config.rustc_debug_assertions {
             cmd.arg("--with-rustc-debug-assertions");
         }
diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs
index 40006aca5c5..90fd57d976d 100644
--- a/src/bootstrap/src/utils/render_tests.rs
+++ b/src/bootstrap/src/utils/render_tests.rs
@@ -250,8 +250,14 @@ impl<'a> Renderer<'a> {
                 if failure.stdout.is_some() || failure.message.is_some() {
                     println!("---- {} stdout ----", failure.name);
                     if let Some(stdout) = &failure.stdout {
-                        println!("{stdout}");
+                        // Captured test output normally ends with a newline,
+                        // so only use `println!` if it doesn't.
+                        print!("{stdout}");
+                        if !stdout.ends_with('\n') {
+                            println!("\n\\ (no newline at end of output)");
+                        }
                     }
+                    println!("---- {} stdout end ----", failure.name);
                     if let Some(message) = &failure.message {
                         println!("NOTE: {message}");
                     }
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index bb28e3abbf3..25c929a1dba 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -196,7 +196,7 @@ to enable.
 
 ### Document keywords
 
-This is for Rust compiler internal use only.
+This is for internal use in the std library.
 
 Rust keywords are documented in the standard library (look for `match` for example).
 
@@ -211,6 +211,23 @@ To do so, the `#[doc(keyword = "...")]` attribute is used. Example:
 mod empty_mod {}
 ```
 
+### Document builtin attributes
+
+This is for internal use in the std library.
+
+Rust builtin attributes are documented in the standard library (look for `repr` for example).
+
+To do so, the `#[doc(attribute = "...")]` attribute is used. Example:
+
+```rust
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
+
+/// Some documentation about the attribute.
+#[doc(attribute = "repr")]
+mod empty_mod {}
+```
+
 ### Use the Rust logo as the crate logo
 
 This is for official Rust project use only.
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 5d36ffc2d3a..02a3a4e0de4 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -13,7 +13,7 @@ arrayvec = { version = "0.7", default-features = false }
 askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
 base64 = "0.21.7"
 indexmap = "2"
-itertools = "0.12"
+itertools.workspace = true
 minifier = { version = "0.3.5", default-features = false }
 pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }
 regex = "1"
@@ -24,8 +24,8 @@ smallvec = "1.8.1"
 stringdex = { version = "0.0.1-alpha4" }
 tempfile = "3"
 threadpool = "1.8.1"
-tracing = "0.1"
 tracing-tree = "0.3.0"
+tracing.workspace = true
 unicode-segmentation = "1.9"
 # tidy-alphabetical-end
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 0d98c64bbde..8461e15c6c3 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -572,30 +572,30 @@ pub(crate) fn build_impl(
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
 
-    // Return if the trait itself or any types of the generic parameters are doc(hidden).
-    let mut stack: Vec<&Type> = vec![&for_];
+    if !document_hidden {
+        // Return if the trait itself or any types of the generic parameters are doc(hidden).
+        let mut stack: Vec<&Type> = vec![&for_];
 
-    if let Some(did) = trait_.as_ref().map(|t| t.def_id())
-        && !document_hidden
-        && tcx.is_doc_hidden(did)
-    {
-        return;
-    }
-
-    if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
-        stack.extend(generics);
-    }
-
-    while let Some(ty) = stack.pop() {
-        if let Some(did) = ty.def_id(&cx.cache)
-            && !document_hidden
+        if let Some(did) = trait_.as_ref().map(|t| t.def_id())
             && tcx.is_doc_hidden(did)
         {
             return;
         }
-        if let Some(generics) = ty.generics() {
+
+        if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
             stack.extend(generics);
         }
+
+        while let Some(ty) = stack.pop() {
+            if let Some(did) = ty.def_id(&cx.cache)
+                && tcx.is_doc_hidden(did)
+            {
+                return;
+            }
+            if let Some(generics) = ty.generics() {
+                stack.extend(generics);
+            }
+        }
     }
 
     if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 92bd4a498ca..fcff15650ce 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -226,15 +226,28 @@ impl ExternalCrate {
     }
 
     pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = (DefId, Symbol)> {
-        fn as_keyword(did: DefId, tcx: TyCtxt<'_>) -> Option<(DefId, Symbol)> {
+        self.retrieve_keywords_or_documented_attributes(tcx, sym::keyword)
+    }
+    pub(crate) fn documented_attributes(
+        &self,
+        tcx: TyCtxt<'_>,
+    ) -> impl Iterator<Item = (DefId, Symbol)> {
+        self.retrieve_keywords_or_documented_attributes(tcx, sym::attribute)
+    }
+
+    fn retrieve_keywords_or_documented_attributes(
+        &self,
+        tcx: TyCtxt<'_>,
+        name: Symbol,
+    ) -> impl Iterator<Item = (DefId, Symbol)> {
+        let as_target = move |did: DefId, tcx: TyCtxt<'_>| -> Option<(DefId, Symbol)> {
             tcx.get_attrs(did, sym::doc)
                 .flat_map(|attr| attr.meta_item_list().unwrap_or_default())
-                .filter(|meta| meta.has_name(sym::keyword))
+                .filter(|meta| meta.has_name(name))
                 .find_map(|meta| meta.value_str())
                 .map(|value| (did, value))
-        }
-
-        self.mapped_root_modules(tcx, as_keyword)
+        };
+        self.mapped_root_modules(tcx, as_target)
     }
 
     pub(crate) fn primitives(
@@ -592,6 +605,20 @@ impl Item {
     pub(crate) fn is_keyword(&self) -> bool {
         self.type_() == ItemType::Keyword
     }
+    pub(crate) fn is_attribute(&self) -> bool {
+        self.type_() == ItemType::Attribute
+    }
+    /// Returns `true` if the item kind is one of the following:
+    ///
+    /// * `ItemType::Primitive`
+    /// * `ItemType::Keyword`
+    /// * `ItemType::Attribute`
+    ///
+    /// They are considered fake because they only exist thanks to their
+    /// `#[doc(primitive|keyword|attribute)]` attribute.
+    pub(crate) fn is_fake_item(&self) -> bool {
+        matches!(self.type_(), ItemType::Primitive | ItemType::Keyword | ItemType::Attribute)
+    }
     pub(crate) fn is_stripped(&self) -> bool {
         match self.kind {
             StrippedItem(..) => true,
@@ -735,7 +762,9 @@ impl Item {
             // Primitives and Keywords are written in the source code as private modules.
             // The modules need to be private so that nobody actually uses them, but the
             // keywords and primitives that they are documenting are public.
-            ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public),
+            ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) | ItemKind::AttributeItem => {
+                return Some(Visibility::Public);
+            }
             // Variant fields inherit their enum's visibility.
             StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => {
                 return None;
@@ -942,7 +971,12 @@ pub(crate) enum ItemKind {
     AssocTypeItem(Box<TypeAlias>, Vec<GenericBound>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemKind>),
+    /// This item represents a module with a `#[doc(keyword = "...")]` attribute which is used
+    /// to generate documentation for Rust keywords.
     KeywordItem,
+    /// This item represents a module with a `#[doc(attribute = "...")]` attribute which is used
+    /// to generate documentation for Rust builtin attributes.
+    AttributeItem,
 }
 
 impl ItemKind {
@@ -983,7 +1017,8 @@ impl ItemKind {
             | RequiredAssocTypeItem(..)
             | AssocTypeItem(..)
             | StrippedItem(_)
-            | KeywordItem => [].iter(),
+            | KeywordItem
+            | AttributeItem => [].iter(),
         }
     }
 
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 813fdee57e1..6fc1e43c724 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -60,6 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
     let local_crate = ExternalCrate { crate_num: LOCAL_CRATE };
     let primitives = local_crate.primitives(cx.tcx);
     let keywords = local_crate.keywords(cx.tcx);
+    let documented_attributes = local_crate.documented_attributes(cx.tcx);
     {
         let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() };
         m.items.extend(primitives.map(|(def_id, prim)| {
@@ -73,6 +74,9 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
         m.items.extend(keywords.map(|(def_id, kw)| {
             Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem, cx)
         }));
+        m.items.extend(documented_attributes.into_iter().map(|(def_id, kw)| {
+            Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::AttributeItem, cx)
+        }));
     }
 
     Crate { module, external_traits: Box::new(mem::take(&mut cx.external_traits)) }
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index c03d16ad081..ee5f260615d 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -96,7 +96,8 @@ pub(crate) trait DocFolder: Sized {
             | ImplAssocConstItem(..)
             | RequiredAssocTypeItem(..)
             | AssocTypeItem(..)
-            | KeywordItem => kind,
+            | KeywordItem
+            | AttributeItem => kind,
         }
     }
 
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index cb6837dd614..29b4c4caaf8 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -372,7 +372,8 @@ impl DocFolder for CacheBuilder<'_, '_> {
             | clean::RequiredAssocTypeItem(..)
             | clean::AssocTypeItem(..)
             | clean::StrippedItem(..)
-            | clean::KeywordItem => {
+            | clean::KeywordItem
+            | clean::AttributeItem => {
                 // FIXME: Do these need handling?
                 // The person writing this comment doesn't know.
                 // So would rather leave them to an expert,
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index 142a9d7d8af..e94ef517309 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -57,6 +57,7 @@ pub(crate) enum ItemType {
     TraitAlias = 25,
     // This number is reserved for use in JavaScript
     // Generic = 26,
+    Attribute = 27,
 }
 
 impl Serialize for ItemType {
@@ -148,6 +149,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
             clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType,
             clean::ForeignTypeItem => ItemType::ForeignType,
             clean::KeywordItem => ItemType::Keyword,
+            clean::AttributeItem => ItemType::Attribute,
             clean::TraitAliasItem(..) => ItemType::TraitAlias,
             clean::ProcMacroItem(mac) => match mac.kind {
                 MacroKind::Bang => ItemType::Macro,
@@ -236,6 +238,7 @@ impl ItemType {
             ItemType::ProcAttribute => "attr",
             ItemType::ProcDerive => "derive",
             ItemType::TraitAlias => "traitalias",
+            ItemType::Attribute => "attribute",
         }
     }
     pub(crate) fn is_method(&self) -> bool {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index faaecaf0cbb..5f92ab2fada 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -218,7 +218,7 @@ impl<'tcx> Context<'tcx> {
         } else {
             it.name.as_ref().unwrap().as_str()
         };
-        if !it.is_primitive() && !it.is_keyword() {
+        if !it.is_fake_item() {
             if !is_module {
                 title.push_str(" in ");
             }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 673947ad308..6db90c9bf2a 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2535,6 +2535,7 @@ pub(crate) enum ItemSection {
     AssociatedConstants,
     ForeignTypes,
     Keywords,
+    Attributes,
     AttributeMacros,
     DeriveMacros,
     TraitAliases,
@@ -2567,6 +2568,7 @@ impl ItemSection {
             AssociatedConstants,
             ForeignTypes,
             Keywords,
+            Attributes,
             AttributeMacros,
             DeriveMacros,
             TraitAliases,
@@ -2596,6 +2598,7 @@ impl ItemSection {
             Self::AssociatedConstants => "associated-consts",
             Self::ForeignTypes => "foreign-types",
             Self::Keywords => "keywords",
+            Self::Attributes => "attributes",
             Self::AttributeMacros => "attributes",
             Self::DeriveMacros => "derives",
             Self::TraitAliases => "trait-aliases",
@@ -2625,6 +2628,7 @@ impl ItemSection {
             Self::AssociatedConstants => "Associated Constants",
             Self::ForeignTypes => "Foreign Types",
             Self::Keywords => "Keywords",
+            Self::Attributes => "Attributes",
             Self::AttributeMacros => "Attribute Macros",
             Self::DeriveMacros => "Derive Macros",
             Self::TraitAliases => "Trait Aliases",
@@ -2655,6 +2659,7 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection {
         ItemType::AssocConst => ItemSection::AssociatedConstants,
         ItemType::ForeignType => ItemSection::ForeignTypes,
         ItemType::Keyword => ItemSection::Keywords,
+        ItemType::Attribute => ItemSection::Attributes,
         ItemType::ProcAttribute => ItemSection::AttributeMacros,
         ItemType::ProcDerive => ItemSection::DeriveMacros,
         ItemType::TraitAlias => ItemSection::TraitAliases,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index b86a2c94697..afa438f2596 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -173,6 +173,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Disp
             clean::ConstantItem(..) => "Constant ",
             clean::ForeignTypeItem => "Foreign Type ",
             clean::KeywordItem => "Keyword ",
+            clean::AttributeItem => "Attribute ",
             clean::TraitAliasItem(..) => "Trait Alias ",
             _ => {
                 // We don't generate pages for any other type.
@@ -193,7 +194,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Disp
         let src_href =
             if cx.info.include_sources && !item.is_primitive() { cx.src_href(item) } else { None };
 
-        let path_components = if item.is_primitive() || item.is_keyword() {
+        let path_components = if item.is_fake_item() {
             vec![]
         } else {
             let cur = &cx.current;
@@ -252,7 +253,9 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Disp
             clean::ForeignTypeItem => {
                 write!(buf, "{}", item_foreign_type(cx, item))
             }
-            clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)),
+            clean::KeywordItem | clean::AttributeItem => {
+                write!(buf, "{}", item_keyword_or_attribute(cx, item))
+            }
             clean::TraitAliasItem(ta) => {
                 write!(buf, "{}", item_trait_alias(cx, item, ta))
             }
@@ -2151,7 +2154,7 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     })
 }
 
-fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
+fn item_keyword_or_attribute(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     document(cx, it, None, HeadingOffset::H2)
 }
 
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index a3c6bf98161..5c02e2eb26a 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -75,6 +75,7 @@ nav.sub {
 	--function-link-color: #ad7c37;
 	--macro-link-color: #068000;
 	--keyword-link-color: #3873ad;
+	--attribute-link-color: #3873ad;
 	--mod-link-color: #3873ad;
 	--link-color: #3873ad;
 	--sidebar-link-color: #356da4;
@@ -180,6 +181,7 @@ nav.sub {
 		--function-link-color: #2bab63;
 		--macro-link-color: #09bd00;
 		--keyword-link-color: #d2991d;
+		--attribute-link-color: #d2991d;
 		--mod-link-color:  #d2991d;
 		--link-color: #d2991d;
 		--sidebar-link-color: #fdbf35;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 86f1a42bc01..09d289d570c 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -400,6 +400,10 @@ span.keyword, a.keyword {
 	color: var(--keyword-link-color);
 }
 
+span.attribute, a.attribute {
+	color: var(--attribute-link-color);
+}
+
 a {
 	color: var(--link-color);
 	text-decoration: none;
@@ -3190,6 +3194,7 @@ by default.
 	--function-link-color: #ad7c37;
 	--macro-link-color: #068000;
 	--keyword-link-color: #3873ad;
+	--attribute-link-color: #3873ad;
 	--mod-link-color: #3873ad;
 	--link-color: #3873ad;
 	--sidebar-link-color: #356da4;
@@ -3294,6 +3299,7 @@ by default.
 	--function-link-color: #2bab63;
 	--macro-link-color: #09bd00;
 	--keyword-link-color: #d2991d;
+	--attribute-link-color: #d2991d;
 	--mod-link-color:  #d2991d;
 	--link-color: #d2991d;
 	--sidebar-link-color: #fdbf35;
@@ -3407,6 +3413,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--function-link-color: #fdd687;
 	--macro-link-color: #a37acc;
 	--keyword-link-color: #39afd7;
+	--attribute-link-color: #39afd7;
 	--mod-link-color: #39afd7;
 	--link-color: #39afd7;
 	--sidebar-link-color: #53b1db;
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 4fcba5f120b..75febd6f737 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -790,6 +790,7 @@ function preLoadCss(cssUrl) {
             //block("associatedconstant", "associated-consts", "Associated Constants");
             block("foreigntype", "foreign-types", "Foreign Types");
             block("keyword", "keywords", "Keywords");
+            block("attribute", "attributes", "Attributes");
             block("attr", "attributes", "Attribute Macros");
             block("derive", "derives", "Derive Macros");
             block("traitalias", "trait-aliases", "Trait Aliases");
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 3fb4db3a89c..b003bcc7bf9 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -119,6 +119,7 @@ const itemTypes = [
     "derive",
     "traitalias", // 25
     "generic",
+    "attribute",
 ];
 
 // used for special search precedence
@@ -2058,7 +2059,7 @@ class DocSearch {
                 displayPath = item.modulePath + "::";
                 href = this.rootPath + item.modulePath.replace(/::/g, "/") +
                     "/index.html#reexport." + name;
-            } else if (type === "primitive" || type === "keyword") {
+            } else if (type === "primitive" || type === "keyword" || type === "attribute") {
                 displayPath = "";
                 exactPath = "";
                 href = this.rootPath + path.replace(/::/g, "/") +
@@ -4560,6 +4561,8 @@ const longItemTypes = [
     "attribute macro",
     "derive macro",
     "trait alias",
+    "",
+    "attribute",
 ];
 // @ts-expect-error
 let currentResults;
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 5fab8ad2a4b..f0520716228 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -52,7 +52,7 @@ impl JsonRenderer<'_> {
         let clean::ItemInner { name, item_id, .. } = *item.inner;
         let id = self.id_from_item(item);
         let inner = match item.kind {
-            clean::KeywordItem => return None,
+            clean::KeywordItem | clean::AttributeItem => return None,
             clean::StrippedItem(ref inner) => {
                 match &**inner {
                     // We document stripped modules as with `Module::is_stripped` set to
@@ -85,7 +85,7 @@ impl JsonRenderer<'_> {
     fn ids(&self, items: &[clean::Item]) -> Vec<Id> {
         items
             .iter()
-            .filter(|i| !i.is_stripped() && !i.is_keyword())
+            .filter(|i| !i.is_stripped() && !i.is_keyword() && !i.is_attribute())
             .map(|i| self.id_from_item(i))
             .collect()
     }
@@ -93,7 +93,10 @@ impl JsonRenderer<'_> {
     fn ids_keeping_stripped(&self, items: &[clean::Item]) -> Vec<Option<Id>> {
         items
             .iter()
-            .map(|i| (!i.is_stripped() && !i.is_keyword()).then(|| self.id_from_item(i)))
+            .map(|i| {
+                (!i.is_stripped() && !i.is_keyword() && !i.is_attribute())
+                    .then(|| self.id_from_item(i))
+            })
             .collect()
     }
 }
@@ -332,8 +335,8 @@ fn from_clean_item(item: &clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum
             bounds: b.into_json(renderer),
             type_: Some(t.item_type.as_ref().unwrap_or(&t.type_).into_json(renderer)),
         },
-        // `convert_item` early returns `None` for stripped items and keywords.
-        KeywordItem => unreachable!(),
+        // `convert_item` early returns `None` for stripped items, keywords and attributes.
+        KeywordItem | AttributeItem => unreachable!(),
         StrippedItem(inner) => {
             match inner.as_ref() {
                 ModuleItem(m) => ItemEnum::Module(Module {
@@ -887,6 +890,7 @@ impl FromClean<ItemType> for ItemKind {
             AssocType => ItemKind::AssocType,
             ForeignType => ItemKind::ExternType,
             Keyword => ItemKind::Keyword,
+            Attribute => ItemKind::Attribute,
             TraitAlias => ItemKind::TraitAlias,
             ProcAttribute => ItemKind::ProcAttribute,
             ProcDerive => ItemKind::ProcDerive,
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 8028afea363..e0ea760cf3b 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -67,6 +67,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
                 | clean::ImportItem(_)
                 | clean::PrimitiveItem(_)
                 | clean::KeywordItem
+                | clean::AttributeItem
                 | clean::ModuleItem(_)
                 | clean::TraitAliasItem(_)
                 | clean::ForeignFunctionItem(..)
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index bad51d7f5b2..719b7c6ab89 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -19,7 +19,7 @@ use rustc_hir::{Mutability, Safety};
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_middle::{bug, span_bug, ty};
 use rustc_resolve::rustdoc::{
-    MalformedGenerics, has_primitive_or_keyword_docs, prepare_to_doc_link_resolution,
+    MalformedGenerics, has_primitive_or_keyword_or_attribute_docs, prepare_to_doc_link_resolution,
     source_span_for_markdown_range, strip_generics_from_path,
 };
 use rustc_session::config::CrateType;
@@ -1073,7 +1073,7 @@ impl LinkCollector<'_, '_> {
             && let Some(def_id) = item.item_id.as_def_id()
             && let Some(def_id) = def_id.as_local()
             && !self.cx.tcx.effective_visibilities(()).is_exported(def_id)
-            && !has_primitive_or_keyword_docs(&item.attrs.other_attrs)
+            && !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs)
         {
             // Skip link resolution for non-exported items.
             return;
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs
index 14ec58702e3..5139ca301dd 100644
--- a/src/librustdoc/passes/propagate_stability.rs
+++ b/src/librustdoc/passes/propagate_stability.rs
@@ -106,7 +106,8 @@ impl DocFolder for StabilityPropagator<'_, '_> {
                     | ItemKind::RequiredAssocTypeItem(..)
                     | ItemKind::AssocTypeItem(..)
                     | ItemKind::PrimitiveItem(..)
-                    | ItemKind::KeywordItem => own_stability,
+                    | ItemKind::KeywordItem
+                    | ItemKind::AttributeItem => own_stability,
 
                     ItemKind::StrippedItem(..) => unreachable!(),
                 }
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index eedbbca0f8d..99d22526f85 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -133,6 +133,8 @@ impl DocFolder for Stripper<'_, '_> {
 
             // Keywords are never stripped
             clean::KeywordItem => {}
+            // Attributes are never stripped
+            clean::AttributeItem => {}
         }
 
         let fastreturn = match i.kind {
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index b8b619514aa..4d31409afe8 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -49,7 +49,8 @@ pub(crate) trait DocVisitor<'a>: Sized {
             | ImplAssocConstItem(..)
             | RequiredAssocTypeItem(..)
             | AssocTypeItem(..)
-            | KeywordItem => {}
+            | KeywordItem
+            | AttributeItem => {}
         }
     }
 
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 9a1f898064f52269bc94675dcbd620b46d45d17
+Subproject 19f0a49c5c3f4ba88b5e7ac620b9a0d8574c09c
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 40f89009a43..658d3791d25 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -37,8 +37,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
 // are deliberately not in a doc comment, because they need not be in public docs.)
 //
-// Latest feature: Add Attribute::MacroUse
-pub const FORMAT_VERSION: u32 = 55;
+// Latest feature: Add `ItemKind::Attribute`.
+pub const FORMAT_VERSION: u32 = 56;
 
 /// The root of the emitted JSON blob.
 ///
@@ -552,6 +552,11 @@ pub enum ItemKind {
     /// [`Item`]s of this kind only come from the come library and exist solely
     /// to carry documentation for the respective keywords.
     Keyword,
+    /// An attribute declaration.
+    ///
+    /// [`Item`]s of this kind only come from the core library and exist solely
+    /// to carry documentation for the respective builtin attributes.
+    Attribute,
 }
 
 /// Specific fields of an item.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 623d536836b4cde09ce38609232a024d5b25da8
+Subproject a6c58d43051d01d83f55a3e61ef5f5b2b0dd6bd
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index cdada5a2230..220c29cec49 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -28,8 +28,8 @@ rustfix = "0.8.1"
 semver = { version = "1.0.23", features = ["serde"] }
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
-tracing = "0.1"
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["ansi", "env-filter", "fmt", "parking_lot", "smallvec"] }
+tracing.workspace = true
 unified-diff = "0.2.1"
 walkdir = "2"
 # tidy-alphabetical-end
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7fc80c1edb1..b72c0b7ed20 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -8,7 +8,7 @@ use camino::{Utf8Path, Utf8PathBuf};
 use semver::Version;
 use serde::de::{Deserialize, Deserializer, Error as _};
 
-use crate::executor::{ColorConfig, OutputFormat};
+use crate::executor::ColorConfig;
 use crate::fatal;
 use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum};
 
@@ -565,13 +565,6 @@ pub struct Config {
     /// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.
     pub verbose: bool,
 
-    /// (Useless) Adjust libtest output format.
-    ///
-    /// FIXME: the hand-rolled executor does not support non-JSON output, because `compiletest` need
-    /// to package test outcome as `libtest`-esque JSON that `bootstrap` can intercept *anyway*.
-    /// However, now that we don't use the `libtest` executor, this is useless.
-    pub format: OutputFormat,
-
     /// Whether to use colors in test output.
     ///
     /// Note: the exact control mechanism is delegated to [`colored`].
@@ -768,7 +761,6 @@ impl Config {
             adb_device_status: Default::default(),
             lldb_python_dir: Default::default(),
             verbose: Default::default(),
-            format: Default::default(),
             color: Default::default(),
             remote_test_client: Default::default(),
             compare_mode: Default::default(),
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
index df64f12784f..fdd7155c21f 100644
--- a/src/tools/compiletest/src/executor.rs
+++ b/src/tools/compiletest/src/executor.rs
@@ -1,5 +1,9 @@
 //! This module contains a reimplementation of the subset of libtest
 //! functionality needed by compiletest.
+//!
+//! FIXME(Zalathar): Much of this code was originally designed to mimic libtest
+//! as closely as possible, for ease of migration. Now that libtest is no longer
+//! used, we can potentially redesign things to be a better fit for compiletest.
 
 use std::borrow::Cow;
 use std::collections::HashMap;
@@ -207,7 +211,7 @@ impl TestOutcome {
 ///
 /// Adapted from `filter_tests` in libtest.
 ///
-/// FIXME(#139660): After the libtest dependency is removed, redesign the whole filtering system to
+/// FIXME(#139660): Now that libtest has been removed, redesign the whole filtering system to
 /// do a better job of understanding and filtering _paths_, instead of being tied to libtest's
 /// substring/exact matching behaviour.
 fn filter_tests(opts: &Config, tests: Vec<CollectedTest>) -> Vec<CollectedTest> {
@@ -249,7 +253,7 @@ fn get_concurrency() -> usize {
     }
 }
 
-/// Information needed to create a `test::TestDescAndFn`.
+/// Information that was historically needed to create a libtest `TestDescAndFn`.
 pub(crate) struct CollectedTest {
     pub(crate) desc: CollectedTestDesc,
     pub(crate) config: Arc<Config>,
@@ -257,7 +261,7 @@ pub(crate) struct CollectedTest {
     pub(crate) revision: Option<String>,
 }
 
-/// Information needed to create a `test::TestDesc`.
+/// Information that was historically needed to create a libtest `TestDesc`.
 pub(crate) struct CollectedTestDesc {
     pub(crate) name: String,
     pub(crate) ignore: bool,
@@ -274,18 +278,6 @@ pub enum ColorConfig {
     NeverColor,
 }
 
-/// Format of the test results output.
-#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
-pub enum OutputFormat {
-    /// Verbose output
-    Pretty,
-    /// Quiet output
-    #[default]
-    Terse,
-    /// JSON output
-    Json,
-}
-
 /// Whether test is expected to panic or not.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub(crate) enum ShouldPanic {
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 469dd68207e..58f7c6b5071 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -43,7 +43,7 @@ use crate::common::{
     expected_output_path, output_base_dir, output_relative_path,
 };
 use crate::directives::DirectivesCache;
-use crate::executor::{CollectedTest, ColorConfig, OutputFormat};
+use crate::executor::{CollectedTest, ColorConfig};
 use crate::util::logv;
 
 /// Creates the `Config` instance for this invocation of compiletest.
@@ -137,9 +137,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "overwrite stderr/stdout files instead of complaining about a mismatch",
         )
         .optflag("", "fail-fast", "stop as soon as possible after any test fails")
-        .optflag("", "quiet", "print one character per test instead of one line")
         .optopt("", "color", "coloring: auto, always, never", "WHEN")
-        .optflag("", "json", "emit json output instead of plaintext output")
         .optopt("", "target", "the target to build for", "TARGET")
         .optopt("", "host", "the host to build for", "HOST")
         .optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH")
@@ -203,7 +201,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "COMMAND",
         )
         .reqopt("", "minicore-path", "path to minicore aux library", "PATH")
-        .optflag("N", "no-new-executor", "disables the new test executor, and uses libtest instead")
         .optopt(
             "",
             "debugger",
@@ -436,12 +433,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
             && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
         lldb_python_dir: matches.opt_str("lldb-python-dir"),
         verbose: matches.opt_present("verbose"),
-        format: match (matches.opt_present("quiet"), matches.opt_present("json")) {
-            (true, true) => panic!("--quiet and --json are incompatible"),
-            (true, false) => OutputFormat::Terse,
-            (false, true) => OutputFormat::Json,
-            (false, false) => OutputFormat::Pretty,
-        },
         only_modified: matches.opt_present("only-modified"),
         color,
         remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from),
@@ -527,7 +518,6 @@ pub fn log_config(config: &Config) {
     logv(c, format!("target-linker: {:?}", config.target_linker));
     logv(c, format!("host-linker: {:?}", config.host_linker));
     logv(c, format!("verbose: {}", config.verbose));
-    logv(c, format!("format: {:?}", config.format));
     logv(c, format!("minicore_path: {}", config.minicore_path));
     logv(c, "\n".to_string());
 }
@@ -601,7 +591,7 @@ pub fn run_tests(config: Arc<Config>) {
         configs.push(config.clone());
     };
 
-    // Discover all of the tests in the test suite directory, and build a libtest
+    // Discover all of the tests in the test suite directory, and build a `CollectedTest`
     // structure for each test (or each revision of a multi-revision test).
     let mut tests = Vec::new();
     for c in configs {
@@ -613,50 +603,35 @@ pub fn run_tests(config: Arc<Config>) {
     // Delegate to the executor to filter and run the big list of test structures
     // created during test discovery. When the executor decides to run a test,
     // it will return control to the rest of compiletest by calling `runtest::run`.
-    // FIXME(Zalathar): Once we're confident that we won't need to revert the
-    // removal of the libtest-based executor, remove this Result and other
-    // remnants of the old executor.
-    let res: io::Result<bool> = Ok(executor::run_tests(&config, tests));
-
-    // Check the outcome reported by libtest.
-    match res {
-        Ok(true) => {}
-        Ok(false) => {
-            // We want to report that the tests failed, but we also want to give
-            // some indication of just what tests we were running. Especially on
-            // CI, where there can be cross-compiled tests for a lot of
-            // architectures, without this critical information it can be quite
-            // easy to miss which tests failed, and as such fail to reproduce
-            // the failure locally.
-
-            let mut msg = String::from("Some tests failed in compiletest");
-            write!(msg, " suite={}", config.suite).unwrap();
-
-            if let Some(compare_mode) = config.compare_mode.as_ref() {
-                write!(msg, " compare_mode={}", compare_mode).unwrap();
-            }
+    let ok = executor::run_tests(&config, tests);
+
+    // Check the outcome reported by the executor.
+    if !ok {
+        // We want to report that the tests failed, but we also want to give
+        // some indication of just what tests we were running. Especially on
+        // CI, where there can be cross-compiled tests for a lot of
+        // architectures, without this critical information it can be quite
+        // easy to miss which tests failed, and as such fail to reproduce
+        // the failure locally.
+
+        let mut msg = String::from("Some tests failed in compiletest");
+        write!(msg, " suite={}", config.suite).unwrap();
+
+        if let Some(compare_mode) = config.compare_mode.as_ref() {
+            write!(msg, " compare_mode={}", compare_mode).unwrap();
+        }
 
-            if let Some(pass_mode) = config.force_pass_mode.as_ref() {
-                write!(msg, " pass_mode={}", pass_mode).unwrap();
-            }
+        if let Some(pass_mode) = config.force_pass_mode.as_ref() {
+            write!(msg, " pass_mode={}", pass_mode).unwrap();
+        }
 
-            write!(msg, " mode={}", config.mode).unwrap();
-            write!(msg, " host={}", config.host).unwrap();
-            write!(msg, " target={}", config.target).unwrap();
+        write!(msg, " mode={}", config.mode).unwrap();
+        write!(msg, " host={}", config.host).unwrap();
+        write!(msg, " target={}", config.target).unwrap();
 
-            println!("{msg}");
+        println!("{msg}");
 
-            std::process::exit(1);
-        }
-        Err(e) => {
-            // We don't know if tests passed or not, but if there was an error
-            // during testing we don't want to just succeed (we may not have
-            // tested something), so fail.
-            //
-            // This should realistically "never" happen, so don't try to make
-            // this a pretty error message.
-            panic!("I/O failure during tests: {:?}", e);
-        }
+        std::process::exit(1);
     }
 }
 
@@ -691,7 +666,11 @@ impl TestCollector {
 ///
 /// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests),
 /// regardless of whether any filters/tests were specified on the command-line,
-/// because filtering is handled later by libtest.
+/// because filtering is handled later by code that was copied from libtest.
+///
+/// FIXME(Zalathar): Now that we no longer rely on libtest, try to overhaul
+/// test discovery to take into account the filters/tests specified on the
+/// command-line, instead of having to enumerate everything.
 pub(crate) fn collect_and_make_tests(config: Arc<Config>) -> Vec<CollectedTest> {
     debug!("making tests from {}", config.src_test_suite_root);
     let common_inputs_stamp = common_inputs_stamp(&config);
@@ -805,7 +784,7 @@ fn modified_tests(config: &Config, dir: &Utf8Path) -> Result<Vec<Utf8PathBuf>, S
 }
 
 /// Recursively scans a directory to find test files and create test structures
-/// that will be handed over to libtest.
+/// that will be handed over to the executor.
 fn collect_tests_from_dir(
     cx: &TestCollectorCx,
     dir: &Utf8Path,
@@ -871,7 +850,7 @@ fn collect_tests_from_dir(
             if is_test(file_name)
                 && (!cx.config.only_modified || cx.modified_tests.contains(&file_path))
             {
-                // We found a test file, so create the corresponding libtest structures.
+                // We found a test file, so create the corresponding test structures.
                 debug!(%file_path, "found test file");
 
                 // Record the stem of the test file, to check for overlaps later.
@@ -915,7 +894,7 @@ pub fn is_test(file_name: &str) -> bool {
 }
 
 /// For a single test file, creates one or more test structures (one per revision) that can be
-/// handed over to libtest to run, possibly in parallel.
+/// handed over to the executor to run, possibly in parallel.
 fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &TestPaths) {
     // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But
     // for the purposes of directive parsing, we want to look at that recipe file, not the directory
@@ -929,7 +908,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
     // Scan the test file to discover its revisions, if any.
     let early_props = EarlyProps::from_file(&cx.config, &test_path);
 
-    // Normally we create one libtest structure per revision, with two exceptions:
+    // Normally we create one structure per revision, with two exceptions:
     // - If a test doesn't use revisions, create a dummy revision (None) so that
     //   the test can still run.
     // - Incremental tests inherently can't run their revisions in parallel, so
@@ -944,12 +923,12 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
     // For each revision (or the sole dummy revision), create and append a
     // `CollectedTest` that can be handed over to the test executor.
     collector.tests.extend(revisions.into_iter().map(|revision| {
-        // Create a test name and description to hand over to libtest.
+        // Create a test name and description to hand over to the executor.
         let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
         let test_name = make_test_name(&cx.config, testpaths, revision);
-        // Create a libtest description for the test/revision.
+        // Create a description struct for the test/revision.
         // This is where `ignore-*`/`only-*`/`needs-*` directives are handled,
-        // because they need to set the libtest ignored flag.
+        // because they historically needed to set the libtest ignored flag.
         let mut desc = make_test_description(
             &cx.config,
             &cx.cache,
@@ -961,10 +940,12 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
         );
 
         // If a test's inputs haven't changed since the last time it ran,
-        // mark it as ignored so that libtest will skip it.
+        // mark it as ignored so that the executor will skip it.
         if !cx.config.force_rerun && is_up_to_date(cx, testpaths, &early_props, revision) {
             desc.ignore = true;
             // Keep this in sync with the "up-to-date" message detected by bootstrap.
+            // FIXME(Zalathar): Now that we are no longer tied to libtest, we could
+            // find a less fragile way to communicate this status to bootstrap.
             desc.ignore_message = Some("up-to-date".into());
         }
 
@@ -1104,7 +1085,7 @@ impl Stamp {
     }
 }
 
-/// Creates a name for this test/revision that can be handed over to libtest.
+/// Creates a name for this test/revision that can be handed over to the executor.
 fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
     // Print the name of the file, relative to the sources root.
     let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c533293e791..3a05b242519 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2222,7 +2222,7 @@ impl<'test> TestCx<'test> {
                 .env("PAGER", "")
                 .stdin(File::open(&diff_filename).unwrap())
                 // Capture output and print it explicitly so it will in turn be
-                // captured by libtest.
+                // captured by output-capture.
                 .output()
                 .unwrap();
             assert!(output.status.success());
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 6114afdc9df..24fdbab3aec 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -395,6 +395,35 @@ impl TestCx<'_> {
         // We don't want to hang when calling `quit` while the process is still running
         let mut script_str = String::from("settings set auto-confirm true\n");
 
+        // macOS has a system for restricting access to files and peripherals
+        // called Transparency, Consent, and Control (TCC), which can be
+        // configured using the "Security & Privacy" tab in your settings.
+        //
+        // This system is provenance-based: if Terminal.app is given access to
+        // your Desktop, and you launch a binary within Terminal.app, the new
+        // binary also has access to the files on your Desktop.
+        //
+        // By default though, LLDB launches binaries in very isolated
+        // contexts. This includes resetting any TCC grants that might
+        // otherwise have been inherited.
+        //
+        // In effect, this means that if the developer has placed the rust
+        // repository under one of the system-protected folders, they will get
+        // a pop-up _for each binary_ asking for permissions to access the
+        // folder - quite annoying.
+        //
+        // To avoid this, we tell LLDB to spawn processes with TCC grants
+        // inherited from the parent process.
+        //
+        // Setting this also avoids unnecessary overhead from XprotectService
+        // when running with the Developer Tool grant.
+        //
+        // TIP: If you want to allow launching `lldb ~/Desktop/my_binary`
+        // without being prompted, you can put this in your `~/.lldbinit` too.
+        if self.config.host.contains("darwin") {
+            script_str.push_str("settings set target.inherit-tcc true\n");
+        }
+
         // Make LLDB emit its version, so we have it documented in the test output
         script_str.push_str("version\n");
 
diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
index c8d5190c039..8a0e45cf8ca 100644
--- a/src/tools/compiletest/src/runtest/run_make.rs
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -308,7 +308,7 @@ impl TestCx<'_> {
         let stdout = String::from_utf8_lossy(&stdout).into_owned();
         let stderr = String::from_utf8_lossy(&stderr).into_owned();
         // This conditions on `status.success()` so we don't print output twice on error.
-        // NOTE: this code is called from a libtest thread, so it's hidden by default unless --nocapture is passed.
+        // NOTE: this code is called from an executor thread, so it's hidden by default unless --no-capture is passed.
         self.dump_output(status.success(), &cmd.get_program().to_string_lossy(), &stdout, &stderr);
         if !status.success() {
             let res = ProcRes { status, stdout, stderr, truncated, cmdline: format!("{:?}", cmd) };
diff --git a/src/tools/coverage-dump/Cargo.toml b/src/tools/coverage-dump/Cargo.toml
index 36a66f16030..2f703537b59 100644
--- a/src/tools/coverage-dump/Cargo.toml
+++ b/src/tools/coverage-dump/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 
 [dependencies]
 anyhow = "1.0.71"
-itertools = "0.12"
+itertools.workspace = true
 leb128 = "0.2.5"
 md5 = { package = "md-5" , version = "0.10.5" }
 miniz_oxide = "0.8.8"
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 51146831efa..e2738636a14 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -26,6 +26,7 @@ pub(crate) enum Kind {
     AssocType,
     Primitive,
     Keyword,
+    Attribute,
     // Not in ItemKind
     ProcMacro,
 }
@@ -53,6 +54,7 @@ impl Kind {
             ExternType => true,
 
             // FIXME(adotinthevoid): I'm not sure if these are correct
+            Attribute => false,
             Keyword => false,
             ProcAttribute => false,
             ProcDerive => false,
@@ -109,6 +111,7 @@ impl Kind {
             Kind::Primitive => false,
             Kind::Keyword => false,
             Kind::ProcMacro => false,
+            Kind::Attribute => false,
         }
     }
 
@@ -163,6 +166,7 @@ impl Kind {
         match s.kind {
             ItemKind::AssocConst => AssocConst,
             ItemKind::AssocType => AssocType,
+            ItemKind::Attribute => Attribute,
             ItemKind::Constant => Constant,
             ItemKind::Enum => Enum,
             ItemKind::ExternCrate => ExternCrate,
diff --git a/src/tools/llvm-bitcode-linker/Cargo.toml b/src/tools/llvm-bitcode-linker/Cargo.toml
index a9210b562f3..f78f8b618d3 100644
--- a/src/tools/llvm-bitcode-linker/Cargo.toml
+++ b/src/tools/llvm-bitcode-linker/Cargo.toml
@@ -8,7 +8,7 @@ publish = false
 
 [dependencies]
 anyhow = "1.0"
-tracing = "0.1"
-tracing-subscriber = {version = "0.3.0", features = ["std"] }
+tracing.workspace = true
+tracing-subscriber = { version = "0.3.0", features = ["std"] }
 clap = { version = "4.3", features = ["derive"] }
 thiserror = "1.0.24"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 18d97a748ba..6974ede624a 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -287,14 +287,12 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "gimli",
     "gsgdt",
     "hashbrown",
+    "icu_collections",
     "icu_list",
-    "icu_list_data",
-    "icu_locid",
-    "icu_locid_transform",
-    "icu_locid_transform_data",
+    "icu_locale",
+    "icu_locale_core",
+    "icu_locale_data",
     "icu_provider",
-    "icu_provider_adapters",
-    "icu_provider_macros",
     "ident_case",
     "indexmap",
     "intl-memoizer",
@@ -332,6 +330,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "polonius-engine",
     "portable-atomic", // dependency for platforms doesn't support `AtomicU64` in std
     "portable-atomic-util",
+    "potential_utf",
     "ppv-lite86",
     "proc-macro-hack",
     "proc-macro2",
@@ -447,6 +446,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "zerocopy-derive",
     "zerofrom",
     "zerofrom-derive",
+    "zerotrie",
     "zerovec",
     "zerovec-derive",
     // tidy-alphabetical-end
diff --git a/tests/assembly-llvm/reg-struct-return.rs b/tests/assembly-llvm/reg-struct-return.rs
new file mode 100644
index 00000000000..b251d791d51
--- /dev/null
+++ b/tests/assembly-llvm/reg-struct-return.rs
@@ -0,0 +1,143 @@
+//! Tests that -Zreg-struct-return changes ABI for small struct returns
+//! from hidden-pointer convention to register-return on x86_32.
+//! This test covers:
+//! * Callee side, verifying that the structs are correctly loaded into registers when
+//!   `-Zreg-struct-return` is activated
+//! * Caller side, verifying callers do receive returned structs in registers when
+//!   `-Zreg-struct-return` is activated
+//@ add-core-stubs
+//@ assembly-output: emit-asm
+//@ compile-flags: -O --target=i686-unknown-linux-gnu -Crelocation-model=static
+//@ revisions: WITH WITHOUT
+//@[WITH] compile-flags: -Zreg-struct-return
+//@ needs-llvm-components: x86
+
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+#![crate_type = "lib"]
+
+extern crate minicore;
+use minicore::*;
+
+// Verifies ABI changes for small structs, where both fields fit into one register.
+// WITH is expected to use register return, WITHOUT should use hidden pointer.
+mod Small {
+    struct SmallStruct {
+        a: i8,
+        b: i8,
+    }
+
+    unsafe extern "C" {
+        fn small() -> SmallStruct;
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn small_callee() -> SmallStruct {
+        // (42 << 8) | 42 = 10794
+
+        // WITH-LABEL: small_callee
+        // WITH: movw $10794, %ax
+        // WITH: retl
+
+        // WITHOUT-LABEL: small_callee
+        // WITHOUT: movl 4(%esp), %e{{.*}}
+        // WITHOUT: movw $10794, (%e{{.*}})
+        // WITHOUT: retl $4
+        SmallStruct { a: 42, b: 42 }
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn small_caller(dst: &mut SmallStruct) {
+        // WITH-LABEL: small_caller
+        // WITH: calll small
+        // WITH: movw %ax, (%e{{.*}})
+
+        // WITHOUT-LABEL: small_caller
+        // WITHOUT: calll small
+        // WITHOUT: movzwl {{.*}}(%esp), %e[[TMP:..]]
+        // WITHOUT: movw %[[TMP]], (%e{{..}})
+        *dst = small();
+    }
+}
+
+// Verifies ABI changes for a struct of size 8, which is the maximum size
+// for reg-struct-return.
+// WITH is expected to still use register return, WITHOUT should use hidden
+// pointer.
+mod Pivot {
+    struct PivotStruct {
+        a: i32,
+        b: i32,
+    }
+
+    unsafe extern "C" {
+        fn pivot() -> PivotStruct;
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn pivot_callee() -> PivotStruct {
+        // WITH-LABEL: pivot_callee
+        // WITH: movl $42, %e{{.*}}
+        // WITH: movl $42, %e{{.*}}
+        // WITH: retl
+
+        // WITHOUT-LABEL: pivot_callee
+        // WITHOUT: movl 4(%esp), %e{{.*}}
+        // WITHOUT-DAG: movl $42, (%e{{.*}})
+        // WITHOUT-DAG: movl $42, 4(%e{{.*}})
+        // WITHOUT: retl $4
+        PivotStruct { a: 42, b: 42 }
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn pivot_caller(dst: &mut PivotStruct) {
+        // WITH-LABEL: pivot_caller
+        // WITH: calll pivot
+        // WITH-DAG: movl %e{{.*}}, 4(%e{{.*}})
+        // WITH-DAG: movl %e{{.*}}, (%e{{.*}})
+
+        // WITHOUT-LABEL: pivot_caller
+        // WITHOUT: calll pivot
+        // WITHOUT: movsd {{.*}}(%esp), %[[TMP:xmm.]]
+        // WITHOUT: movsd %[[TMP]], (%e{{..}})
+        *dst = pivot();
+    }
+}
+
+// Verifies ABI changes for a struct of size 12, which is larger than the
+// maximum size for reg-struct-return (8 bytes).
+// Here, the hidden pointer convention should be used even when `-Zreg-struct-return` is set.
+mod Large {
+    struct LargeStruct {
+        a: i32,
+        b: i32,
+        c: i32,
+    }
+
+    unsafe extern "C" {
+        fn large() -> LargeStruct;
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn large_callee() -> LargeStruct {
+        // CHECK-LABEL: large_callee
+        // CHECK: movl 4(%esp), %e{{.*}}
+        // CHECK-DAG: movl $42, (%e{{.*}})
+        // CHECK-DAG: movl $42, 4(%e{{.*}})
+        // CHECK-DAG: movl $42, 8(%e{{.*}})
+        // CHECK: retl $4
+        LargeStruct { a: 42, b: 42, c: 42 }
+    }
+
+    #[unsafe(no_mangle)]
+    pub unsafe extern "C" fn large_caller(dst: &mut LargeStruct) {
+        // CHECK-LABEL: large_caller
+        // CHECK: calll large
+        // CHECK-DAG: movl   {{.*}}(%esp), %[[TMP1:e..]]
+        // CHECK-DAG: movl  %[[TMP1]], {{.*}}(%e{{..}})
+        // CHECK-DAG: movsd  {{.*}}(%esp), %[[TMP2:xmm.]]
+        // CHECK-DAG: movsd  %[[TMP2]], {{.*}}(%e{{..}})
+        *dst = large();
+    }
+}
diff --git a/tests/codegen-llvm/addr-of-mutate.rs b/tests/codegen-llvm/addr-of-mutate.rs
index 71669065289..36d6bf555d1 100644
--- a/tests/codegen-llvm/addr-of-mutate.rs
+++ b/tests/codegen-llvm/addr-of-mutate.rs
@@ -5,7 +5,7 @@
 // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
 // See <https://github.com/rust-lang/rust/issues/111502>.
 
-// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
+// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}} dereferenceable(128) %x)
 #[no_mangle]
 pub fn foo(x: [u8; 128]) -> u8 {
     let ptr = core::ptr::addr_of!(x).cast_mut();
@@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 {
     x[0]
 }
 
-// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
@@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
 }
 
 // If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
-// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();
diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs
index db508682862..a0744e44c61 100644
--- a/tests/codegen-llvm/function-arguments.rs
+++ b/tests/codegen-llvm/function-arguments.rs
@@ -134,7 +134,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {}
 #[no_mangle]
 pub fn notunpin_borrow(_: &NotUnpin) {}
 
-// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
+// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(address\))?}} dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {}
 
@@ -197,7 +197,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
     x
 }
 
-// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(none\))?}} dereferenceable(32){{( %_0)?}})
+// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(address\))?}} dereferenceable(32){{( %_0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
     S { _field: [0, 0, 0, 0, 0, 0, 0, 0] }
diff --git a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
index 4666342a16a..7ea08a1a8f7 100644
--- a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
+++ b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
@@ -256,11 +256,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
+// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}} dereferenceable(24) %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(none\))?}} dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(address\))?}} dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs
index c6e7203ff98..e441454bed2 100644
--- a/tests/crashes/120175.rs
+++ b/tests/crashes/120175.rs
@@ -2,8 +2,9 @@
 //@ needs-rustc-debug-assertions
 
 #![feature(extern_types)]
+#![feature(raw_dylib_elf)]
 
-#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")]
+#[link(name = "bar", kind = "raw-dylib")]
 extern "C" {
     pub type CrossCrate;
 }
diff --git a/tests/crashes/137580.rs b/tests/crashes/137580.rs
deleted file mode 100644
index 246c80ef556..00000000000
--- a/tests/crashes/137580.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #137580
-fn main() {
-    println!("%65536$", 1);
-}
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index f11920cdd8c..a363175c1dd 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -9,7 +9,7 @@ show-text: true
 define-function: (
     "check-colors",
     [theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
-     sidebar, sidebar_current, sidebar_current_background],
+     attribute, sidebar, sidebar_current, sidebar_current_background],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
         // Checking results colors.
@@ -22,6 +22,7 @@ define-function: (
         assert-css: (".item-table .type", {"color": |type|}, ALL)
         assert-css: (".item-table .union", {"color": |union|}, ALL)
         assert-css: (".item-table .keyword", {"color": |keyword|}, ALL)
+        assert-css: (".item-table .attribute", {"color": |attribute|}, ALL)
         // Checking sidebar elements.
         assert-css: (
             ".sidebar-elems li:not(.current) a",
@@ -58,6 +59,7 @@ call-function: (
         "type": "#ffa0a5",
         "union": "#ffa0a5",
         "keyword": "#39afd7",
+        "attribute": "#39afd7",
         "sidebar": "#53b1db",
         "sidebar_current": "#ffb44c",
         "sidebar_current_background": "transparent",
@@ -76,6 +78,7 @@ call-function: (
         "type": "#2dbfb8",
         "union": "#2dbfb8",
         "keyword": "#d2991d",
+        "attribute": "#d2991d",
         "sidebar": "#fdbf35",
         "sidebar_current": "#fdbf35",
         "sidebar_current_background": "#444",
@@ -94,6 +97,7 @@ call-function: (
         "type": "#ad378a",
         "union": "#ad378a",
         "keyword": "#3873ad",
+        "attribute": "#3873ad",
         "sidebar": "#356da4",
         "sidebar_current": "#356da4",
         "sidebar_current_background": "#fff",
diff --git a/tests/rustdoc-gui/module-items-font.goml b/tests/rustdoc-gui/module-items-font.goml
index 0e6dd81c05b..bed95b378c6 100644
--- a/tests/rustdoc-gui/module-items-font.goml
+++ b/tests/rustdoc-gui/module-items-font.goml
@@ -65,3 +65,12 @@ assert-css: (
     "#keywords + .item-table dd",
     {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
 )
+// attributes
+assert-css: (
+    "#attributes + .item-table dt a",
+    {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
+assert-css: (
+    "#attributes + .item-table dd",
+    {"font-family": '"Source Serif 4", NanumBarunGothic, serif'},
+)
diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml
index e136eab6a7d..fe0f6401089 100644
--- a/tests/rustdoc-gui/search-result-color.goml
+++ b/tests/rustdoc-gui/search-result-color.goml
@@ -7,7 +7,8 @@ define-function: (
     [
         theme, count_color, desc_color, path_color, bottom_border_color, keyword_color,
         struct_color, associatedtype_color, tymethod_color, method_color, structfield_color,
-        structfield_hover_color, macro_color, fn_color, hover_path_color, hover_background, grey
+        structfield_hover_color, macro_color, fn_color, hover_path_color, hover_background,
+        attribute_color, grey
     ],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
@@ -47,6 +48,11 @@ define-function: (
             "hover_color": |keyword_color|,
         })
         call-function: ("check-result-color", {
+            "result_kind": "attribute",
+            "color": |attribute_color|,
+            "hover_color": |attribute_color|,
+        })
+        call-function: ("check-result-color", {
             "result_kind": "struct",
             "color": |struct_color|,
             "hover_color": |struct_color|,
@@ -155,6 +161,7 @@ call-function: ("check-search-color", {
     "path_color": "#0096cf",
     "bottom_border_color": "#aaa3",
     "keyword_color": "#39afd7",
+    "attribute_color": "#39afd7",
     "struct_color": "#ffa0a5",
     "associatedtype_color": "#39afd7",
     "tymethod_color": "#fdd687",
@@ -176,6 +183,7 @@ call-function: ("check-search-color", {
     "path_color": "#ddd",
     "bottom_border_color": "#aaa3",
     "keyword_color": "#d2991d",
+    "attribute_color": "#d2991d",
     "struct_color": "#2dbfb8",
     "associatedtype_color": "#d2991d",
     "tymethod_color": "#2bab63",
@@ -197,6 +205,7 @@ call-function: ("check-search-color", {
     "path_color": "#000",
     "bottom_border_color": "#aaa3",
     "keyword_color": "#3873ad",
+    "attribute_color": "#3873ad",
     "struct_color": "#ad378a",
     "associatedtype_color": "#3873ad",
     "tymethod_color": "#ad7c37",
diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml
index 57c45555a76..9a398655f8f 100644
--- a/tests/rustdoc-gui/sidebar-links-color.goml
+++ b/tests/rustdoc-gui/sidebar-links-color.goml
@@ -12,6 +12,7 @@ define-function: (
         enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover,
         trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover,
         type_hover_background, keyword, keyword_hover, keyword_hover_background,
+        attribute, attribute_hover, attribute_hover_background,
     ],
     block {
         call-function: ("switch-theme", {"theme": |theme|})
@@ -85,6 +86,16 @@ define-function: (
             ".sidebar .block.keyword a:hover",
             {"color": |keyword_hover|, "background-color": |keyword_hover_background|},
         )
+        // Attribute
+        assert-css: (
+            ".sidebar .block.attribute a",
+            {"color": |attribute|, "background-color": "rgba(0, 0, 0, 0)"},
+        )
+        move-cursor-to: ".sidebar .block.attribute a"
+        assert-css: (
+            ".sidebar .block.attribute a:hover",
+            {"color": |attribute_hover|, "background-color": |attribute_hover_background|},
+        )
     }
 )
 
@@ -113,6 +124,9 @@ call-function: (
         "keyword": "#53b1db",
         "keyword_hover": "#ffb44c",
         "keyword_hover_background": "transparent",
+        "attribute": "#53b1db",
+        "attribute_hover": "#ffb44c",
+        "attribute_hover_background": "transparent",
     }
 )
 call-function: (
@@ -140,6 +154,9 @@ call-function: (
         "keyword": "#fdbf35",
         "keyword_hover": "#fdbf35",
         "keyword_hover_background": "#444",
+        "attribute": "#fdbf35",
+        "attribute_hover": "#fdbf35",
+        "attribute_hover_background": "#444",
     }
 )
 call-function: (
@@ -167,5 +184,8 @@ call-function: (
         "keyword": "#356da4",
         "keyword_hover": "#356da4",
         "keyword_hover_background": "#fff",
+        "attribute": "#356da4",
+        "attribute_hover": "#356da4",
+        "attribute_hover_background": "#fff",
     }
 )
diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs
index 623f5b33e9b..42f2fbd93b1 100644
--- a/tests/rustdoc-gui/src/test_docs/lib.rs
+++ b/tests/rustdoc-gui/src/test_docs/lib.rs
@@ -161,6 +161,10 @@ pub enum AnEnum {
 /// Some keyword.
 pub mod keyword {}
 
+#[doc(attribute = "forbid")]
+/// Some attribute.
+pub mod repr {}
+
 /// Just some type alias.
 pub type SomeType = u32;
 
diff --git a/tests/rustdoc-json/doc_attribute.rs b/tests/rustdoc-json/doc_attribute.rs
new file mode 100644
index 00000000000..9e1a711f0b7
--- /dev/null
+++ b/tests/rustdoc-json/doc_attribute.rs
@@ -0,0 +1,18 @@
+// Doc attributes (`#[doc(attribute = "...")]` should not be generated in rustdoc JSON output
+// and this test ensures it.
+
+#![feature(rustdoc_internals)]
+#![no_std]
+
+//@ !has "$.index[?(@.name=='repr')]"
+//@ has "$.index[?(@.name=='foo')]"
+
+#[doc(attribute = "repr")]
+/// this is a test!
+pub mod foo {}
+
+//@ !has "$.index[?(@.name=='forbid')]"
+//@ !has "$.index[?(@.name=='bar')]"
+#[doc(attribute = "forbid")]
+/// hello
+mod bar {}
diff --git a/tests/rustdoc-ui/doc-attribute-unsupported.rs b/tests/rustdoc-ui/doc-attribute-unsupported.rs
new file mode 100644
index 00000000000..3bd153117a9
--- /dev/null
+++ b/tests/rustdoc-ui/doc-attribute-unsupported.rs
@@ -0,0 +1,7 @@
+// This is currently not supported but should be!
+
+#![feature(rustdoc_internals)]
+
+#[doc(attribute = "diagnostic::do_not_recommend")] //~ ERROR
+/// bla
+mod yup {}
diff --git a/tests/rustdoc-ui/doc-attribute-unsupported.stderr b/tests/rustdoc-ui/doc-attribute-unsupported.stderr
new file mode 100644
index 00000000000..e2480a548ac
--- /dev/null
+++ b/tests/rustdoc-ui/doc-attribute-unsupported.stderr
@@ -0,0 +1,10 @@
+error: nonexistent builtin attribute `diagnostic::do_not_recommend` used in `#[doc(attribute = "...")]`
+  --> $DIR/doc-attribute-unsupported.rs:5:19
+   |
+LL | #[doc(attribute = "diagnostic::do_not_recommend")]
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: only existing builtin attributes are allowed in core/std
+
+error: aborting due to 1 previous error
+
diff --git a/tests/rustdoc-ui/invalid-attribute.rs b/tests/rustdoc-ui/invalid-attribute.rs
new file mode 100644
index 00000000000..2fc7be2cf34
--- /dev/null
+++ b/tests/rustdoc-ui/invalid-attribute.rs
@@ -0,0 +1,10 @@
+// Testing the output when an invalid builtin attribute is passed as value
+// to `doc(attribute = "...")`.
+
+#![feature(rustdoc_internals)]
+
+#[doc(attribute = "foo df")] //~ ERROR
+mod foo {}
+
+#[doc(attribute = "fooyi")] //~ ERROR
+mod foo2 {}
diff --git a/tests/rustdoc-ui/invalid-attribute.stderr b/tests/rustdoc-ui/invalid-attribute.stderr
new file mode 100644
index 00000000000..66e68ce44b4
--- /dev/null
+++ b/tests/rustdoc-ui/invalid-attribute.stderr
@@ -0,0 +1,18 @@
+error: nonexistent builtin attribute `foo df` used in `#[doc(attribute = "...")]`
+  --> $DIR/invalid-attribute.rs:6:19
+   |
+LL | #[doc(attribute = "foo df")]
+   |                   ^^^^^^^^
+   |
+   = help: only existing builtin attributes are allowed in core/std
+
+error: nonexistent builtin attribute `fooyi` used in `#[doc(attribute = "...")]`
+  --> $DIR/invalid-attribute.rs:9:19
+   |
+LL | #[doc(attribute = "fooyi")]
+   |                   ^^^^^^^
+   |
+   = help: only existing builtin attributes are allowed in core/std
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/rustdoc/doc-attribute.rs b/tests/rustdoc/doc-attribute.rs
new file mode 100644
index 00000000000..92e603ae6e5
--- /dev/null
+++ b/tests/rustdoc/doc-attribute.rs
@@ -0,0 +1,24 @@
+// Test checking the `#[doc(attribute = "...")]` attribute.
+
+#![crate_name = "foo"]
+
+#![feature(rustdoc_internals)]
+
+//@ has foo/index.html '//h2[@id="attributes"]' 'Attributes'
+//@ has foo/index.html '//a[@href="attribute.no_mangle.html"]' 'no_mangle'
+//@ has foo/index.html '//div[@class="sidebar-elems"]//li/a' 'Attributes'
+//@ has foo/index.html '//div[@class="sidebar-elems"]//li/a/@href' '#attributes'
+//@ has foo/attribute.no_mangle.html '//h1' 'Attribute no_mangle'
+//@ has foo/attribute.no_mangle.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
+//@ has foo/index.html '//a/@href' '../foo/index.html'
+//@ !has foo/foo/index.html
+//@ !has-dir foo/foo
+//@ !has foo/index.html '//span' '🔒'
+#[doc(attribute = "no_mangle")]
+/// this is a test!
+mod foo{}
+
+//@ has foo/attribute.repr.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello'
+#[doc(attribute = "repr")]
+/// hello
+mod bar {}
diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr
index b8d6c632b97..ec6b9b8f027 100644
--- a/tests/ui/abi/c-zst.powerpc-linux.stderr
+++ b/tests/ui/abi/c-zst.powerpc-linux.stderr
@@ -27,7 +27,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(0 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr
index b8d6c632b97..ec6b9b8f027 100644
--- a/tests/ui/abi/c-zst.s390x-linux.stderr
+++ b/tests/ui/abi/c-zst.s390x-linux.stderr
@@ -27,7 +27,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(0 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr
index b8d6c632b97..ec6b9b8f027 100644
--- a/tests/ui/abi/c-zst.sparc64-linux.stderr
+++ b/tests/ui/abi/c-zst.sparc64-linux.stderr
@@ -27,7 +27,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(0 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
index b8d6c632b97..ec6b9b8f027 100644
--- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
+++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
@@ -27,7 +27,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(0 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr
index 0fec35dabdd..47341da221f 100644
--- a/tests/ui/abi/debug.generic.stderr
+++ b/tests/ui/abi/debug.generic.stderr
@@ -454,7 +454,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(32 bytes),
                            pointee_align: Some(
@@ -527,7 +527,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(128 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr
index ce8bd41f045..94a01a80873 100644
--- a/tests/ui/abi/debug.loongarch64.stderr
+++ b/tests/ui/abi/debug.loongarch64.stderr
@@ -454,7 +454,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(32 bytes),
                            pointee_align: Some(
@@ -527,7 +527,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(128 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr
index ce8bd41f045..94a01a80873 100644
--- a/tests/ui/abi/debug.riscv64.stderr
+++ b/tests/ui/abi/debug.riscv64.stderr
@@ -454,7 +454,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(32 bytes),
                            pointee_align: Some(
@@ -527,7 +527,7 @@ error: ABIs are not compatible
                    },
                    mode: Indirect {
                        attrs: ArgAttributes {
-                           regular: NoAlias | NoCapture | NonNull | NoUndef,
+                           regular: NoAlias | CapturesAddress | NonNull | NoUndef,
                            arg_ext: None,
                            pointee_size: Size(128 bytes),
                            pointee_align: Some(
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
index 3d82f572a1a..823d8d5b92f 100644
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
+++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr
@@ -25,6 +25,7 @@ error[E0599]: no method named `poll` found for struct `Pin<&mut impl Future<Outp
    |
 LL |         match fut.as_mut().poll(ctx) {
    |                            ^^^^ method not found in `Pin<&mut impl Future<Output = ()>>`
+   |
   --> $SRC_DIR/core/src/future/future.rs:LL:COL
    |
    = note: the method is available for `Pin<&mut impl Future<Output = ()>>` here
diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs
index 90ca007451e..932aaf7a9e2 100644
--- a/tests/ui/attributes/malformed-attrs.rs
+++ b/tests/ui/attributes/malformed-attrs.rs
@@ -81,8 +81,7 @@
 #[export_stable = 1]
 //~^ ERROR malformed
 #[link]
-//~^ ERROR valid forms for the attribute are
-//~| WARN this was previously accepted by the compiler
+//~^ ERROR malformed
 #[link_name]
 //~^ ERROR malformed
 #[link_section]
diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr
index 69f9a18c179..b85864b401e 100644
--- a/tests/ui/attributes/malformed-attrs.stderr
+++ b/tests/ui/attributes/malformed-attrs.stderr
@@ -1,5 +1,5 @@
 error[E0539]: malformed `cfg` attribute input
-  --> $DIR/malformed-attrs.rs:102:1
+  --> $DIR/malformed-attrs.rs:101:1
    |
 LL | #[cfg]
    | ^^^^^^
@@ -10,7 +10,7 @@ LL | #[cfg]
    = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
 
 error: malformed `cfg_attr` attribute input
-  --> $DIR/malformed-attrs.rs:104:1
+  --> $DIR/malformed-attrs.rs:103:1
    |
 LL | #[cfg_attr]
    | ^^^^^^^^^^^
@@ -22,7 +22,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
    |           ++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0463]: can't find crate for `wloop`
-  --> $DIR/malformed-attrs.rs:211:1
+  --> $DIR/malformed-attrs.rs:210:1
    |
 LL | extern crate wloop;
    | ^^^^^^^^^^^^^^^^^^^ can't find crate
@@ -42,7 +42,7 @@ LL | #![windows_subsystem = "windows"]
    |                      +++++++++++
 
 error: malformed `instruction_set` attribute input
-  --> $DIR/malformed-attrs.rs:106:1
+  --> $DIR/malformed-attrs.rs:105:1
    |
 LL | #[instruction_set]
    | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]`
@@ -50,13 +50,13 @@ LL | #[instruction_set]
    = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute>
 
 error: malformed `patchable_function_entry` attribute input
-  --> $DIR/malformed-attrs.rs:108:1
+  --> $DIR/malformed-attrs.rs:107:1
    |
 LL | #[patchable_function_entry]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
 
 error: malformed `must_not_suspend` attribute input
-  --> $DIR/malformed-attrs.rs:132:1
+  --> $DIR/malformed-attrs.rs:131:1
    |
 LL | #[must_not_suspend()]
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -71,13 +71,13 @@ LL + #[must_not_suspend]
    |
 
 error: malformed `cfi_encoding` attribute input
-  --> $DIR/malformed-attrs.rs:134:1
+  --> $DIR/malformed-attrs.rs:133:1
    |
 LL | #[cfi_encoding]
    | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]`
 
 error: malformed `allow` attribute input
-  --> $DIR/malformed-attrs.rs:178:1
+  --> $DIR/malformed-attrs.rs:177:1
    |
 LL | #[allow]
    | ^^^^^^^^
@@ -93,7 +93,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")]
    |        +++++++++++++++++++++++++++++++++++++
 
 error: malformed `expect` attribute input
-  --> $DIR/malformed-attrs.rs:180:1
+  --> $DIR/malformed-attrs.rs:179:1
    |
 LL | #[expect]
    | ^^^^^^^^^
@@ -109,7 +109,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")]
    |         +++++++++++++++++++++++++++++++++++++
 
 error: malformed `warn` attribute input
-  --> $DIR/malformed-attrs.rs:182:1
+  --> $DIR/malformed-attrs.rs:181:1
    |
 LL | #[warn]
    | ^^^^^^^
@@ -125,7 +125,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")]
    |       +++++++++++++++++++++++++++++++++++++
 
 error: malformed `deny` attribute input
-  --> $DIR/malformed-attrs.rs:184:1
+  --> $DIR/malformed-attrs.rs:183:1
    |
 LL | #[deny]
    | ^^^^^^^
@@ -141,7 +141,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")]
    |       +++++++++++++++++++++++++++++++++++++
 
 error: malformed `forbid` attribute input
-  --> $DIR/malformed-attrs.rs:186:1
+  --> $DIR/malformed-attrs.rs:185:1
    |
 LL | #[forbid]
    | ^^^^^^^^^
@@ -157,7 +157,7 @@ LL | #[forbid(lint1, lint2, lint3, reason = "...")]
    |         +++++++++++++++++++++++++++++++++++++
 
 error: malformed `debugger_visualizer` attribute input
-  --> $DIR/malformed-attrs.rs:188:1
+  --> $DIR/malformed-attrs.rs:187:1
    |
 LL | #[debugger_visualizer]
    | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]`
@@ -165,13 +165,13 @@ LL | #[debugger_visualizer]
    = note: for more information, visit <https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute>
 
 error: malformed `thread_local` attribute input
-  --> $DIR/malformed-attrs.rs:203:1
+  --> $DIR/malformed-attrs.rs:202:1
    |
 LL | #[thread_local()]
    | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]`
 
 error: malformed `no_link` attribute input
-  --> $DIR/malformed-attrs.rs:207:1
+  --> $DIR/malformed-attrs.rs:206:1
    |
 LL | #[no_link()]
    | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]`
@@ -179,7 +179,7 @@ LL | #[no_link()]
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute>
 
 error: malformed `macro_export` attribute input
-  --> $DIR/malformed-attrs.rs:214:1
+  --> $DIR/malformed-attrs.rs:213:1
    |
 LL | #[macro_export = 18]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -195,25 +195,25 @@ LL + #[macro_export]
    |
 
 error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:99:1
+  --> $DIR/malformed-attrs.rs:98:1
    |
 LL | #[proc_macro = 18]
    | ^^^^^^^^^^^^^^^^^^
 
 error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:116:1
+  --> $DIR/malformed-attrs.rs:115:1
    |
 LL | #[proc_macro_attribute = 19]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
-  --> $DIR/malformed-attrs.rs:123:1
+  --> $DIR/malformed-attrs.rs:122:1
    |
 LL | #[proc_macro_derive]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint
-  --> $DIR/malformed-attrs.rs:216:1
+  --> $DIR/malformed-attrs.rs:215:1
    |
 LL | #[allow_internal_unsafe = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -242,18 +242,8 @@ LL | #[doc]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
    = note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
 
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-attrs.rs:83:1
-   |
-LL | #[link]
-   | ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-
 error: invalid argument
-  --> $DIR/malformed-attrs.rs:188:1
+  --> $DIR/malformed-attrs.rs:187:1
    |
 LL | #[debugger_visualizer]
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -494,8 +484,27 @@ LL | #[export_stable = 1]
    | |               didn't expect any arguments here
    | help: must be of the form: `#[export_stable]`
 
+error[E0539]: malformed `link` attribute input
+  --> $DIR/malformed-attrs.rs:83:1
+   |
+LL | #[link]
+   | ^^^^^^^ expected this to be a list
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL | #[link(name = "...")]
+   |       ++++++++++++++
+LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...")]
+   |       +++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   = and 1 other candidate
+
 error[E0539]: malformed `link_name` attribute input
-  --> $DIR/malformed-attrs.rs:86:1
+  --> $DIR/malformed-attrs.rs:85:1
    |
 LL | #[link_name]
    | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]`
@@ -503,7 +512,7 @@ LL | #[link_name]
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute>
 
 error[E0539]: malformed `link_section` attribute input
-  --> $DIR/malformed-attrs.rs:88:1
+  --> $DIR/malformed-attrs.rs:87:1
    |
 LL | #[link_section]
    | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]`
@@ -511,7 +520,7 @@ LL | #[link_section]
    = note: for more information, visit <https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute>
 
 error[E0539]: malformed `coverage` attribute input
-  --> $DIR/malformed-attrs.rs:90:1
+  --> $DIR/malformed-attrs.rs:89:1
    |
 LL | #[coverage]
    | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument
@@ -524,7 +533,7 @@ LL | #[coverage(on)]
    |           ++++
 
 error[E0539]: malformed `sanitize` attribute input
-  --> $DIR/malformed-attrs.rs:92:1
+  --> $DIR/malformed-attrs.rs:91:1
    |
 LL | #[sanitize]
    | ^^^^^^^^^^^ expected this to be a list
@@ -542,7 +551,7 @@ LL | #[sanitize(kcfi = "on|off")]
    = and 5 other candidates
 
 error[E0565]: malformed `no_implicit_prelude` attribute input
-  --> $DIR/malformed-attrs.rs:97:1
+  --> $DIR/malformed-attrs.rs:96:1
    |
 LL | #[no_implicit_prelude = 23]
    | ^^^^^^^^^^^^^^^^^^^^^^----^
@@ -551,7 +560,7 @@ LL | #[no_implicit_prelude = 23]
    | help: must be of the form: `#[no_implicit_prelude]`
 
 error[E0565]: malformed `proc_macro` attribute input
-  --> $DIR/malformed-attrs.rs:99:1
+  --> $DIR/malformed-attrs.rs:98:1
    |
 LL | #[proc_macro = 18]
    | ^^^^^^^^^^^^^----^
@@ -560,7 +569,7 @@ LL | #[proc_macro = 18]
    | help: must be of the form: `#[proc_macro]`
 
 error[E0565]: malformed `coroutine` attribute input
-  --> $DIR/malformed-attrs.rs:111:5
+  --> $DIR/malformed-attrs.rs:110:5
    |
 LL |     #[coroutine = 63] || {}
    |     ^^^^^^^^^^^^----^
@@ -569,7 +578,7 @@ LL |     #[coroutine = 63] || {}
    |     help: must be of the form: `#[coroutine]`
 
 error[E0565]: malformed `proc_macro_attribute` attribute input
-  --> $DIR/malformed-attrs.rs:116:1
+  --> $DIR/malformed-attrs.rs:115:1
    |
 LL | #[proc_macro_attribute = 19]
    | ^^^^^^^^^^^^^^^^^^^^^^^----^
@@ -578,7 +587,7 @@ LL | #[proc_macro_attribute = 19]
    | help: must be of the form: `#[proc_macro_attribute]`
 
 error[E0539]: malformed `must_use` attribute input
-  --> $DIR/malformed-attrs.rs:119:1
+  --> $DIR/malformed-attrs.rs:118:1
    |
 LL | #[must_use = 1]
    | ^^^^^^^^^^^^^-^
@@ -596,7 +605,7 @@ LL + #[must_use]
    |
 
 error[E0539]: malformed `proc_macro_derive` attribute input
-  --> $DIR/malformed-attrs.rs:123:1
+  --> $DIR/malformed-attrs.rs:122:1
    |
 LL | #[proc_macro_derive]
    | ^^^^^^^^^^^^^^^^^^^^ expected this to be a list
@@ -610,7 +619,7 @@ LL | #[proc_macro_derive(TraitName, attributes(name1, name2, ...))]
    |                    ++++++++++++++++++++++++++++++++++++++++++
 
 error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input
-  --> $DIR/malformed-attrs.rs:128:1
+  --> $DIR/malformed-attrs.rs:127:1
    |
 LL | #[rustc_layout_scalar_valid_range_start]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -619,7 +628,7 @@ LL | #[rustc_layout_scalar_valid_range_start]
    | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]`
 
 error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input
-  --> $DIR/malformed-attrs.rs:130:1
+  --> $DIR/malformed-attrs.rs:129:1
    |
 LL | #[rustc_layout_scalar_valid_range_end]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -628,7 +637,7 @@ LL | #[rustc_layout_scalar_valid_range_end]
    | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`
 
 error[E0565]: malformed `marker` attribute input
-  --> $DIR/malformed-attrs.rs:155:1
+  --> $DIR/malformed-attrs.rs:154:1
    |
 LL | #[marker = 3]
    | ^^^^^^^^^---^
@@ -637,7 +646,7 @@ LL | #[marker = 3]
    | help: must be of the form: `#[marker]`
 
 error[E0565]: malformed `fundamental` attribute input
-  --> $DIR/malformed-attrs.rs:157:1
+  --> $DIR/malformed-attrs.rs:156:1
    |
 LL | #[fundamental()]
    | ^^^^^^^^^^^^^--^
@@ -646,7 +655,7 @@ LL | #[fundamental()]
    | help: must be of the form: `#[fundamental]`
 
 error[E0565]: malformed `ffi_pure` attribute input
-  --> $DIR/malformed-attrs.rs:165:5
+  --> $DIR/malformed-attrs.rs:164:5
    |
 LL |     #[unsafe(ffi_pure = 1)]
    |     ^^^^^^^^^^^^^^^^^^---^^
@@ -655,7 +664,7 @@ LL |     #[unsafe(ffi_pure = 1)]
    |     help: must be of the form: `#[ffi_pure]`
 
 error[E0539]: malformed `link_ordinal` attribute input
-  --> $DIR/malformed-attrs.rs:167:5
+  --> $DIR/malformed-attrs.rs:166:5
    |
 LL |     #[link_ordinal]
    |     ^^^^^^^^^^^^^^^
@@ -666,7 +675,7 @@ LL |     #[link_ordinal]
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute>
 
 error[E0565]: malformed `ffi_const` attribute input
-  --> $DIR/malformed-attrs.rs:171:5
+  --> $DIR/malformed-attrs.rs:170:5
    |
 LL |     #[unsafe(ffi_const = 1)]
    |     ^^^^^^^^^^^^^^^^^^^---^^
@@ -675,7 +684,7 @@ LL |     #[unsafe(ffi_const = 1)]
    |     help: must be of the form: `#[ffi_const]`
 
 error[E0539]: malformed `linkage` attribute input
-  --> $DIR/malformed-attrs.rs:173:5
+  --> $DIR/malformed-attrs.rs:172:5
    |
 LL |     #[linkage]
    |     ^^^^^^^^^^ expected this to be of the form `linkage = "..."`
@@ -693,7 +702,7 @@ LL |     #[linkage = "external"]
    = and 5 other candidates
 
 error[E0565]: malformed `automatically_derived` attribute input
-  --> $DIR/malformed-attrs.rs:191:1
+  --> $DIR/malformed-attrs.rs:190:1
    |
 LL | #[automatically_derived = 18]
    | ^^^^^^^^^^^^^^^^^^^^^^^^----^
@@ -702,7 +711,7 @@ LL | #[automatically_derived = 18]
    | help: must be of the form: `#[automatically_derived]`
 
 error[E0565]: malformed `non_exhaustive` attribute input
-  --> $DIR/malformed-attrs.rs:197:1
+  --> $DIR/malformed-attrs.rs:196:1
    |
 LL | #[non_exhaustive = 1]
    | ^^^^^^^^^^^^^^^^^---^
@@ -711,13 +720,13 @@ LL | #[non_exhaustive = 1]
    | help: must be of the form: `#[non_exhaustive]`
 
 error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]`
-  --> $DIR/malformed-attrs.rs:209:1
+  --> $DIR/malformed-attrs.rs:208:1
    |
 LL | #[macro_use = 1]
    | ^^^^^^^^^^^^^^^^
 
 error[E0565]: malformed `allow_internal_unsafe` attribute input
-  --> $DIR/malformed-attrs.rs:216:1
+  --> $DIR/malformed-attrs.rs:215:1
    |
 LL | #[allow_internal_unsafe = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^---^
@@ -726,7 +735,7 @@ LL | #[allow_internal_unsafe = 1]
    | help: must be of the form: `#[allow_internal_unsafe]`
 
 error[E0565]: malformed `type_const` attribute input
-  --> $DIR/malformed-attrs.rs:143:5
+  --> $DIR/malformed-attrs.rs:142:5
    |
 LL |     #[type_const = 1]
    |     ^^^^^^^^^^^^^---^
@@ -759,7 +768,7 @@ LL | #[repr]
    | ^^^^^^^
 
 warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
-  --> $DIR/malformed-attrs.rs:149:1
+  --> $DIR/malformed-attrs.rs:148:1
    |
 LL | #[diagnostic::do_not_recommend()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -767,7 +776,7 @@ LL | #[diagnostic::do_not_recommend()]
    = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/malformed-attrs.rs:138:1
+  --> $DIR/malformed-attrs.rs:137:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -775,7 +784,7 @@ LL | #[diagnostic::on_unimplemented]
    = help: at least one of the `message`, `note` and `label` options are expected
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/malformed-attrs.rs:140:1
+  --> $DIR/malformed-attrs.rs:139:1
    |
 LL | #[diagnostic::on_unimplemented = 1]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -792,7 +801,7 @@ LL | #[inline = 5]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:94:1
+  --> $DIR/malformed-attrs.rs:93:1
    |
 LL | #[ignore()]
    | ^^^^^^^^^^^
@@ -801,7 +810,7 @@ LL | #[ignore()]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:223:1
+  --> $DIR/malformed-attrs.rs:222:1
    |
 LL | #[ignore = 1]
    | ^^^^^^^^^^^^^
@@ -810,7 +819,7 @@ LL | #[ignore = 1]
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
 error[E0308]: mismatched types
-  --> $DIR/malformed-attrs.rs:111:23
+  --> $DIR/malformed-attrs.rs:110:23
    |
 LL | fn test() {
    |          - help: a return type might be missing here: `-> _`
@@ -818,7 +827,7 @@ LL |     #[coroutine = 63] || {}
    |                       ^^^^^ expected `()`, found coroutine
    |
    = note: expected unit type `()`
-              found coroutine `{coroutine@$DIR/malformed-attrs.rs:111:23: 111:25}`
+              found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}`
 
 error: aborting due to 77 previous errors; 3 warnings emitted
 
@@ -849,18 +858,6 @@ LL | #[doc]
    = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
 
 Future breakage diagnostic:
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-attrs.rs:83:1
-   |
-LL | #[link]
-   | ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
-
-Future breakage diagnostic:
 error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
   --> $DIR/malformed-attrs.rs:52:1
    |
@@ -873,7 +870,7 @@ LL | #[inline = 5]
 
 Future breakage diagnostic:
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:94:1
+  --> $DIR/malformed-attrs.rs:93:1
    |
 LL | #[ignore()]
    | ^^^^^^^^^^^
@@ -884,7 +881,7 @@ LL | #[ignore()]
 
 Future breakage diagnostic:
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
-  --> $DIR/malformed-attrs.rs:223:1
+  --> $DIR/malformed-attrs.rs:222:1
    |
 LL | #[ignore = 1]
    | ^^^^^^^^^^^^^
diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr
index dc323f9a234..3bf8b7ba5d8 100644
--- a/tests/ui/c-variadic/issue-86053-1.stderr
+++ b/tests/ui/c-variadic/issue-86053-1.stderr
@@ -57,10 +57,10 @@ error[E0412]: cannot find type `F` in this scope
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
    |                                                ^
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
-   |
 help: a trait with a similar name exists
    |
 LL |     self , ... ,   self ,   self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) {
diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr
index 3e95fab441a..987625d22c9 100644
--- a/tests/ui/closures/issue-78720.stderr
+++ b/tests/ui/closures/issue-78720.stderr
@@ -9,10 +9,10 @@ error[E0412]: cannot find type `F` in this scope
    |
 LL |     _func: F,
    |            ^
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
-   |
 help: a trait with a similar name exists
    |
 LL |     _func: Fn,
diff --git a/tests/ui/closures/issue-90871.stderr b/tests/ui/closures/issue-90871.stderr
index ef1cb213f73..12020226680 100644
--- a/tests/ui/closures/issue-90871.stderr
+++ b/tests/ui/closures/issue-90871.stderr
@@ -3,6 +3,7 @@ error[E0412]: cannot find type `n` in this scope
    |
 LL |     type_ascribe!(2, n([u8; || 1]))
    |                      ^ help: a trait with a similar name exists: `Fn`
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
diff --git a/tests/ui/codegen/indirect-nocapture.rs b/tests/ui/codegen/indirect-nocapture.rs
new file mode 100644
index 00000000000..78024a94c0d
--- /dev/null
+++ b/tests/ui/codegen/indirect-nocapture.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #137668 where an indirect argument have been marked as nocapture
+// despite the fact that callee did in fact capture the address.
+//
+//@ run-pass
+//@ compile-flags: -Copt-level=2
+
+#[inline(never)]
+pub fn f(a: [u32; 64], b: [u32; 64]) -> bool {
+    &a as *const _ as usize != &b as *const _ as usize
+}
+
+fn main() {
+    static S: [u32; 64] = [0; 64];
+    assert!(f(S, S));
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
index b9db7461699..c9c8115660f 100644
--- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr
@@ -3,10 +3,10 @@ error[E0412]: cannot find type `F` in this scope
    |
 LL |          let f: F = async { 1 };
    |                 ^
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
-   |
 help: a trait with a similar name exists
    |
 LL |          let f: Fn = async { 1 };
diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr
index 56025e0d9b2..5008a2eada8 100644
--- a/tests/ui/consts/issue-89088.stderr
+++ b/tests/ui/consts/issue-89088.stderr
@@ -6,6 +6,7 @@ LL | const FOO: &A = &A::Field(Cow::Borrowed("foo"));
 ...
 LL |         FOO => todo!(),
    |         ^^^ constant of non-structural type
+   |
   --> $SRC_DIR/alloc/src/borrow.rs:LL:COL
    |
    = note: `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr
index 28753b8f9f2..7ee90ae9eb0 100644
--- a/tests/ui/derives/deriving-meta-unknown-trait.stderr
+++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr
@@ -3,6 +3,7 @@ error: cannot find derive macro `Eqr` in this scope
    |
 LL | #[derive(Eqr)]
    |          ^^^ help: a derive macro with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named derive macro `Eq` defined here
@@ -12,6 +13,7 @@ error: cannot find derive macro `Eqr` in this scope
    |
 LL | #[derive(Eqr)]
    |          ^^^ help: a derive macro with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named derive macro `Eq` defined here
diff --git a/tests/ui/did_you_mean/println-typo.stderr b/tests/ui/did_you_mean/println-typo.stderr
index a1e0b1f1ba4..7dd6fbba620 100644
--- a/tests/ui/did_you_mean/println-typo.stderr
+++ b/tests/ui/did_you_mean/println-typo.stderr
@@ -3,6 +3,7 @@ error: cannot find macro `prinltn` in this scope
    |
 LL |     prinltn!();
    |     ^^^^^^^ help: a macro with a similar name exists: `println`
+   |
   --> $SRC_DIR/std/src/macros.rs:LL:COL
    |
    = note: similarly named macro `println` defined here
diff --git a/tests/ui/error-codes/E0458.rs b/tests/ui/error-codes/E0458.rs
index 35e7e84d479..0e35ba43bfb 100644
--- a/tests/ui/error-codes/E0458.rs
+++ b/tests/ui/error-codes/E0458.rs
@@ -1,4 +1,4 @@
-#[link(kind = "wonderful_unicorn")] extern "C" {} //~ ERROR E0458
+#[link(kind = "wonderful_unicorn")] extern "C" {} //~ ERROR malformed `link` attribute input [E0539]
                                                   //~| ERROR E0459
 
 fn main() {
diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr
index c13ae4e7862..524765ea12a 100644
--- a/tests/ui/error-codes/E0458.stderr
+++ b/tests/ui/error-codes/E0458.stderr
@@ -1,8 +1,27 @@
-error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib, link-arg
-  --> $DIR/E0458.rs:1:15
+error[E0539]: malformed `link` attribute input
+  --> $DIR/E0458.rs:1:1
    |
 LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
-   |               ^^^^^^^^^^^^^^^^^^^ unknown link kind
+   | ^^^^^^^^^^^^^^-------------------^^
+   |               |
+   |               valid arguments are "static", "dylib", "framework", "raw-dylib" or "link-arg"
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(kind = "wonderful_unicorn")] extern "C" {}
+LL + #[link(name = "...")] extern "C" {}
+   |
+LL - #[link(kind = "wonderful_unicorn")] extern "C" {}
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {}
+   |
+LL - #[link(kind = "wonderful_unicorn")] extern "C" {}
+LL + #[link(name = "...", kind = "dylib|static|...")] extern "C" {}
+   |
+LL - #[link(kind = "wonderful_unicorn")] extern "C" {}
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {}
+   |
+   = and 1 other candidate
 
 error[E0459]: `#[link]` attribute requires a `name = "string"` argument
   --> $DIR/E0458.rs:1:1
@@ -12,5 +31,5 @@ LL | #[link(kind = "wonderful_unicorn")] extern "C" {}
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0458, E0459.
-For more information about an error, try `rustc --explain E0458`.
+Some errors have detailed explanations: E0459, E0539.
+For more information about an error, try `rustc --explain E0459`.
diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
index 57d6b591287..0ad3b2aead4 100644
--- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
+++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
@@ -2,6 +2,10 @@
 /// wonderful
 mod foo {}
 
+#[doc(attribute = "repr")] //~ ERROR: `#[doc(attribute)]` is meant for internal use only
+/// wonderful
+mod foo2 {}
+
 trait Mine {}
 
 #[doc(fake_variadic)]  //~ ERROR: `#[doc(fake_variadic)]` is meant for internal use only
diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
index f3c00a2156b..5a6d4d3b45e 100644
--- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
+++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
@@ -8,8 +8,18 @@ LL | #[doc(keyword = "match")]
    = help: add `#![feature(rustdoc_internals)]` 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]: `#[doc(attribute)]` is meant for internal use only
+  --> $DIR/feature-gate-rustdoc_internals.rs:5:1
+   |
+LL | #[doc(attribute = "repr")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #90418 <https://github.com/rust-lang/rust/issues/90418> for more information
+   = help: add `#![feature(rustdoc_internals)]` 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]: `#[doc(fake_variadic)]` is meant for internal use only
-  --> $DIR/feature-gate-rustdoc_internals.rs:7:1
+  --> $DIR/feature-gate-rustdoc_internals.rs:11:1
    |
 LL | #[doc(fake_variadic)]
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +29,7 @@ LL | #[doc(fake_variadic)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `#[doc(search_unbox)]` is meant for internal use only
-  --> $DIR/feature-gate-rustdoc_internals.rs:10:1
+  --> $DIR/feature-gate-rustdoc_internals.rs:14:1
    |
 LL | #[doc(search_unbox)]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -28,6 +38,6 @@ LL | #[doc(search_unbox)]
    = help: add `#![feature(rustdoc_internals)]` 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 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index 3d814700d98..e5dae4c0069 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -69,7 +69,7 @@
 //~| WARN previously accepted
 //~| HELP can only be applied to
 //~| HELP remove the attribute
-#![link()] //~ WARN attribute should be applied to an `extern` block
+#![link(name = "x")] //~ WARN attribute should be applied to an `extern` block
 //~^ WARN this was previously accepted
 #![link_name = "1900"]
 //~^ WARN attribute cannot be used on
@@ -692,38 +692,38 @@ mod link_section {
 
 // Note that this is a `check-pass` test, so it will never invoke the linker.
 
-#[link()]
+#[link(name = "x")]
 //~^ WARN attribute should be applied to an `extern` block
 //~| WARN this was previously accepted
 mod link {
     //~^ NOTE not an `extern` block
 
-    mod inner { #![link()] }
+    mod inner { #![link(name = "x")] }
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
     //~| NOTE not an `extern` block
 
-    #[link()] fn f() { }
+    #[link(name = "x")] fn f() { }
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
     //~| NOTE not an `extern` block
 
-    #[link()] struct S;
+    #[link(name = "x")] struct S;
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
     //~| NOTE not an `extern` block
 
-    #[link()] type T = S;
+    #[link(name = "x")] type T = S;
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
     //~| NOTE not an `extern` block
 
-    #[link()] impl S { }
+    #[link(name = "x")] impl S { }
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
     //~| NOTE not an `extern` block
 
-    #[link()] extern "Rust" {}
+    #[link(name = "x")] extern "Rust" {}
     //~^ WARN attribute should be applied to an `extern` block
     //~| WARN this was previously accepted
 }
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index 65e3d29e269..ef74a00e5a1 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -223,13 +223,13 @@ LL | #![no_std]
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:1
    |
-LL |   #[link()]
-   |   ^^^^^^^^^
+LL |   #[link(name = "x")]
+   |   ^^^^^^^^^^^^^^^^^^^
 ...
 LL | / mod link {
 LL | |
 LL | |
-LL | |     mod inner { #![link()] }
+LL | |     mod inner { #![link(name = "x")] }
 ...  |
 LL | | }
    | |_- not an `extern` block
@@ -316,8 +316,8 @@ LL | #![type_length_limit="0100"]
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
    |
-LL | #![link()]
-   | ^^^^^^^^^^ not an `extern` block
+LL | #![link(name = "x")]
+   | ^^^^^^^^^^^^^^^^^^^^ not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
@@ -462,48 +462,48 @@ LL |     #![no_std] impl S { }
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17
    |
-LL |     mod inner { #![link()] }
-   |     ------------^^^^^^^^^^-- not an `extern` block
+LL |     mod inner { #![link(name = "x")] }
+   |     ------------^^^^^^^^^^^^^^^^^^^^-- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:5
    |
-LL |     #[link()] fn f() { }
-   |     ^^^^^^^^^ ---------- not an `extern` block
+LL |     #[link(name = "x")] fn f() { }
+   |     ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:5
    |
-LL |     #[link()] struct S;
-   |     ^^^^^^^^^ --------- not an `extern` block
+LL |     #[link(name = "x")] struct S;
+   |     ^^^^^^^^^^^^^^^^^^^ --------- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:5
    |
-LL |     #[link()] type T = S;
-   |     ^^^^^^^^^ ----------- not an `extern` block
+LL |     #[link(name = "x")] type T = S;
+   |     ^^^^^^^^^^^^^^^^^^^ ----------- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
    |
-LL |     #[link()] impl S { }
-   |     ^^^^^^^^^ ---------- not an `extern` block
+LL |     #[link(name = "x")] impl S { }
+   |     ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5
    |
-LL |     #[link()] extern "Rust" {}
-   |     ^^^^^^^^^
+LL |     #[link(name = "x")] extern "Rust" {}
+   |     ^^^^^^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr
index dbac74b2247..2ca79aa7c10 100644
--- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr
+++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr
@@ -3,6 +3,7 @@ error[E0599]: no method named `fmt` found for opaque type `impl Debug` in the cu
    |
 LL |         x.fmt(f);
    |           ^^^ method not found in `impl Debug`
+   |
   --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
    |
    = note: the method is available for `impl Debug` here
diff --git a/tests/ui/impl-trait/impl-generic-mismatch.stderr b/tests/ui/impl-trait/impl-generic-mismatch.stderr
index 18347bd0f97..d7fff4c445d 100644
--- a/tests/ui/impl-trait/impl-generic-mismatch.stderr
+++ b/tests/ui/impl-trait/impl-generic-mismatch.stderr
@@ -48,6 +48,7 @@ error[E0643]: method `hash` has incompatible signature for trait
    |
 LL |     fn hash(&self, hasher: &mut impl Hasher) {}
    |                                 ^^^^^^^^^^^ expected generic parameter, found `impl Trait`
+   |
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
    = note: declaration in trait here
diff --git a/tests/ui/imports/suggest-remove-issue-121315.stderr b/tests/ui/imports/suggest-remove-issue-121315.stderr
index 5d0bf9bea6a..c91ea8a8793 100644
--- a/tests/ui/imports/suggest-remove-issue-121315.stderr
+++ b/tests/ui/imports/suggest-remove-issue-121315.stderr
@@ -3,10 +3,10 @@ error: the item `TryFrom` is imported redundantly
    |
 LL |     use std::convert::TryFrom;
    |         ^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `TryFrom` is already defined here
-   |
 note: the lint level is defined here
   --> $DIR/suggest-remove-issue-121315.rs:2:25
    |
@@ -18,6 +18,7 @@ error: the item `TryFrom` is imported redundantly
    |
 LL |     use std::convert::{TryFrom, TryInto};
    |                        ^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `TryFrom` is already defined here
@@ -27,6 +28,7 @@ error: the item `TryInto` is imported redundantly
    |
 LL |     use std::convert::{TryFrom, TryInto};
    |                                 ^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `TryInto` is already defined here
@@ -48,6 +50,7 @@ error: the item `Into` is imported redundantly
    |
 LL |     use std::convert::{AsMut, Into};
    |                               ^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `Into` is already defined here
diff --git a/tests/ui/issues/issue-17546.stderr b/tests/ui/issues/issue-17546.stderr
index 25a94dd9723..5bae738d3ec 100644
--- a/tests/ui/issues/issue-17546.stderr
+++ b/tests/ui/issues/issue-17546.stderr
@@ -3,10 +3,10 @@ error[E0573]: expected type, found variant `NoResult`
    |
 LL |     fn new() -> NoResult<MyEnum, String> {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named enum `Result` defined here
-   |
 help: try using the variant's enum
    |
 LL -     fn new() -> NoResult<MyEnum, String> {
@@ -57,10 +57,10 @@ error[E0573]: expected type, found variant `NoResult`
    |
 LL | fn newer() -> NoResult<foo::MyEnum, String> {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named enum `Result` defined here
-   |
 help: try using the variant's enum
    |
 LL - fn newer() -> NoResult<foo::MyEnum, String> {
diff --git a/tests/ui/issues/issue-27033.stderr b/tests/ui/issues/issue-27033.stderr
index 7a0ca888d74..129870f8c40 100644
--- a/tests/ui/issues/issue-27033.stderr
+++ b/tests/ui/issues/issue-27033.stderr
@@ -3,6 +3,7 @@ error[E0530]: match bindings cannot shadow unit variants
    |
 LL |         None @ _ => {}
    |         ^^^^ cannot be named the same as a unit variant
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the unit variant `None` is defined here
diff --git a/tests/ui/link-native-libs/issue-43925.rs b/tests/ui/link-native-libs/issue-43925.rs
index 1a210887154..e3ce71352c0 100644
--- a/tests/ui/link-native-libs/issue-43925.rs
+++ b/tests/ui/link-native-libs/issue-43925.rs
@@ -1,4 +1,6 @@
-#[link(name = "foo", cfg("rlib"))] //~ ERROR link cfg must have a single predicate argument
+#[link(name = "foo", cfg("rlib"))]
+//~^ ERROR link cfg is unstable
+//~| ERROR `cfg` predicate key must be an identifier
 extern "C" {}
 
 fn main() {}
diff --git a/tests/ui/link-native-libs/issue-43925.stderr b/tests/ui/link-native-libs/issue-43925.stderr
index 7cc347c6163..82d204222df 100644
--- a/tests/ui/link-native-libs/issue-43925.stderr
+++ b/tests/ui/link-native-libs/issue-43925.stderr
@@ -1,8 +1,18 @@
-error: link cfg must have a single predicate argument
+error[E0658]: link cfg is unstable
   --> $DIR/issue-43925.rs:1:22
    |
 LL | #[link(name = "foo", cfg("rlib"))]
    |                      ^^^^^^^^^^^
+   |
+   = help: add `#![feature(link_cfg)]` 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: `cfg` predicate key must be an identifier
+  --> $DIR/issue-43925.rs:1:26
+   |
+LL | #[link(name = "foo", cfg("rlib"))]
+   |                          ^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/link-native-libs/issue-43926.rs b/tests/ui/link-native-libs/issue-43926.rs
index 6d3003552dc..293ad3f4ec1 100644
--- a/tests/ui/link-native-libs/issue-43926.rs
+++ b/tests/ui/link-native-libs/issue-43926.rs
@@ -1,4 +1,4 @@
-#[link(name = "foo", cfg())] //~ ERROR link cfg must have a single predicate argument
+#[link(name = "foo", cfg())] //~ ERROR malformed `link` attribute input
 extern "C" {}
 
 fn main() {}
diff --git a/tests/ui/link-native-libs/issue-43926.stderr b/tests/ui/link-native-libs/issue-43926.stderr
index 7c5c50a38a9..9e3ec21cc94 100644
--- a/tests/ui/link-native-libs/issue-43926.stderr
+++ b/tests/ui/link-native-libs/issue-43926.stderr
@@ -1,8 +1,28 @@
-error: link cfg must have a single predicate argument
-  --> $DIR/issue-43926.rs:1:22
+error[E0805]: malformed `link` attribute input
+  --> $DIR/issue-43926.rs:1:1
    |
 LL | #[link(name = "foo", cfg())]
-   |                      ^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^-----^^
+   |                      |
+   |                      expected a single argument here
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "foo", cfg())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "foo", cfg())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "foo", cfg())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "foo", cfg())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0805`.
diff --git a/tests/ui/link-native-libs/link-attr-validation-early.rs b/tests/ui/link-native-libs/link-attr-validation-early.rs
index a7dd80f8920..89a34ac6ca1 100644
--- a/tests/ui/link-native-libs/link-attr-validation-early.rs
+++ b/tests/ui/link-native-libs/link-attr-validation-early.rs
@@ -1,8 +1,6 @@
 // Top-level ill-formed
-#[link] //~ ERROR valid forms for the attribute are
-        //~| WARN this was previously accepted
-#[link = "foo"] //~ ERROR valid forms for the attribute are
-                //~| WARN this was previously accepted
+#[link] //~ ERROR malformed
+#[link = "foo"] //~ ERROR malformed
 extern "C" {}
 
 fn main() {}
diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr
index d4fc2e272f8..e4799b1a161 100644
--- a/tests/ui/link-native-libs/link-attr-validation-early.stderr
+++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr
@@ -1,47 +1,45 @@
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
+error[E0539]: malformed `link` attribute input
   --> $DIR/link-attr-validation-early.rs:2:1
    |
 LL | #[link]
-   | ^^^^^^^
+   | ^^^^^^^ expected this to be a list
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL | #[link(name = "...")]
+   |       ++++++++++++++
+LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...")]
+   |       +++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   = and 1 other candidate
 
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/link-attr-validation-early.rs:4:1
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-early.rs:3:1
    |
 LL | #[link = "foo"]
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ expected this to be a list
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-
-error: aborting due to 2 previous errors
-
-Future incompatibility report: Future breakage diagnostic:
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/link-attr-validation-early.rs:2:1
+help: try changing it to one of the following valid forms of the attribute
    |
-LL | #[link]
-   | ^^^^^^^
+LL - #[link = "foo"]
+LL + #[link(name = "...")]
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
-
-Future breakage diagnostic:
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/link-attr-validation-early.rs:4:1
+LL - #[link = "foo"]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
    |
-LL | #[link = "foo"]
-   | ^^^^^^^^^^^^^^^
+LL - #[link = "foo"]
+LL + #[link(name = "...", kind = "dylib|static|...")]
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
+LL - #[link = "foo"]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0539`.
diff --git a/tests/ui/link-native-libs/link-attr-validation-late.rs b/tests/ui/link-native-libs/link-attr-validation-late.rs
index 4eeb8ba4884..d2947b5f61a 100644
--- a/tests/ui/link-native-libs/link-attr-validation-late.rs
+++ b/tests/ui/link-native-libs/link-attr-validation-late.rs
@@ -1,38 +1,36 @@
 #![feature(link_cfg)]
 
 // Top-level ill-formed
-#[link(name = "...", "literal")] //~ ERROR unexpected `#[link]` argument
-#[link(name = "...", unknown)] //~ ERROR unexpected `#[link]` argument
+#[link(name = "...", "literal")] //~ ERROR malformed `link` attribute input
+#[link(name = "...", unknown)] //~ ERROR malformed `link` attribute input
 extern "C" {}
 
 // Duplicate arguments
-#[link(name = "foo", name = "bar")] //~ ERROR multiple `name` arguments
-#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR multiple `kind` arguments
-#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR multiple `modifiers` arguments
-#[link(name = "...", cfg(false), cfg(false))] //~ ERROR multiple `cfg` arguments
-#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR multiple `wasm_import_module` arguments
+#[link(name = "foo", name = "bar")] //~ ERROR malformed `link` attribute input
+#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR malformed `link` attribute input
+#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR malformed `link` attribute input
+#[link(name = "...", cfg(false), cfg(false))] //~ ERROR malformed `link` attribute input
+#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR malformed `link` attribute input
 extern "C" {}
 
 // Ill-formed arguments
-#[link(name)] //~ ERROR link name must be of the form `name = "string"`
-              //~| ERROR `#[link]` attribute requires a `name = "string"` argument
-#[link(name())] //~ ERROR link name must be of the form `name = "string"`
-              //~| ERROR `#[link]` attribute requires a `name = "string"` argument
-#[link(name = "...", kind)] //~ ERROR link kind must be of the form `kind = "string"`
-#[link(name = "...", kind())] //~ ERROR link kind must be of the form `kind = "string"`
-#[link(name = "...", modifiers)] //~ ERROR link modifiers must be of the form `modifiers = "string"`
-#[link(name = "...", modifiers())] //~ ERROR link modifiers must be of the form `modifiers = "string"`
-#[link(name = "...", cfg)] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
-#[link(name = "...", cfg = "literal")] //~ ERROR link cfg must be of the form `cfg(/* predicate */)`
-#[link(name = "...", cfg("literal"))] //~ ERROR link cfg must have a single predicate argument
-#[link(name = "...", wasm_import_module)] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
-#[link(name = "...", wasm_import_module())] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"`
+#[link(name)] //~ ERROR malformed `link` attribute input
+#[link(name())] //~ ERROR malformed `link` attribute input
+#[link(name = "...", kind)] //~ ERROR malformed `link` attribute input
+#[link(name = "...", kind())] //~ ERROR malformed `link` attribute input
+#[link(name = "...", modifiers)] //~ ERROR malformed `link` attribute input
+#[link(name = "...", modifiers())] //~ ERROR malformed `link` attribute input
+#[link(name = "...", cfg)] //~ ERROR malformed `link` attribute input
+#[link(name = "...", cfg = "literal")] //~ ERROR malformed `link` attribute input
+#[link(name = "...", cfg("literal"))] //~ ERROR `cfg` predicate key must be an identifier
+#[link(name = "...", wasm_import_module)] //~ ERROR malformed `link` attribute input
+#[link(name = "...", wasm_import_module())] //~ ERROR malformed `link` attribute input
 extern "C" {}
 
 // Basic modifier validation
 #[link(name = "...", modifiers = "")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
 #[link(name = "...", modifiers = "no-plus-minus")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix
-#[link(name = "...", modifiers = "+unknown")] //~ ERROR unknown linking modifier `unknown`
+#[link(name = "...", modifiers = "+unknown")] //~ ERROR malformed `link` attribute input
 #[link(name = "...", modifiers = "+verbatim,+verbatim")] //~ ERROR multiple `verbatim` modifiers
 extern "C" {}
 
diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr
index f3989c09360..834dca0bc0b 100644
--- a/tests/ui/link-native-libs/link-attr-validation-late.stderr
+++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr
@@ -1,147 +1,472 @@
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
-  --> $DIR/link-attr-validation-late.rs:4:22
+error[E0565]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:4:1
    |
 LL | #[link(name = "...", "literal")]
-   |                      ^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^---------^^
+   |                      |
+   |                      didn't expect a literal here
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", "literal")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", "literal")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", "literal")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", "literal")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
-  --> $DIR/link-attr-validation-late.rs:5:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:5:1
    |
 LL | #[link(name = "...", unknown)]
-   |                      ^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^-------^^
+   |                      |
+   |                      valid arguments are "name", "kind", "modifiers", "cfg", "wasm_import_module" or "import_name_type"
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", unknown)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", unknown)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", unknown)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", unknown)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: multiple `name` arguments in a single `#[link]` attribute
-  --> $DIR/link-attr-validation-late.rs:9:22
+error[E0538]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:9:1
    |
 LL | #[link(name = "foo", name = "bar")]
-   |                      ^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^------------^^
+   |                      |
+   |                      found `name` used as a key more than once
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "foo", name = "bar")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "foo", name = "bar")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "foo", name = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "foo", name = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: multiple `kind` arguments in a single `#[link]` attribute
-  --> $DIR/link-attr-validation-late.rs:10:38
+error[E0538]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:10:1
    |
 LL | #[link(name = "...", kind = "dylib", kind = "bar")]
-   |                                      ^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------^^
+   |                                      |
+   |                                      found `kind` used as a key more than once
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", kind = "dylib", kind = "bar")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", kind = "dylib", kind = "bar")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", kind = "dylib", kind = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", kind = "dylib", kind = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: multiple `modifiers` arguments in a single `#[link]` attribute
-  --> $DIR/link-attr-validation-late.rs:11:47
+error[E0538]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:11:1
    |
 LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
-   |                                               ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^
+   |                                               |
+   |                                               found `modifiers` used as a key more than once
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: multiple `cfg` arguments in a single `#[link]` attribute
-  --> $DIR/link-attr-validation-late.rs:12:34
+error[E0538]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:12:1
    |
 LL | #[link(name = "...", cfg(false), cfg(false))]
-   |                                  ^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^
+   |                                  |
+   |                                  found `cfg` used as a key more than once
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", cfg(false), cfg(false))]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", cfg(false), cfg(false))]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", cfg(false), cfg(false))]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", cfg(false), cfg(false))]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: multiple `wasm_import_module` arguments in a single `#[link]` attribute
-  --> $DIR/link-attr-validation-late.rs:13:36
+error[E0538]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:13:1
    |
 LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: link name must be of the form `name = "string"`
-  --> $DIR/link-attr-validation-late.rs:17:8
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------^^
+   |                                    |
+   |                                    found `wasm_import_module` used as a key more than once
    |
-LL | #[link(name)]
-   |        ^^^^
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+error[E0539]: malformed `link` attribute input
   --> $DIR/link-attr-validation-late.rs:17:1
    |
 LL | #[link(name)]
-   | ^^^^^^^^^^^^^ missing `name` argument
-
-error: link name must be of the form `name = "string"`
-  --> $DIR/link-attr-validation-late.rs:19:8
+   | ^^^^^^^----^^
+   |        |
+   |        expected this to be of the form `name = "..."`
    |
-LL | #[link(name())]
-   |        ^^^^^^
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL | #[link(name = "...")]
+   |             +++++++
+LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |             ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...")]
+   |             ++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |             +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   = and 1 other candidate
 
-error[E0459]: `#[link]` attribute requires a `name = "string"` argument
-  --> $DIR/link-attr-validation-late.rs:19:1
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:18:1
    |
 LL | #[link(name())]
-   | ^^^^^^^^^^^^^^^ missing `name` argument
+   | ^^^^^^^------^^
+   |        |
+   |        expected this to be of the form `name = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link kind must be of the form `kind = "string"`
-  --> $DIR/link-attr-validation-late.rs:21:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:19:1
    |
 LL | #[link(name = "...", kind)]
-   |                      ^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^----^^
+   |                      |
+   |                      expected this to be of the form `kind = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", kind)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", kind)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL | #[link(name = "...", kind = "dylib|static|...")]
+   |                           ++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |                           +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   = and 1 other candidate
 
-error: link kind must be of the form `kind = "string"`
-  --> $DIR/link-attr-validation-late.rs:22:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:20:1
    |
 LL | #[link(name = "...", kind())]
-   |                      ^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^------^^
+   |                      |
+   |                      expected this to be of the form `kind = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", kind())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", kind())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", kind())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", kind())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link modifiers must be of the form `modifiers = "string"`
-  --> $DIR/link-attr-validation-late.rs:23:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:21:1
    |
 LL | #[link(name = "...", modifiers)]
-   |                      ^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^---------^^
+   |                      |
+   |                      expected this to be of the form `modifiers = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", modifiers)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", modifiers)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", modifiers)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", modifiers)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link modifiers must be of the form `modifiers = "string"`
-  --> $DIR/link-attr-validation-late.rs:24:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:22:1
    |
 LL | #[link(name = "...", modifiers())]
-   |                      ^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^-----------^^
+   |                      |
+   |                      expected this to be of the form `modifiers = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", modifiers())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", modifiers())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", modifiers())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", modifiers())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link cfg must be of the form `cfg(/* predicate */)`
-  --> $DIR/link-attr-validation-late.rs:25:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:23:1
    |
 LL | #[link(name = "...", cfg)]
-   |                      ^^^
+   | ^^^^^^^^^^^^^^^^^^^^^---^^
+   |                      |
+   |                      expected this to be a list
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", cfg)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", cfg)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", cfg)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", cfg)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link cfg must be of the form `cfg(/* predicate */)`
-  --> $DIR/link-attr-validation-late.rs:26:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:24:1
    |
 LL | #[link(name = "...", cfg = "literal")]
-   |                      ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                      |
+   |                      expected this to be a list
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", cfg = "literal")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", cfg = "literal")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", cfg = "literal")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", cfg = "literal")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: link cfg must have a single predicate argument
-  --> $DIR/link-attr-validation-late.rs:27:22
+error: `cfg` predicate key must be an identifier
+  --> $DIR/link-attr-validation-late.rs:25:26
    |
 LL | #[link(name = "...", cfg("literal"))]
-   |                      ^^^^^^^^^^^^^^
+   |                          ^^^^^^^^^
 
-error: wasm import module must be of the form `wasm_import_module = "string"`
-  --> $DIR/link-attr-validation-late.rs:28:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:26:1
    |
 LL | #[link(name = "...", wasm_import_module)]
-   |                      ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^------------------^^
+   |                      |
+   |                      expected this to be of the form `wasm_import_module = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: wasm import module must be of the form `wasm_import_module = "string"`
-  --> $DIR/link-attr-validation-late.rs:29:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:27:1
    |
 LL | #[link(name = "...", wasm_import_module())]
-   |                      ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^--------------------^^
+   |                      |
+   |                      expected this to be of the form `wasm_import_module = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
-  --> $DIR/link-attr-validation-late.rs:33:34
+  --> $DIR/link-attr-validation-late.rs:31:34
    |
 LL | #[link(name = "...", modifiers = "")]
    |                                  ^^
 
 error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
-  --> $DIR/link-attr-validation-late.rs:34:34
+  --> $DIR/link-attr-validation-late.rs:32:34
    |
 LL | #[link(name = "...", modifiers = "no-plus-minus")]
    |                                  ^^^^^^^^^^^^^^^
 
-error: unknown linking modifier `unknown`, expected one of: bundle, verbatim, whole-archive, as-needed
-  --> $DIR/link-attr-validation-late.rs:35:34
+error[E0539]: malformed `link` attribute input
+  --> $DIR/link-attr-validation-late.rs:33:1
    |
 LL | #[link(name = "...", modifiers = "+unknown")]
-   |                                  ^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^
+   |                                  |
+   |                                  valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed"
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", modifiers = "+unknown")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", modifiers = "+unknown")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", modifiers = "+unknown")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", modifiers = "+unknown")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: multiple `verbatim` modifiers in a single `modifiers` argument
-  --> $DIR/link-attr-validation-late.rs:36:34
+  --> $DIR/link-attr-validation-late.rs:34:34
    |
 LL | #[link(name = "...", modifiers = "+verbatim,+verbatim")]
    |                                  ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: aborting due to 22 previous errors
 
-For more information about this error, try `rustc --explain E0459`.
+Some errors have detailed explanations: E0538, E0539, E0565.
+For more information about an error, try `rustc --explain E0538`.
diff --git a/tests/ui/link-native-libs/modifiers-override-4.rs b/tests/ui/link-native-libs/modifiers-override-4.rs
new file mode 100644
index 00000000000..cc5b07e20cc
--- /dev/null
+++ b/tests/ui/link-native-libs/modifiers-override-4.rs
@@ -0,0 +1,12 @@
+#[link(name = "foo")]
+#[link(
+//~^ ERROR malformed `link` attribute input
+    name = "bar",
+    kind = "static",
+    modifiers = "+whole-archive,-whole-archive",
+    //~^ ERROR multiple `whole-archive` modifiers in a single `modifiers` argument
+    modifiers = "+bundle"
+)]
+extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/link-native-libs/modifiers-override-4.stderr b/tests/ui/link-native-libs/modifiers-override-4.stderr
new file mode 100644
index 00000000000..317e89cb39c
--- /dev/null
+++ b/tests/ui/link-native-libs/modifiers-override-4.stderr
@@ -0,0 +1,67 @@
+error[E0538]: malformed `link` attribute input
+  --> $DIR/modifiers-override-4.rs:2:1
+   |
+LL | / #[link(
+LL | |
+LL | |     name = "bar",
+LL | |     kind = "static",
+...  |
+LL | |     modifiers = "+bundle"
+   | |     --------------------- found `modifiers` used as a key more than once
+LL | | )]
+   | |__^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(
+LL -
+LL -     name = "bar",
+LL -     kind = "static",
+LL -     modifiers = "+whole-archive,-whole-archive",
+LL -
+LL -     modifiers = "+bundle"
+LL - )]
+LL + #[link(name = "...")]
+   |
+LL - #[link(
+LL -
+LL -     name = "bar",
+LL -     kind = "static",
+LL -     modifiers = "+whole-archive,-whole-archive",
+LL -
+LL -     modifiers = "+bundle"
+LL - )]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(
+LL -
+LL -     name = "bar",
+LL -     kind = "static",
+LL -     modifiers = "+whole-archive,-whole-archive",
+LL -
+LL -     modifiers = "+bundle"
+LL - )]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(
+LL -
+LL -     name = "bar",
+LL -     kind = "static",
+LL -     modifiers = "+whole-archive,-whole-archive",
+LL -
+LL -     modifiers = "+bundle"
+LL - )]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
+
+error: multiple `whole-archive` modifiers in a single `modifiers` argument
+  --> $DIR/modifiers-override-4.rs:6:17
+   |
+LL |     modifiers = "+whole-archive,-whole-archive",
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0538`.
diff --git a/tests/ui/link-native-libs/modifiers-override.rs b/tests/ui/link-native-libs/modifiers-override.rs
index cd2d003664a..a44b7d37ed8 100644
--- a/tests/ui/link-native-libs/modifiers-override.rs
+++ b/tests/ui/link-native-libs/modifiers-override.rs
@@ -4,13 +4,8 @@
 #[link(
     name = "bar",
     kind = "static",
-    modifiers = "+whole-archive,-whole-archive",
-    //~^ ERROR multiple `whole-archive` modifiers in a single `modifiers` argument
-    modifiers = "+bundle"
-    //~^ ERROR multiple `modifiers` arguments in a single `#[link]` attribute
 )]
 extern "C" {}
 //~^ ERROR overriding linking modifiers from command line is not supported
-//~| ERROR overriding linking modifiers from command line is not supported
 
 fn main() {}
diff --git a/tests/ui/link-native-libs/modifiers-override.stderr b/tests/ui/link-native-libs/modifiers-override.stderr
index 64427651e9f..3cc99c96c7c 100644
--- a/tests/ui/link-native-libs/modifiers-override.stderr
+++ b/tests/ui/link-native-libs/modifiers-override.stderr
@@ -1,28 +1,8 @@
-error: multiple `modifiers` arguments in a single `#[link]` attribute
-  --> $DIR/modifiers-override.rs:9:5
-   |
-LL |     modifiers = "+bundle"
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
-error: multiple `whole-archive` modifiers in a single `modifiers` argument
-  --> $DIR/modifiers-override.rs:7:17
-   |
-LL |     modifiers = "+whole-archive,-whole-archive",
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: overriding linking modifiers from command line is not supported
-  --> $DIR/modifiers-override.rs:12:1
-   |
-LL | extern "C" {}
-   | ^^^^^^^^^^^^^
-
 error: overriding linking modifiers from command line is not supported
-  --> $DIR/modifiers-override.rs:12:1
+  --> $DIR/modifiers-override.rs:8:1
    |
 LL | extern "C" {}
    | ^^^^^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs
index 50ad8a173ad..542f34b3eb1 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs
@@ -1,7 +1,10 @@
-//@ only-windows
-//@ only-x86
+//@ add-core-stubs
+//@ compile-flags: --target i686-pc-windows-msvc
+//@ needs-llvm-components: x86
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
 #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
-//~^ ERROR import name type must be of the form `import_name_type = "string"`
+//~^ ERROR malformed
 extern "C" { }
-
-fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr
index d2cf7a0ba1f..6121762fb03 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr
@@ -1,8 +1,28 @@
-error: import name type must be of the form `import_name_type = "string"`
-  --> $DIR/import-name-type-invalid-format.rs:3:42
+error[E0539]: malformed `link` attribute input
+  --> $DIR/import-name-type-invalid-format.rs:8:1
    |
 LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
-   |                                          ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------^^
+   |                                          |
+   |                                          expected this to be of the form `import_name_type = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0539`.
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs
index cf456b9b261..e2418642aea 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs
@@ -1,8 +1,11 @@
 // ignore-tidy-linelength
-//@ only-windows
-//@ only-x86
+//@ add-core-stubs
+//@ compile-flags: --target i686-pc-windows-msvc
+//@ needs-llvm-components: x86
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
 #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
-//~^ ERROR multiple `import_name_type` arguments in a single `#[link]` attribute
+//~^ ERROR malformed
 extern "C" { }
-
-fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr
index 8e65baf65df..adfe915b464 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr
@@ -1,8 +1,28 @@
-error: multiple `import_name_type` arguments in a single `#[link]` attribute
-  --> $DIR/import-name-type-multiple.rs:4:74
+error[E0538]: malformed `link` attribute input
+  --> $DIR/import-name-type-multiple.rs:9:1
    |
 LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
-   |                                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------^^
+   |                                                                          |
+   |                                                                          found `import_name_type` used as a key more than once
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0538`.
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs
index b3859ba1ce6..174e8682f29 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs
@@ -1,7 +1,10 @@
-//@ only-windows
-//@ only-x86
+//@ add-core-stubs
+//@ compile-flags: --target i686-pc-windows-msvc
+//@ needs-llvm-components: x86
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
 #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
-//~^ ERROR unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
+//~^ ERROR malformed
 extern "C" { }
-
-fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr
index 4b8b90eb6e2..fc24a6bed17 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr
@@ -1,8 +1,28 @@
-error: unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated
-  --> $DIR/import-name-type-unknown-value.rs:3:42
+error[E0539]: malformed `link` attribute input
+  --> $DIR/import-name-type-unknown-value.rs:8:1
    |
 LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------^^
+   |                                          |
+   |                                          valid arguments are "decorated", "noprefix" or "undecorated"
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0539`.
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs
index 3ead5cb1fd7..ca6aef79c95 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs
@@ -1,5 +1,10 @@
-//@ only-windows
-//@ only-x86
+//@ add-core-stubs
+//@ compile-flags: --target i686-pc-windows-msvc
+//@ needs-llvm-components: x86
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
 #[link(name = "foo", import_name_type = "decorated")]
 //~^ ERROR import name type can only be used with link kind `raw-dylib`
 extern "C" { }
@@ -11,5 +16,3 @@ extern "C" { }
 // Specifying `import_name_type` before `kind` shouldn't raise an error.
 #[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")]
 extern "C" { }
-
-fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr
index 75cadc471c4..075e4ffffb8 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr
@@ -1,11 +1,11 @@
 error: import name type can only be used with link kind `raw-dylib`
-  --> $DIR/import-name-type-unsupported-link-kind.rs:3:22
+  --> $DIR/import-name-type-unsupported-link-kind.rs:8:22
    |
 LL | #[link(name = "foo", import_name_type = "decorated")]
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: import name type can only be used with link kind `raw-dylib`
-  --> $DIR/import-name-type-unsupported-link-kind.rs:7:39
+  --> $DIR/import-name-type-unsupported-link-kind.rs:12:39
    |
 LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")]
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs
index ab0dcda64e6..5f1410f7d2a 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs
@@ -1,7 +1,10 @@
-//@ only-windows
-//@ ignore-x86
+//@ add-core-stubs
+//@ compile-flags: --target aarch64-pc-windows-msvc
+//@ needs-llvm-components: aarch64
+#![feature(no_core, rustc_attrs, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
 #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
 //~^ ERROR import name type is only supported on x86
 extern "C" { }
-
-fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr
index 757f1f7994e..ad3b9f79c84 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr
@@ -1,5 +1,5 @@
 error: import name type is only supported on x86
-  --> $DIR/import-name-type-x86-only.rs:3:42
+  --> $DIR/import-name-type-x86-only.rs:8:42
    |
 LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")]
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs
index 301e690be38..8651a4e7175 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs
@@ -10,7 +10,7 @@ fn test() {}
 //~^ ERROR attribute cannot be used on
 static mut imported_val: i32 = 123;
 
-#[link(name = "exporter", kind = "raw-dylib")]
+#[link(name = "exporter")]
 extern "C" {
     #[link_ordinal(13)]
     fn imported_function();
diff --git a/tests/ui/lint/int_to_ptr-unsized.rs b/tests/ui/lint/int_to_ptr-unsized.rs
new file mode 100644
index 00000000000..bbdc2474561
--- /dev/null
+++ b/tests/ui/lint/int_to_ptr-unsized.rs
@@ -0,0 +1,23 @@
+// Checks for the `integer_to_pointer_transmutes` lint with unsized types
+//
+// Related to https://github.com/rust-lang/rust/issues/145935
+
+//@ check-pass
+
+#![allow(non_camel_case_types)]
+#![allow(unused_unsafe)]
+
+#[cfg(target_pointer_width = "64")]
+type usizemetadata = i128;
+
+#[cfg(target_pointer_width = "32")]
+type usizemetadata = i64;
+
+unsafe fn unsized_type(a: usize) {
+    let _ref = unsafe { std::mem::transmute::<usizemetadata, &'static str>(0xff) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr = unsafe { std::mem::transmute::<usizemetadata, *const [u8]>(0xff) };
+    //~^ WARN transmuting an integer to a pointer
+}
+
+fn main() {}
diff --git a/tests/ui/lint/int_to_ptr-unsized.stderr b/tests/ui/lint/int_to_ptr-unsized.stderr
new file mode 100644
index 00000000000..9799af8b12c
--- /dev/null
+++ b/tests/ui/lint/int_to_ptr-unsized.stderr
@@ -0,0 +1,27 @@
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr-unsized.rs:17:25
+   |
+LL |     let _ref = unsafe { std::mem::transmute::<usizemetadata, &'static str>(0xff) };
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+   = note: `#[warn(integer_to_ptr_transmutes)]` on by default
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr-unsized.rs:19:25
+   |
+LL |     let _ptr = unsafe { std::mem::transmute::<usizemetadata, *const [u8]>(0xff) };
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr b/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr
index c14ab9e11e0..8a5c243ddf8 100644
--- a/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr
+++ b/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr
@@ -3,10 +3,10 @@ warning: the item `String` is imported redundantly
    |
 LL |         use std::string::String;
    |             ^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `String` is already defined here
-   |
 note: the lint level is defined here
   --> $DIR/use-redundant-issue-71450.rs:3:9
    |
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr
index 48d5c275055..71bc7d3b371 100644
--- a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr
@@ -3,10 +3,10 @@ warning: the item `Some` is imported redundantly
    |
 LL | use std::option::Option::Some;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `Some` is already defined here
-   |
 note: the lint level is defined here
   --> $DIR/use-redundant-prelude-rust-2015.rs:3:9
    |
@@ -18,6 +18,7 @@ warning: the item `None` is imported redundantly
    |
 LL | use std::option::Option::None;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `None` is already defined here
@@ -27,6 +28,7 @@ warning: the item `Ok` is imported redundantly
    |
 LL | use std::result::Result::Ok;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `Ok` is already defined here
@@ -36,6 +38,7 @@ warning: the item `Err` is imported redundantly
    |
 LL | use std::result::Result::Err;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `Err` is already defined here
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr
index 526771c597a..f9b7af2105c 100644
--- a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr
@@ -3,10 +3,10 @@ warning: the item `TryFrom` is imported redundantly
    |
 LL | use std::convert::TryFrom;
    |     ^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `TryFrom` is already defined here
-   |
 note: the lint level is defined here
   --> $DIR/use-redundant-prelude-rust-2021.rs:3:9
    |
@@ -18,6 +18,7 @@ warning: the item `TryInto` is imported redundantly
    |
 LL | use std::convert::TryInto;
    |     ^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
    |
    = note: the item `TryInto` is already defined here
diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.rs b/tests/ui/macros/format-foreign-dollar-without-spec.rs
new file mode 100644
index 00000000000..c57c1382c8d
--- /dev/null
+++ b/tests/ui/macros/format-foreign-dollar-without-spec.rs
@@ -0,0 +1,5 @@
+// https://github.com/rust-lang/rust/issues/137580
+fn main() {
+    println!("%65536$", 1);
+    //~^ ERROR never used
+}
diff --git a/tests/ui/macros/format-foreign-dollar-without-spec.stderr b/tests/ui/macros/format-foreign-dollar-without-spec.stderr
new file mode 100644
index 00000000000..d5a07c50f00
--- /dev/null
+++ b/tests/ui/macros/format-foreign-dollar-without-spec.stderr
@@ -0,0 +1,16 @@
+error: argument never used
+  --> $DIR/format-foreign-dollar-without-spec.rs:3:25
+   |
+LL |     println!("%65536$", 1);
+   |                         ^ argument never used
+   |
+note: format specifiers use curly braces, and the conversion specifier `
+      ` is unknown or unsupported
+  --> $DIR/format-foreign-dollar-without-spec.rs:3:15
+   |
+LL |     println!("%65536$", 1);
+   |               ^^^^^^^^
+   = note: printf formatting is not supported; see the documentation for `std::fmt`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/macros/macro-name-typo.stderr b/tests/ui/macros/macro-name-typo.stderr
index 9059b10faaa..1cc7ea6ec1b 100644
--- a/tests/ui/macros/macro-name-typo.stderr
+++ b/tests/ui/macros/macro-name-typo.stderr
@@ -3,6 +3,7 @@ error: cannot find macro `printlx` in this scope
    |
 LL |     printlx!("oh noes!");
    |     ^^^^^^^ help: a macro with a similar name exists: `println`
+   |
   --> $SRC_DIR/std/src/macros.rs:LL:COL
    |
    = note: similarly named macro `println` defined here
diff --git a/tests/ui/macros/macro-path-prelude-fail-3.stderr b/tests/ui/macros/macro-path-prelude-fail-3.stderr
index 485d7b7869a..3d0a074deeb 100644
--- a/tests/ui/macros/macro-path-prelude-fail-3.stderr
+++ b/tests/ui/macros/macro-path-prelude-fail-3.stderr
@@ -3,6 +3,7 @@ error: cannot find macro `inline` in this scope
    |
 LL |     inline!();
    |     ^^^^^^ help: a macro with a similar name exists: `line`
+   |
   --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
    |
    = note: similarly named macro `line` defined here
diff --git a/tests/ui/macros/missing-writer-issue-139830.stderr b/tests/ui/macros/missing-writer-issue-139830.stderr
index 34dd61328e0..0a1c6f6f3ea 100644
--- a/tests/ui/macros/missing-writer-issue-139830.stderr
+++ b/tests/ui/macros/missing-writer-issue-139830.stderr
@@ -3,10 +3,10 @@ error[E0599]: cannot write into `String`
    |
 LL |     let _ = write!(buf, "foo");
    |                    ^^^
+   |
   --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
    |
    = note: the method is available for `String` here
-   |
 note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
   --> $DIR/missing-writer-issue-139830.rs:7:20
    |
diff --git a/tests/ui/malformed/malformed-regressions.rs b/tests/ui/malformed/malformed-regressions.rs
index 99f0fc904a9..407920c4e4e 100644
--- a/tests/ui/malformed/malformed-regressions.rs
+++ b/tests/ui/malformed/malformed-regressions.rs
@@ -4,9 +4,7 @@
 //~^ WARN this was previously accepted
 #[inline = ""] //~ ERROR valid forms for the attribute are
 //~^ WARN this was previously accepted
-#[link] //~ ERROR valid forms for the attribute are
-//~^ WARN this was previously accepted
-#[link = ""] //~ ERROR valid forms for the attribute are
-//~^ WARN this was previously accepted
+#[link] //~ ERROR malformed
+#[link = ""] //~ ERROR malformed
 
 fn main() {}
diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr
index cab347a8062..850bcb6cbc2 100644
--- a/tests/ui/malformed/malformed-regressions.stderr
+++ b/tests/ui/malformed/malformed-regressions.stderr
@@ -9,25 +9,47 @@ LL | #[doc]
    = note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
    = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
 
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
+error[E0539]: malformed `link` attribute input
   --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link]
-   | ^^^^^^^
+   | ^^^^^^^ expected this to be a list
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL | #[link(name = "...")]
+   |       ++++++++++++++
+LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...")]
+   |       +++++++++++++++++++++++++++++++++++++++++
+LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   = and 1 other candidate
 
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-regressions.rs:9:1
+error[E0539]: malformed `link` attribute input
+  --> $DIR/malformed-regressions.rs:8:1
    |
 LL | #[link = ""]
-   | ^^^^^^^^^^^^
+   | ^^^^^^^^^^^^ expected this to be a list
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
    = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link = ""]
+LL + #[link(name = "...")]
+   |
+LL - #[link = ""]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link = ""]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link = ""]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
   --> $DIR/malformed-regressions.rs:3:1
@@ -49,6 +71,7 @@ LL | #[inline = ""]
 
 error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0539`.
 Future incompatibility report: Future breakage diagnostic:
 error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]`
   --> $DIR/malformed-regressions.rs:1:1
@@ -62,30 +85,6 @@ LL | #[doc]
    = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
 
 Future breakage diagnostic:
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-regressions.rs:7:1
-   |
-LL | #[link]
-   | ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
-
-Future breakage diagnostic:
-error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", wasm_import_module = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`
-  --> $DIR/malformed-regressions.rs:9:1
-   |
-LL | #[link = ""]
-   | ^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
-   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
-   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
-
-Future breakage diagnostic:
 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
   --> $DIR/malformed-regressions.rs:3:1
    |
diff --git a/tests/ui/methods/method-call-lifetime-args-unresolved.stderr b/tests/ui/methods/method-call-lifetime-args-unresolved.stderr
index a87c47a9f12..cc8bd18449a 100644
--- a/tests/ui/methods/method-call-lifetime-args-unresolved.stderr
+++ b/tests/ui/methods/method-call-lifetime-args-unresolved.stderr
@@ -14,6 +14,7 @@ warning: cannot specify lifetime arguments explicitly if late bound lifetime par
    |
 LL |     0.clone::<'a>();
    |               ^^
+   |
   --> $SRC_DIR/core/src/clone.rs:LL:COL
    |
    = note: the late bound lifetime parameter is introduced here
diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs
index 0a01bb84f01..0a1ee120730 100644
--- a/tests/ui/parser/bad-lit-suffixes.rs
+++ b/tests/ui/parser/bad-lit-suffixes.rs
@@ -42,5 +42,10 @@ extern "C" {}
 
 #[rustc_layout_scalar_valid_range_start(0suffix)]
 //~^ ERROR invalid suffix `suffix` for number literal
-//~| ERROR malformed `rustc_layout_scalar_valid_range_start` attribute input
 struct S;
+
+impl S {
+    #[rustc_confusables("blah"suffix)]
+    //~^ ERROR suffixes on string literals are invalid
+    fn woof() { }
+}
diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr
index e1a8a6834f4..6c3dbbcec64 100644
--- a/tests/ui/parser/bad-lit-suffixes.stderr
+++ b/tests/ui/parser/bad-lit-suffixes.stderr
@@ -10,12 +10,6 @@ error: suffixes on string literals are invalid
 LL |     "C"suffix
    |     ^^^^^^^^^ invalid suffix `suffix`
 
-error: suffixes on string literals are invalid
-  --> $DIR/bad-lit-suffixes.rs:39:15
-   |
-LL | #[link(name = "string"suffix)]
-   |               ^^^^^^^^^^^^^^ invalid suffix `suffix`
-
 warning: `extern` declarations without an explicit ABI are deprecated
   --> $DIR/bad-lit-suffixes.rs:3:1
    |
@@ -160,6 +154,12 @@ LL - #[must_use = "string"suffix]
 LL + #[must_use]
    |
 
+error: suffixes on string literals are invalid
+  --> $DIR/bad-lit-suffixes.rs:39:15
+   |
+LL | #[link(name = "string"suffix)]
+   |               ^^^^^^^^^^^^^^ invalid suffix `suffix`
+
 error: invalid suffix `suffix` for number literal
   --> $DIR/bad-lit-suffixes.rs:43:41
    |
@@ -168,14 +168,11 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
    |
    = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
 
-error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input
-  --> $DIR/bad-lit-suffixes.rs:43:1
+error: suffixes on string literals are invalid
+  --> $DIR/bad-lit-suffixes.rs:48:25
    |
-LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^
-   | |                                       |
-   | |                                       expected an integer literal here
-   | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]`
+LL |     #[rustc_confusables("blah"suffix)]
+   |                         ^^^^^^^^^^^^ invalid suffix `suffix`
 
 error: aborting due to 22 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/parser/misspelled-keywords/ref.stderr b/tests/ui/parser/misspelled-keywords/ref.stderr
index 21b99d6e663..dd33fdb21ba 100644
--- a/tests/ui/parser/misspelled-keywords/ref.stderr
+++ b/tests/ui/parser/misspelled-keywords/ref.stderr
@@ -15,6 +15,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has
    |
 LL |         Some(refe list) => println!("{list:?}"),
    |              ^^^^ ^^^^ expected 1 field, found 2
+   |
   --> $SRC_DIR/core/src/option.rs:LL:COL
    |
    = note: tuple variant has 1 field
diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr
index 33000022b8f..a99f7e16fca 100644
--- a/tests/ui/parser/recover/recover-pat-exprs.stderr
+++ b/tests/ui/parser/recover/recover-pat-exprs.stderr
@@ -690,6 +690,7 @@ error: expected one of `)`, `,`, `@`, `if`, or `|`, found `*`
    |
 LL |     let b = matches!(x, (x * x | x.f()) | x[0]);
    |                            ^ expected one of `)`, `,`, `@`, `if`, or `|`
+   |
   --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
    |
    = note: while parsing argument for this `pat` macro fragment
diff --git a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr
index 21d09ec44c4..6d430184628 100644
--- a/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr
+++ b/tests/ui/pattern/deref-patterns/implicit-const-deref.stderr
@@ -6,6 +6,7 @@ LL | const EMPTY: Vec<()> = Vec::new();
 ...
 LL |         EMPTY => {}
    |         ^^^^^ constant of non-structural type
+   |
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
    = note: `Vec<()>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
diff --git a/tests/ui/pattern/issue-115599.stderr b/tests/ui/pattern/issue-115599.stderr
index 69d10728ccd..ed465ea0bba 100644
--- a/tests/ui/pattern/issue-115599.stderr
+++ b/tests/ui/pattern/issue-115599.stderr
@@ -6,6 +6,7 @@ LL | const CONST_STRING: String = String::new();
 ...
 LL |     if let CONST_STRING = empty_str {}
    |            ^^^^^^^^^^^^ constant of non-structural type
+   |
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
    = note: `Vec<u8>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr
index 6c47b52c9de..2b48e9046bf 100644
--- a/tests/ui/privacy/suggest-box-new.stderr
+++ b/tests/ui/privacy/suggest-box-new.stderr
@@ -3,10 +3,10 @@ error[E0423]: expected function, tuple struct or tuple variant, found struct `st
    |
 LL |     let _ = std::collections::HashMap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
    |
    = note: `std::collections::HashMap` defined here
-   |
 help: you might have meant to use an associated function to build this type
    |
 LL |     let _ = std::collections::HashMap::new();
diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr
index a3b27fd7bcc..db1eed5e458 100644
--- a/tests/ui/proc-macro/parent-source-spans.stderr
+++ b/tests/ui/proc-macro/parent-source-spans.stderr
@@ -144,6 +144,7 @@ LL |     parent_source_spans!($($tokens)*);
 ...
 LL |     one!("hello", "world");
    |     ---------------------- in this macro invocation
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named tuple variant `Ok` defined here
@@ -158,6 +159,7 @@ LL |     parent_source_spans!($($tokens)*);
 ...
 LL |     two!("yay", "rust");
    |     ------------------- in this macro invocation
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named tuple variant `Ok` defined here
@@ -172,6 +174,7 @@ LL |     parent_source_spans!($($tokens)*);
 ...
 LL |     three!("hip", "hop");
    |     -------------------- in this macro invocation
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named tuple variant `Ok` defined here
diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr
index 963298311ef..45b71a3e7b3 100644
--- a/tests/ui/proc-macro/resolve-error.stderr
+++ b/tests/ui/proc-macro/resolve-error.stderr
@@ -76,6 +76,7 @@ error: cannot find derive macro `Dlone` in this scope
    |
 LL | #[derive(Dlone)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
+   |
   --> $SRC_DIR/core/src/clone.rs:LL:COL
    |
    = note: similarly named derive macro `Clone` defined here
@@ -85,6 +86,7 @@ error: cannot find derive macro `Dlone` in this scope
    |
 LL | #[derive(Dlone)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
+   |
   --> $SRC_DIR/core/src/clone.rs:LL:COL
    |
    = note: similarly named derive macro `Clone` defined here
diff --git a/tests/ui/resolve/levenshtein.stderr b/tests/ui/resolve/levenshtein.stderr
index cf478210132..7fc5710c35e 100644
--- a/tests/ui/resolve/levenshtein.stderr
+++ b/tests/ui/resolve/levenshtein.stderr
@@ -18,6 +18,7 @@ error[E0412]: cannot find type `Opiton` in this scope
    |
 LL | type B = Opiton<u8>; // Misspelled type name from the prelude.
    |          ^^^^^^ help: an enum with a similar name exists: `Option`
+   |
   --> $SRC_DIR/core/src/option.rs:LL:COL
    |
    = note: similarly named enum `Option` defined here
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs
index 65e61a21f1a..7902f40b09b 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs
@@ -5,12 +5,12 @@
 const fn assert_file_has_trailing_zero() {
     let caller = core::panic::Location::caller();
     let file_str = caller.file();
-    let file_with_nul = caller.file_with_nul();
-    if file_str.len() != file_with_nul.count_bytes() {
+    let file_cstr = caller.file_as_c_str();
+    if file_str.len() != file_cstr.count_bytes() {
         panic!("mismatched lengths");
     }
     let trailing_byte: core::ffi::c_char = unsafe {
-        *file_with_nul.as_ptr().offset(file_with_nul.count_bytes() as _)
+        *file_cstr.as_ptr().offset(file_cstr.count_bytes() as _)
     };
     if trailing_byte != 0 {
         panic!("trailing byte was nonzero")
diff --git a/tests/ui/sanitizer/cfi/no_builtins.rs b/tests/ui/sanitizer/cfi/no_builtins.rs
new file mode 100644
index 00000000000..949057689ab
--- /dev/null
+++ b/tests/ui/sanitizer/cfi/no_builtins.rs
@@ -0,0 +1,22 @@
+// Verifies that `#![no_builtins]` crates can be built with linker-plugin-lto and CFI.
+// See Issue #142284
+//
+//@ needs-sanitizer-cfi
+//@ compile-flags: -Clinker-plugin-lto -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: --crate-type rlib
+//@ build-pass
+
+#![no_builtins]
+#![no_std]
+
+pub static FUNC: fn() = initializer;
+
+pub fn initializer() {
+    call(fma_with_fma);
+}
+
+pub fn call(fn_ptr: fn()) {
+    fn_ptr();
+}
+
+pub fn fma_with_fma() {}
diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr
index a1a01c0abd6..1816a27dcdc 100644
--- a/tests/ui/suggestions/attribute-typos.stderr
+++ b/tests/ui/suggestions/attribute-typos.stderr
@@ -15,6 +15,7 @@ error: cannot find attribute `tests` in this scope
    |
 LL | #[tests]
    |   ^^^^^ help: an attribute macro with a similar name exists: `test`
+   |
   --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
    |
    = note: similarly named attribute macro `test` defined here
diff --git a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr
index 0cd6267b3b3..c81ac34aaf4 100644
--- a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr
+++ b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr
@@ -3,6 +3,7 @@ error[E0573]: expected type, found module `result`
    |
 LL | impl result {
    |      ^^^^^^ help: an enum with a similar name exists: `Result`
+   |
   --> $SRC_DIR/core/src/result.rs:LL:COL
    |
    = note: similarly named enum `Result` defined here
diff --git a/tests/ui/suggestions/enum-method-probe.stderr b/tests/ui/suggestions/enum-method-probe.stderr
index 5aa0fc44c7b..7d97495af82 100644
--- a/tests/ui/suggestions/enum-method-probe.stderr
+++ b/tests/ui/suggestions/enum-method-probe.stderr
@@ -99,10 +99,10 @@ error[E0624]: method `len` is private
    |
 LL |     res.len();
    |         ^^^ private method
+   |
   --> $SRC_DIR/core/src/option.rs:LL:COL
    |
    = note: private method defined here
-   |
 note: the method `len` exists on the type `Vec<{integer}>`
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 help: consider using `Option::expect` to unwrap the `Vec<{integer}>` value, panicking if the value is an `Option::None`
diff --git a/tests/ui/suggestions/import-trait-for-method-call.stderr b/tests/ui/suggestions/import-trait-for-method-call.stderr
index 58b07fe7a42..177ab76cd1f 100644
--- a/tests/ui/suggestions/import-trait-for-method-call.stderr
+++ b/tests/ui/suggestions/import-trait-for-method-call.stderr
@@ -3,6 +3,7 @@ error[E0599]: no method named `finish` found for struct `DefaultHasher` in the c
    |
 LL |     h.finish()
    |       ^^^^^^ method not found in `DefaultHasher`
+   |
   --> $SRC_DIR/core/src/hash/mod.rs:LL:COL
    |
    = note: the method is available for `DefaultHasher` here
diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr
index f2a146fbd52..1744162e6ce 100644
--- a/tests/ui/suggestions/multi-suggestion.ascii.stderr
+++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr
@@ -3,10 +3,10 @@ error[E0423]: expected function, tuple struct or tuple variant, found struct `st
    |
 LL |     let _ = std::collections::HashMap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
   --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
    |
    = note: `std::collections::HashMap` defined here
-   |
 help: you might have meant to use an associated function to build this type
    |
 LL |     let _ = std::collections::HashMap::new();
diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr
index 69df481579b..4835c263f19 100644
--- a/tests/ui/suggestions/multi-suggestion.unicode.stderr
+++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr
@@ -3,10 +3,10 @@ error[E0423]: expected function, tuple struct or tuple variant, found struct `st

 LL │     let _ = std::collections::HashMap();
    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━
+   ╰╴
    ╭▸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL

    ╰ note: `std::collections::HashMap` defined here
-   ╰╴
 help: you might have meant to use an associated function to build this type
    ╭╴
 LL │     let _ = std::collections::HashMap::new();
@@ -34,7 +34,7 @@ LL │         wtf: Some(Box(U {
 note: constructor is not visible here due to private fields
    ╭▸ $SRC_DIR/alloc/src/boxed.rs:LL:COL

-   ╰ note: private field
+   ├ note: private field

    ╰ note: private field
 help: you might have meant to use an associated function to build this type
diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr
index 0008b4fb5ed..8ab8a1716b1 100644
--- a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -44,6 +44,7 @@ error[E0599]: no method named `try_into` found for type `i32` in the current sco
    |
 LL |     let _i: i16 = 0_i32.try_into().unwrap();
    |                         ^^^^^^^^
+   |
   --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
    |
    = note: the method is available for `i32` here
diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr
index 2288bd1129c..40936ce1ec3 100644
--- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr
+++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr
@@ -3,10 +3,10 @@ error[E0404]: expected trait, found struct `String`
    |
 LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: String {
    |                                              ^^^^^^ not a trait
+   |
   --> $SRC_DIR/alloc/src/string.rs:LL:COL
    |
    = note: similarly named trait `ToString` defined here
-   |
 help: constrain the associated type to `String`
    |
 LL - struct Foo<T> where T: Bar, <T as Bar>::Baz: String {
@@ -22,10 +22,10 @@ error[E0404]: expected trait, found struct `String`
    |
 LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String {
    |                                                      ^^^^^^ not a trait
+   |
   --> $SRC_DIR/alloc/src/string.rs:LL:COL
    |
    = note: similarly named trait `ToString` defined here
-   |
 help: constrain the associated type to `String`
    |
 LL - struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String {
@@ -41,10 +41,10 @@ error[E0404]: expected trait, found struct `String`
    |
 LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String {
    |                                             ^^^^^^ not a trait
+   |
   --> $SRC_DIR/alloc/src/string.rs:LL:COL
    |
    = note: similarly named trait `ToString` defined here
-   |
 help: constrain the associated type to `String`
    |
 LL - fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String {
@@ -60,10 +60,10 @@ error[E0404]: expected trait, found struct `String`
    |
 LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String {
    |                                                         ^^^^^^ not a trait
+   |
   --> $SRC_DIR/alloc/src/string.rs:LL:COL
    |
    = note: similarly named trait `ToString` defined here
-   |
 help: constrain the associated type to `String`
    |
 LL - fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String {
@@ -85,6 +85,7 @@ error[E0404]: expected trait, found struct `String`
    |
 LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {}
    |                                                   ^^^^^^ help: a trait with a similar name exists: `ToString`
+   |
   --> $SRC_DIR/alloc/src/string.rs:LL:COL
    |
    = note: similarly named trait `ToString` defined here
diff --git a/tests/ui/type/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr
index db4c8f25dbc..69b6d62e987 100644
--- a/tests/ui/type/issue-7607-1.stderr
+++ b/tests/ui/type/issue-7607-1.stderr
@@ -3,6 +3,7 @@ error[E0412]: cannot find type `Fo` in this scope
    |
 LL | impl Fo {
    |      ^^ help: a trait with a similar name exists: `Fn`
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr
index 34bca426116..0359b8af93a 100644
--- a/tests/ui/typeck/issue-83693.stderr
+++ b/tests/ui/typeck/issue-83693.stderr
@@ -3,6 +3,7 @@ error[E0412]: cannot find type `F` in this scope
    |
 LL | impl F {
    |      ^ help: a trait with a similar name exists: `Fn`
+   |
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
    = note: similarly named trait `Fn` defined here
diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr
index 69d6bd74a73..a854ecb0622 100644
--- a/tests/ui/ufcs/ufcs-partially-resolved.stderr
+++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr
@@ -12,6 +12,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     let _: <u8 as E>::N;
    |                   ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -42,6 +43,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     <u8 as E>::N;
    |            ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -63,6 +65,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     let _: <u8 as E>::Y;
    |                   ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -72,6 +75,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     <u8 as E>::Y;
    |            ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -90,6 +94,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     let _: <u8 as E>::N::NN;
    |                   ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -120,6 +125,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     <u8 as E>::N::NN;
    |            ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -141,6 +147,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     let _: <u8 as E>::Y::NN;
    |                   ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
@@ -150,6 +157,7 @@ error[E0404]: expected trait, found enum `E`
    |
 LL |     <u8 as E>::Y::NN;
    |            ^ help: a trait with a similar name exists: `Eq`
+   |
   --> $SRC_DIR/core/src/cmp.rs:LL:COL
    |
    = note: similarly named trait `Eq` defined here
diff --git a/tests/ui/wasm/wasm-import-module.rs b/tests/ui/wasm/wasm-import-module.rs
index 2b3bca9a411..c38fcb1a000 100644
--- a/tests/ui/wasm/wasm-import-module.rs
+++ b/tests/ui/wasm/wasm-import-module.rs
@@ -1,12 +1,12 @@
 #![feature(link_cfg)]
 
-#[link(name = "...", wasm_import_module)] //~ ERROR: must be of the form
+#[link(name = "...", wasm_import_module)] //~ ERROR: malformed `link` attribute input
 extern "C" {}
 
-#[link(name = "...", wasm_import_module(x))] //~ ERROR: must be of the form
+#[link(name = "...", wasm_import_module(x))] //~ ERROR: malformed `link` attribute input
 extern "C" {}
 
-#[link(name = "...", wasm_import_module())] //~ ERROR: must be of the form
+#[link(name = "...", wasm_import_module())] //~ ERROR: malformed `link` attribute input
 extern "C" {}
 
 #[link(wasm_import_module = "foo", name = "bar")] //~ ERROR: `wasm_import_module` is incompatible with other arguments
diff --git a/tests/ui/wasm/wasm-import-module.stderr b/tests/ui/wasm/wasm-import-module.stderr
index 84f437941a7..f5ea449839b 100644
--- a/tests/ui/wasm/wasm-import-module.stderr
+++ b/tests/ui/wasm/wasm-import-module.stderr
@@ -1,20 +1,77 @@
-error: wasm import module must be of the form `wasm_import_module = "string"`
-  --> $DIR/wasm-import-module.rs:3:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/wasm-import-module.rs:3:1
    |
 LL | #[link(name = "...", wasm_import_module)]
-   |                      ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^------------------^^
+   |                      |
+   |                      expected this to be of the form `wasm_import_module = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", wasm_import_module)]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: wasm import module must be of the form `wasm_import_module = "string"`
-  --> $DIR/wasm-import-module.rs:6:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/wasm-import-module.rs:6:1
    |
 LL | #[link(name = "...", wasm_import_module(x))]
-   |                      ^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^---------------------^^
+   |                      |
+   |                      expected this to be of the form `wasm_import_module = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", wasm_import_module(x))]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", wasm_import_module(x))]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", wasm_import_module(x))]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", wasm_import_module(x))]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
-error: wasm import module must be of the form `wasm_import_module = "string"`
-  --> $DIR/wasm-import-module.rs:9:22
+error[E0539]: malformed `link` attribute input
+  --> $DIR/wasm-import-module.rs:9:1
    |
 LL | #[link(name = "...", wasm_import_module())]
-   |                      ^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^--------------------^^
+   |                      |
+   |                      expected this to be of the form `wasm_import_module = "..."`
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute>
+help: try changing it to one of the following valid forms of the attribute
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", kind = "dylib|static|...")]
+   |
+LL - #[link(name = "...", wasm_import_module())]
+LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]
+   |
+   = and 1 other candidate
 
 error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
   --> $DIR/wasm-import-module.rs:12:8
@@ -36,3 +93,4 @@ LL | #[link(wasm_import_module = "foo", cfg(false))]
 
 error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0539`.