about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock185
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs4
-rw-r--r--compiler/rustc_feature/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs60
-rw-r--r--compiler/rustc_lint/messages.ftl4
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs10
-rw-r--r--compiler/rustc_lint/src/lints.rs21
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs43
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_parse/messages.ftl9
-rw-r--r--compiler/rustc_parse/src/errors.rs31
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs64
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs21
-rw-r--r--compiler/rustc_passes/src/errors.rs11
-rw-r--r--compiler/rustc_target/src/asm/arm.rs80
-rw-r--r--library/std/src/sys/pal/unix/fs.rs50
-rw-r--r--library/std/src/sys/pal/unix/os.rs6
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs1
-rw-r--r--src/ci/docker/README.md16
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile35
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig15
-rw-r--r--src/ci/docker/scripts/crosstool-ng-git.sh17
-rw-r--r--src/ci/github-actions/jobs.yml3
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/tools/build-manifest/src/main.rs2
-rw-r--r--src/tools/rustfmt/src/items.rs1
-rw-r--r--src/tools/rustfmt/src/overflow.rs15
-rw-r--r--src/tools/rustfmt/src/spanned.rs9
-rw-r--r--src/tools/rustfmt/src/types.rs26
-rw-r--r--src/tools/rustfmt/tests/source/precise-capturing.rs9
-rw-r--r--src/tools/rustfmt/tests/target/precise-capturing.rs55
-rw-r--r--tests/ui/asm/arm-low-dreg.rs33
-rw-r--r--tests/ui/attributes/unsafe/double-unsafe-attributes.stderr12
-rw-r--r--tests/ui/mismatched_types/mismatched-types-issue-126222.fixed34
-rw-r--r--tests/ui/mismatched_types/mismatched-types-issue-126222.rs34
-rw-r--r--tests/ui/mismatched_types/mismatched-types-issue-126222.stderr51
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs9
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr21
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs12
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed61
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs61
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr93
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr13
-rw-r--r--tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs12
48 files changed, 987 insertions, 280 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b4f623e626d..241a37588b4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -266,7 +266,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -601,9 +601,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.5"
+version = "4.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4"
+checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58"
 dependencies = [
  "clap",
 ]
@@ -617,7 +617,7 @@ dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -644,7 +644,7 @@ dependencies = [
  "regex",
  "rustc_tools_util",
  "serde",
- "syn 2.0.66",
+ "syn 2.0.67",
  "tempfile",
  "termize",
  "tokio",
@@ -755,7 +755,7 @@ dependencies = [
  "nom",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -991,7 +991,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1002,7 +1002,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1028,7 +1028,7 @@ version = "0.1.81"
 dependencies = [
  "itertools",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1069,7 +1069,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1079,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1090,7 +1090,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1102,7 +1102,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1180,13 +1180,13 @@ dependencies = [
 
 [[package]]
 name = "displaydoc"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1506,7 +1506,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1739,7 +1739,7 @@ dependencies = [
  "markup5ever",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1781,18 +1781,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "icu_collections"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
 name = "icu_list"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1846,51 +1834,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
 
 [[package]]
-name = "icu_normalizer"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
-
-[[package]]
-name = "icu_properties"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_locid_transform",
- "icu_properties_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
-
-[[package]]
 name = "icu_provider"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1928,7 +1871,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -1939,14 +1882,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
 [[package]]
 name = "idna"
-version = "1.0.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
 dependencies = [
- "icu_normalizer",
- "icu_properties",
- "smallvec",
- "utf8_iter",
+ "unicode-bidi",
+ "unicode-normalization",
 ]
 
 [[package]]
@@ -2146,9 +2087,9 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "leb128"
@@ -2521,9 +2462,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
 dependencies = [
  "adler",
  "compiler_builtins",
@@ -2949,7 +2890,7 @@ dependencies = [
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -3141,9 +3082,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.85"
+version = "1.0.86"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
 dependencies = [
  "unicode-ident",
 ]
@@ -4045,7 +3986,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "unic-langid",
 ]
 
@@ -4179,7 +4120,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -4326,7 +4267,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "synstructure",
 ]
 
@@ -4905,7 +4846,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "synstructure",
 ]
 
@@ -5003,7 +4944,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -5153,7 +5094,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -5446,9 +5387,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.66"
+version = "2.0.67"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
+checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5463,7 +5404,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -5640,7 +5581,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -5855,7 +5796,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -6055,7 +5996,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "unic-langid-impl",
 ]
 
@@ -6076,6 +6017,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "unicode-bidi"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+
+[[package]]
 name = "unicode-ident"
 version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6176,9 +6123,9 @@ dependencies = [
 
 [[package]]
 name = "url"
-version = "2.5.1"
+version = "2.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -6192,24 +6139,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
 
 [[package]]
-name = "utf16_iter"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
-
-[[package]]
 name = "utf8-width"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
 
 [[package]]
-name = "utf8_iter"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-
-[[package]]
 name = "utf8parse"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6293,7 +6228,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "wasm-bindgen-shared",
 ]
 
@@ -6315,7 +6250,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -6396,7 +6331,7 @@ dependencies = [
  "rayon",
  "serde",
  "serde_json",
- "syn 2.0.66",
+ "syn 2.0.67",
  "windows-metadata",
 ]
 
@@ -6573,12 +6508,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "write16"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
-
-[[package]]
 name = "writeable"
 version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6648,7 +6577,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "synstructure",
 ]
 
@@ -6669,7 +6598,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
 
 [[package]]
@@ -6689,7 +6618,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
  "synstructure",
 ]
 
@@ -6712,5 +6641,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.66",
+ "syn 2.0.67",
 ]
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 79717c969d7..941bb78c0dd 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -899,7 +899,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
-        validate_attr::check_attr(&self.session.psess, attr);
+        validate_attr::check_attr(&self.features, &self.session.psess, attr);
     }
 
     fn visit_ty(&mut self, ty: &'a Ty) {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index a331d83aab0..26fc77c7f33 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1883,7 +1883,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         let mut span: Option<Span> = None;
         while let Some(attr) = attrs.next() {
             rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
-            validate_attr::check_attr(&self.cx.sess.psess, attr);
+            validate_attr::check_attr(features, &self.cx.sess.psess, attr);
 
             let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
             span = Some(current_span);
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 9e2756f07ed..5e83e0d27e1 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -1145,10 +1145,6 @@ pub fn is_valid_for_get_attr(name: Symbol) -> bool {
     })
 }
 
-pub fn is_unsafe_attr(name: Symbol) -> bool {
-    BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.safety == AttributeSafety::Unsafe)
-}
-
 pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
     LazyLock::new(|| {
         let mut map = FxHashMap::default();
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index fb3b7c0a127..bf429364318 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -125,7 +125,7 @@ pub use accepted::ACCEPTED_FEATURES;
 pub use builtin_attrs::AttributeDuplicates;
 pub use builtin_attrs::{
     deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name,
-    is_unsafe_attr, is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType,
+    is_valid_for_get_attr, AttributeGate, AttributeSafety, AttributeTemplate, AttributeType,
     BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
 };
 pub use removed::REMOVED_FEATURES;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 9dd82868adc..b3ebc0621cb 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -26,10 +26,8 @@ use rustc_middle::lint::in_external_macro;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::span_bug;
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{
-    self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt,
-    Upcast,
-};
+use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder};
+use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{sym, Ident};
@@ -1111,12 +1109,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
             )
         {
-            err.multipart_suggestion(
+            // When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end.
+            // For example:
+            // fn mismatch_types() -> i32 {
+            //     match 1 {
+            //         x => dbg!(x),
+            //     }
+            //     todo!()
+            // }
+            // -------------^^^^^^^-
+            // Don't add semicolon `;` at the end of `dbg!(x)` expr
+            fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
+                for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
+                    match node {
+                        hir::Node::Block(block) => {
+                            if let Some(ret) = block.expr
+                                && ret.hir_id == expr.hir_id
+                            {
+                                continue;
+                            }
+                        }
+                        hir::Node::Arm(arm) => {
+                            if let hir::ExprKind::Block(block, _) = arm.body.kind
+                                && let Some(ret) = block.expr
+                                && ret.hir_id == expr.hir_id
+                            {
+                                return true;
+                            }
+                        }
+                        hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => {
+                            if let Some(ret) = block.expr
+                                && ret.hir_id == expr.hir_id
+                            {
+                                continue;
+                            }
+                        }
+                        _ => {
+                            return false;
+                        }
+                    }
+                }
+
+                false
+            }
+            let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())];
+            if !is_in_arm(expr, self.tcx) {
+                suggs.push((span.shrink_to_hi(), ";".to_string()));
+            }
+            err.multipart_suggestion_verbose(
                 "you might have meant to return this value",
-                vec![
-                    (span.shrink_to_lo(), "return ".to_string()),
-                    (span.shrink_to_hi(), ";".to_string()),
-                ],
+                suggs,
                 Applicability::MaybeIncorrect,
             );
         }
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index fdedf2c2e6d..eac5083ffbf 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -825,6 +825,10 @@ lint_unnameable_test_items = cannot test inner items
 lint_unnecessary_qualification = unnecessary qualification
     .suggestion = remove the unnecessary path segments
 
+lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
+    .label = usage of unsafe attribute
+lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
+
 lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´
 
 lint_untranslatable_diag = diagnostics should be created using translatable messages
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 290bb5173db..adb2a3275c0 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -319,6 +319,16 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::UnusedQualifications { removal_span } => {
             lints::UnusedQualifications { removal_span }.decorate_lint(diag);
         }
+        BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
+            attribute_name_span,
+            sugg_spans: (left, right),
+        } => {
+            lints::UnsafeAttrOutsideUnsafe {
+                span: attribute_name_span,
+                suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
+            }
+            .decorate_lint(diag);
+        }
         BuiltinLintDiag::AssociatedConstElidedLifetime {
             elided,
             span: lt_span,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index b26d04d0618..6df3a11deb0 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2890,3 +2890,24 @@ pub struct RedundantImportVisibility {
     pub import_vis: String,
     pub max_vis: String,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(lint_unsafe_attr_outside_unsafe)]
+pub struct UnsafeAttrOutsideUnsafe {
+    #[label]
+    pub span: Span,
+    #[subdiagnostic]
+    pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    lint_unsafe_attr_outside_unsafe_suggestion,
+    applicability = "machine-applicable"
+)]
+pub struct UnsafeAttrOutsideUnsafeSuggestion {
+    #[suggestion_part(code = "unsafe(")]
+    pub left: Span,
+    #[suggestion_part(code = ")")]
+    pub right: Span,
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1913b9d6a1c..265779c9374 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -115,6 +115,7 @@ declare_lint_pass! {
         UNNAMEABLE_TYPES,
         UNREACHABLE_CODE,
         UNREACHABLE_PATTERNS,
+        UNSAFE_ATTR_OUTSIDE_UNSAFE,
         UNSAFE_OP_IN_UNSAFE_FN,
         UNSTABLE_NAME_COLLISIONS,
         UNSTABLE_SYNTAX_PRE_EXPANSION,
@@ -4902,3 +4903,45 @@ declare_lint! {
         reference: "issue #123743 <https://github.com/rust-lang/rust/issues/123743>",
     };
 }
+
+declare_lint! {
+    /// The `unsafe_attr_outside_unsafe` lint detects a missing unsafe keyword
+    /// on attributes considered unsafe.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![feature(unsafe_attributes)]
+    /// #![warn(unsafe_attr_outside_unsafe)]
+    ///
+    /// #[no_mangle]
+    /// extern "C" fn foo() {}
+    ///
+    /// fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Some attributes (e.g. `no_mangle`, `export_name`, `link_section` -- see
+    /// [issue #82499] for a more complete list) are considered "unsafe" attributes.
+    /// An unsafe attribute must only be used inside unsafe(...).
+    ///
+    /// This lint can automatically wrap the attributes in `unsafe(...)` , but this
+    /// obviously cannot verify that the preconditions of the `unsafe`
+    /// attributes are fulfilled, so that is still up to the user.
+    ///
+    /// The lint is currently "allow" by default, but that might change in the
+    /// future.
+    ///
+    /// [editions]: https://doc.rust-lang.org/edition-guide/
+    /// [issue #82499]: https://github.com/rust-lang/rust/issues/82499
+    pub UNSAFE_ATTR_OUTSIDE_UNSAFE,
+    Allow,
+    "detects unsafe attributes outside of unsafe",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
+        reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>",
+    };
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index b3838f915f6..f33aadfbbc8 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -691,6 +691,10 @@ pub enum BuiltinLintDiag {
         /// The span of the unnecessarily-qualified path to remove.
         removal_span: Span,
     },
+    UnsafeAttrOutsideUnsafe {
+        attribute_name_span: Span,
+        sugg_spans: (Span, Span),
+    },
     AssociatedConstElidedLifetime {
         elided: bool,
         span: Span,
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index efb9526eabc..f08efe60d96 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -366,6 +366,10 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment
     .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item}
     .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style
 
+parse_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
+    .suggestion = remove the `unsafe(...)`
+    .note = extraneous unsafe is not allowed in attributes
+
 parse_invalid_block_macro_segment = cannot use a `block` macro fragment here
     .label = the `block` fragment is within this context
     .suggestion = wrap this in another block
@@ -866,6 +870,11 @@ parse_unmatched_angle_brackets = {$num_extra_brackets ->
            *[other] remove extra angle brackets
         }
 
+parse_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
+    .label = usage of unsafe attribute
+parse_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
+
+
 parse_unskipped_whitespace = whitespace symbol '{$ch}' is not skipped
     .label = {parse_unskipped_whitespace}
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 46e15734853..8d49887f164 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2997,3 +2997,34 @@ pub(crate) struct DotDotRangeAttribute {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(parse_invalid_attr_unsafe)]
+#[note]
+pub struct InvalidAttrUnsafe {
+    #[primary_span]
+    pub span: Span,
+    pub name: Path,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_unsafe_attr_outside_unsafe)]
+pub struct UnsafeAttrOutsideUnsafe {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[subdiagnostic]
+    pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    parse_unsafe_attr_outside_unsafe_suggestion,
+    applicability = "machine-applicable"
+)]
+pub struct UnsafeAttrOutsideUnsafeSuggestion {
+    #[suggestion_part(code = "unsafe(")]
+    pub left: Span,
+    #[suggestion_part(code = ")")]
+    pub right: Span,
+}
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 4ca52146039..bcb1131cc19 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -5,21 +5,73 @@ use crate::{errors, parse_in};
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::DelimSpan;
 use rustc_ast::MetaItemKind;
-use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem};
+use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety};
 use rustc_errors::{Applicability, FatalError, PResult};
-use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+use rustc_feature::{
+    AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
+};
 use rustc_session::errors::report_lit_error;
-use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
+use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::ParseSess;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{sym, BytePos, Span, Symbol};
 
-pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
+pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
     if attr.is_doc_comment() {
         return;
     }
 
     let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
+    let attr_item = attr.get_normal_item();
+
+    let is_unsafe_attr = attr_info.is_some_and(|attr| attr.safety == AttributeSafety::Unsafe);
+
+    if features.unsafe_attributes {
+        if is_unsafe_attr {
+            if let ast::Safety::Default = attr_item.unsafety {
+                let path_span = attr_item.path.span;
+
+                // If the `attr_item`'s span is not from a macro, then just suggest
+                // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the
+                // `unsafe(`, `)` right after and right before the opening and closing
+                // square bracket respectively.
+                let diag_span = if attr_item.span().can_be_used_for_suggestions() {
+                    attr_item.span()
+                } else {
+                    attr.span
+                        .with_lo(attr.span.lo() + BytePos(2))
+                        .with_hi(attr.span.hi() - BytePos(1))
+                };
+
+                if attr.span.at_least_rust_2024() {
+                    psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe {
+                        span: path_span,
+                        suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion {
+                            left: diag_span.shrink_to_lo(),
+                            right: diag_span.shrink_to_hi(),
+                        },
+                    });
+                } else {
+                    psess.buffer_lint(
+                        UNSAFE_ATTR_OUTSIDE_UNSAFE,
+                        path_span,
+                        ast::CRATE_NODE_ID,
+                        BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
+                            attribute_name_span: path_span,
+                            sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
+                        },
+                    );
+                }
+            }
+        } else {
+            if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
+                psess.dcx().emit_err(errors::InvalidAttrUnsafe {
+                    span: unsafe_span,
+                    name: attr_item.path.clone(),
+                });
+            }
+        }
+    }
 
     // Check input tokens for built-in and key-value attributes.
     match attr_info {
@@ -32,7 +84,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
                 }
             }
         }
-        _ if let AttrArgs::Eq(..) = attr.get_normal_item().args => {
+        _ if let AttrArgs::Eq(..) = attr_item.args => {
             // All key-value attributes are restricted to meta-item syntax.
             match parse_meta(psess, attr) {
                 Ok(_) => {}
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 84c71c4bed2..9a830b0f49b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -384,10 +384,6 @@ passes_invalid_attr_at_crate_level =
 passes_invalid_attr_at_crate_level_item =
     the inner attribute doesn't annotate this {$kind}
 
-passes_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
-    .suggestion = remove the `unsafe(...)`
-    .note = extraneous unsafe is not allowed in attributes
-
 passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
 
 passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a0b3470df6d..2ed5bba85c6 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -10,9 +10,7 @@ use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, IntoDiagArg, MultiSpan};
 use rustc_errors::{DiagCtxtHandle, StashKey};
-use rustc_feature::{
-    is_unsafe_attr, AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP,
-};
+use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir};
@@ -116,8 +114,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         let mut seen = FxHashMap::default();
         let attrs = self.tcx.hir().attrs(hir_id);
         for attr in attrs {
-            self.check_unsafe_attr(attr);
-
             match attr.path().as_slice() {
                 [sym::diagnostic, sym::do_not_recommend] => {
                     self.check_do_not_recommend(attr.span, hir_id, target)
@@ -312,21 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         true
     }
 
-    /// Checks if `unsafe()` is applied to an invalid attribute.
-    fn check_unsafe_attr(&self, attr: &Attribute) {
-        if !attr.is_doc_comment() {
-            let attr_item = attr.get_normal_item();
-            if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety {
-                if !is_unsafe_attr(attr.name_or_empty()) {
-                    self.dcx().emit_err(errors::InvalidAttrUnsafe {
-                        span: unsafe_span,
-                        name: attr_item.path.clone(),
-                    });
-                }
-            }
-        }
-    }
-
     /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition
     fn check_diagnostic_on_unimplemented(
         &self,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index d27b94ebd22..f0596568092 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -4,7 +4,7 @@ use std::{
 };
 
 use crate::fluent_generated as fluent;
-use rustc_ast::{ast, Label};
+use rustc_ast::Label;
 use rustc_errors::{
     codes::*, Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee,
     Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
@@ -863,15 +863,6 @@ pub struct InvalidAttrAtCrateLevel {
     pub item: Option<ItemFollowingInnerAttr>,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_invalid_attr_unsafe)]
-#[note]
-pub struct InvalidAttrUnsafe {
-    #[primary_span]
-    pub span: Span,
-    pub name: ast::Path,
-}
-
 #[derive(Clone, Copy)]
 pub struct ItemFollowingInnerAttr {
     pub span: Span,
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index 9d79faadd61..70fcaab1847 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -148,22 +148,22 @@ def_regs! {
         r11: reg = ["r11", "fp"] % frame_pointer_r11,
         r12: reg = ["r12", "ip"] % not_thumb1,
         r14: reg = ["r14", "lr"] % not_thumb1,
-        s0: sreg, sreg_low16 = ["s0"],
-        s1: sreg, sreg_low16 = ["s1"],
-        s2: sreg, sreg_low16 = ["s2"],
-        s3: sreg, sreg_low16 = ["s3"],
-        s4: sreg, sreg_low16 = ["s4"],
-        s5: sreg, sreg_low16 = ["s5"],
-        s6: sreg, sreg_low16 = ["s6"],
-        s7: sreg, sreg_low16 = ["s7"],
-        s8: sreg, sreg_low16 = ["s8"],
-        s9: sreg, sreg_low16 = ["s9"],
-        s10: sreg, sreg_low16 = ["s10"],
-        s11: sreg, sreg_low16 = ["s11"],
-        s12: sreg, sreg_low16 = ["s12"],
-        s13: sreg, sreg_low16 = ["s13"],
-        s14: sreg, sreg_low16 = ["s14"],
-        s15: sreg, sreg_low16 = ["s15"],
+        s0: sreg_low16, sreg = ["s0"],
+        s1: sreg_low16, sreg = ["s1"],
+        s2: sreg_low16, sreg = ["s2"],
+        s3: sreg_low16, sreg = ["s3"],
+        s4: sreg_low16, sreg = ["s4"],
+        s5: sreg_low16, sreg = ["s5"],
+        s6: sreg_low16, sreg = ["s6"],
+        s7: sreg_low16, sreg = ["s7"],
+        s8: sreg_low16, sreg = ["s8"],
+        s9: sreg_low16, sreg = ["s9"],
+        s10: sreg_low16, sreg = ["s10"],
+        s11: sreg_low16, sreg = ["s11"],
+        s12: sreg_low16, sreg = ["s12"],
+        s13: sreg_low16, sreg = ["s13"],
+        s14: sreg_low16, sreg = ["s14"],
+        s15: sreg_low16, sreg = ["s15"],
         s16: sreg = ["s16"],
         s17: sreg = ["s17"],
         s18: sreg = ["s18"],
@@ -180,22 +180,22 @@ def_regs! {
         s29: sreg = ["s29"],
         s30: sreg = ["s30"],
         s31: sreg = ["s31"],
-        d0: dreg, dreg_low16, dreg_low8 = ["d0"],
-        d1: dreg, dreg_low16, dreg_low8 = ["d1"],
-        d2: dreg, dreg_low16, dreg_low8 = ["d2"],
-        d3: dreg, dreg_low16, dreg_low8 = ["d3"],
-        d4: dreg, dreg_low16, dreg_low8 = ["d4"],
-        d5: dreg, dreg_low16, dreg_low8 = ["d5"],
-        d6: dreg, dreg_low16, dreg_low8 = ["d6"],
-        d7: dreg, dreg_low16, dreg_low8 = ["d7"],
-        d8: dreg, dreg_low16 = ["d8"],
-        d9: dreg, dreg_low16 = ["d9"],
-        d10: dreg, dreg_low16 = ["d10"],
-        d11: dreg, dreg_low16 = ["d11"],
-        d12: dreg, dreg_low16 = ["d12"],
-        d13: dreg, dreg_low16 = ["d13"],
-        d14: dreg, dreg_low16 = ["d14"],
-        d15: dreg, dreg_low16 = ["d15"],
+        d0: dreg_low8, dreg_low16, dreg = ["d0"],
+        d1: dreg_low8, dreg_low16, dreg = ["d1"],
+        d2: dreg_low8, dreg_low16, dreg = ["d2"],
+        d3: dreg_low8, dreg_low16, dreg = ["d3"],
+        d4: dreg_low8, dreg_low16, dreg = ["d4"],
+        d5: dreg_low8, dreg_low16, dreg = ["d5"],
+        d6: dreg_low8, dreg_low16, dreg = ["d6"],
+        d7: dreg_low8, dreg_low16, dreg = ["d7"],
+        d8: dreg_low16, dreg = ["d8"],
+        d9: dreg_low16, dreg = ["d9"],
+        d10: dreg_low16, dreg = ["d10"],
+        d11: dreg_low16, dreg = ["d11"],
+        d12: dreg_low16, dreg = ["d12"],
+        d13: dreg_low16, dreg = ["d13"],
+        d14: dreg_low16, dreg = ["d14"],
+        d15: dreg_low16, dreg = ["d15"],
         d16: dreg = ["d16"],
         d17: dreg = ["d17"],
         d18: dreg = ["d18"],
@@ -212,14 +212,14 @@ def_regs! {
         d29: dreg = ["d29"],
         d30: dreg = ["d30"],
         d31: dreg = ["d31"],
-        q0: qreg, qreg_low8, qreg_low4 = ["q0"],
-        q1: qreg, qreg_low8, qreg_low4 = ["q1"],
-        q2: qreg, qreg_low8, qreg_low4 = ["q2"],
-        q3: qreg, qreg_low8, qreg_low4 = ["q3"],
-        q4: qreg, qreg_low8 = ["q4"],
-        q5: qreg, qreg_low8 = ["q5"],
-        q6: qreg, qreg_low8 = ["q6"],
-        q7: qreg, qreg_low8 = ["q7"],
+        q0: qreg_low4, qreg_low8, qreg = ["q0"],
+        q1: qreg_low4, qreg_low8, qreg = ["q1"],
+        q2: qreg_low4, qreg_low8, qreg = ["q2"],
+        q3: qreg_low4, qreg_low8, qreg = ["q3"],
+        q4: qreg_low8, qreg = ["q4"],
+        q5: qreg_low8, qreg = ["q5"],
+        q6: qreg_low8, qreg = ["q6"],
+        q7: qreg_low8, qreg = ["q7"],
         q8: qreg = ["q8"],
         q9: qreg = ["q9"],
         q10: qreg = ["q10"],
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 5c4ccd32850..92c76ec4303 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -20,14 +20,14 @@ use crate::sys::time::SystemTime;
 use crate::sys::{cvt, cvt_r};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
-#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
+#[cfg(all(target_os = "linux", target_env = "gnu"))]
 use crate::sys::weak::syscall;
 #[cfg(target_os = "android")]
 use crate::sys::weak::weak;
 
 use libc::{c_int, mode_t};
 
-#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))]
+#[cfg(all(target_os = "linux", target_env = "gnu"))]
 use libc::c_char;
 #[cfg(any(
     all(target_os = "linux", not(target_env = "musl")),
@@ -1891,8 +1891,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
 
 #[cfg(target_vendor = "apple")]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
-    use crate::sync::atomic::{AtomicBool, Ordering};
-
     const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA;
 
     struct FreeOnDrop(libc::copyfile_state_t);
@@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
         }
     }
 
-    // MacOS prior to 10.12 don't support `fclonefileat`
-    // We store the availability in a global to avoid unnecessary syscalls
-    static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true);
-    syscall! {
-        // Mirrors `libc::fclonefileat`
-        fn fclonefileat(
-            srcfd: libc::c_int,
-            dst_dirfd: libc::c_int,
-            dst: *const c_char,
-            flags: libc::c_int
-        ) -> libc::c_int
-    }
-
     let (reader, reader_metadata) = open_from(from)?;
 
-    // Opportunistically attempt to create a copy-on-write clone of `from`
-    // using `fclonefileat`.
-    if HAS_FCLONEFILEAT.load(Ordering::Relaxed) {
-        let clonefile_result = run_path_with_cstr(to, &|to| {
-            cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
-        });
-        match clonefile_result {
-            Ok(_) => return Ok(reader_metadata.len()),
-            Err(err) => match err.raw_os_error() {
-                // `fclonefileat` will fail on non-APFS volumes, if the
-                // destination already exists, or if the source and destination
-                // are on different devices. In all these cases `fcopyfile`
-                // should succeed.
-                Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
-                Some(libc::ENOSYS) => HAS_FCLONEFILEAT.store(false, Ordering::Relaxed),
-                _ => return Err(err),
-            },
-        }
+    let clonefile_result = run_path_with_cstr(to, &|to| {
+        cvt(unsafe { libc::fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) })
+    });
+    match clonefile_result {
+        Ok(_) => return Ok(reader_metadata.len()),
+        Err(e) => match e.raw_os_error() {
+            // `fclonefileat` will fail on non-APFS volumes, if the
+            // destination already exists, or if the source and destination
+            // are on different devices. In all these cases `fcopyfile`
+            // should succeed.
+            Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (),
+            _ => return Err(e),
+        },
     }
 
     // Fall back to using `fcopyfile` if `fclonefileat` does not succeed.
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 2e71ceceb58..40e2d1403ef 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -738,17 +738,17 @@ pub fn home_dir() -> Option<PathBuf> {
             n => n as usize,
         };
         let mut buf = Vec::with_capacity(amt);
-        let mut passwd: libc::passwd = mem::zeroed();
+        let mut p = mem::MaybeUninit::<libc::passwd>::uninit();
         let mut result = ptr::null_mut();
         match libc::getpwuid_r(
             libc::getuid(),
-            &mut passwd,
+            p.as_mut_ptr(),
             buf.as_mut_ptr(),
             buf.capacity(),
             &mut result,
         ) {
             0 if !result.is_null() => {
-                let ptr = passwd.pw_dir as *const _;
+                let ptr = (*result).pw_dir as *const _;
                 let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
                 Some(OsStringExt::from_vec(bytes))
             }
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index e4dbd3a13fe..258a0347451 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/125141
+Last change is for: https://github.com/rust-lang/rust/pull/126298
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index f90403d2ec4..8b379d3be5c 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -217,6 +217,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
         ("arm-unknown-linux-gnueabihf", false),
         ("armv7-unknown-linux-gnueabihf", false),
         ("loongarch64-unknown-linux-gnu", false),
+        ("loongarch64-unknown-linux-musl", false),
         ("mips-unknown-linux-gnu", false),
         ("mips64-unknown-linux-gnuabi64", false),
         ("mips64el-unknown-linux-gnuabi64", false),
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 824c904e17f..985e3b37422 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -271,6 +271,22 @@ For targets: `loongarch64-unknown-linux-gnu`
 - C compiler > gcc version = 13.2.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
+### `loongarch64-linux-musl.defconfig`
+
+For targets: `loongarch64-unknown-linux-musl`
+
+- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET}
+- Path and misc options > Use a mirror = ENABLE
+- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc
+- Target options > Target Architecture = loongarch
+- Target options > Bitness = 64-bit
+- Operating System > Target OS = linux
+- Operating System > Linux kernel version = 5.19.16
+- Binary utilities > Version of binutils = 2.41
+- C-library > musl version = 1.2.5
+- C compiler > gcc version = 13.2.0
+- C compiler > C++ = ENABLE -- to cross compile LLVM
+
 ### `mips-linux-gnu.defconfig`
 
 For targets: `mips-unknown-linux-gnu`
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
new file mode 100644
index 00000000000..560adf971ba
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile
@@ -0,0 +1,35 @@
+FROM ubuntu:22.04
+
+COPY scripts/cross-apt-packages.sh /scripts/
+RUN sh /scripts/cross-apt-packages.sh
+
+COPY scripts/crosstool-ng-git.sh /scripts/
+RUN sh /scripts/crosstool-ng-git.sh
+
+COPY scripts/rustbuild-setup.sh /scripts/
+RUN sh /scripts/rustbuild-setup.sh
+WORKDIR /tmp
+
+COPY scripts/crosstool-ng-build.sh /scripts/
+COPY host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig
+RUN /scripts/crosstool-ng-build.sh
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-musl/bin
+
+ENV CC_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-gcc \
+    AR_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-ar \
+    CXX_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-g++
+
+ENV HOSTS=loongarch64-unknown-linux-musl
+
+ENV RUST_CONFIGURE_ARGS \
+      --enable-extended \
+      --enable-lld \
+      --disable-docs \
+      --set target.loongarch64-unknown-linux-musl.crt-static=false \
+      --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr
+
+ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig
new file mode 100644
index 00000000000..3ab676ed971
--- /dev/null
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig
@@ -0,0 +1,15 @@
+CT_CONFIG_VERSION="4"
+CT_EXPERIMENTAL=y
+CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
+CT_ARCH_LOONGARCH=y
+# CT_DEMULTILIB is not set
+CT_ARCH_USE_MMU=y
+CT_ARCH_ARCH="loongarch64"
+CT_KERNEL_LINUX=y
+CT_LINUX_V_5_19=y
+CT_LIBC_MUSL=y
+CT_CC_GCC_ENABLE_DEFAULT_PIE=y
+CT_CC_LANG_CXX=y
+CT_GETTEXT_NEEDED=y
diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh
new file mode 100644
index 00000000000..2a10e262df8
--- /dev/null
+++ b/src/ci/docker/scripts/crosstool-ng-git.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -ex
+
+URL=https://github.com/crosstool-ng/crosstool-ng
+REV=c64500d94be92ed1bcdfdef911048a14e216a5e1
+
+mkdir crosstool-ng
+cd crosstool-ng
+git init
+git fetch --depth=1 ${URL} ${REV}
+git reset --hard FETCH_HEAD
+./bootstrap
+./configure --prefix=/usr/local
+make -j$(nproc)
+make install
+cd ..
+rm -rf crosstool-ng
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 4366a92fbcd..e3903c3dd5a 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -144,6 +144,9 @@ auto:
   - image: dist-loongarch64-linux
     <<: *job-linux-4c
 
+  - image: dist-loongarch64-musl
+    <<: *job-linux-4c
+
   - image: dist-ohos
     <<: *job-linux-4c
 
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 537c88cd22b..39659473f22 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -93,6 +93,7 @@ target | notes
 `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
 `armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
 [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
+[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5)
 `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
 `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17)
 `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
@@ -305,7 +306,6 @@ target | std | host | notes
 `i686-uwp-windows-msvc` | ✓ |  | [^x86_32-floats-return-ABI]
 [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ |   | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
 `i686-wrs-vxworks` | ? |  | [^x86_32-floats-return-ABI]
-[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? |  | LoongArch64 Linux (LP64D ABI) with musl 1.2.3
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
 `mips-unknown-linux-musl` | ✓ |  | MIPS Linux with musl 1.2.3
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index a709aab7ce2..a2e7907b532 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -25,6 +25,7 @@ static HOSTS: &[&str] = &[
     "i686-pc-windows-msvc",
     "i686-unknown-linux-gnu",
     "loongarch64-unknown-linux-gnu",
+    "loongarch64-unknown-linux-musl",
     "mips-unknown-linux-gnu",
     "mips64-unknown-linux-gnuabi64",
     "mips64el-unknown-linux-gnuabi64",
@@ -106,6 +107,7 @@ static TARGETS: &[&str] = &[
     "i686-unknown-redox",
     "i686-unknown-uefi",
     "loongarch64-unknown-linux-gnu",
+    "loongarch64-unknown-linux-musl",
     "loongarch64-unknown-none",
     "loongarch64-unknown-none-softfloat",
     "m68k-unknown-linux-gnu",
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index c8ea104e9d6..eb11604b277 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -1994,7 +1994,6 @@ fn rewrite_static(
     static_parts: &StaticParts<'_>,
     offset: Indent,
 ) -> Option<String> {
-    println!("rewriting static");
     let colon = colon_spaces(context.config);
     let mut prefix = format!(
         "{}{}{}{} {}{}{}",
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index c44f3788d97..a1de71a35be 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -83,6 +83,7 @@ pub(crate) enum OverflowableItem<'a> {
     TuplePatField(&'a TuplePatField<'a>),
     Ty(&'a ast::Ty),
     Pat(&'a ast::Pat),
+    PreciseCapturingArg(&'a ast::PreciseCapturingArg),
 }
 
 impl<'a> Rewrite for OverflowableItem<'a> {
@@ -123,6 +124,7 @@ impl<'a> OverflowableItem<'a> {
             OverflowableItem::TuplePatField(pat) => f(*pat),
             OverflowableItem::Ty(ty) => f(*ty),
             OverflowableItem::Pat(pat) => f(*pat),
+            OverflowableItem::PreciseCapturingArg(arg) => f(*arg),
         }
     }
 
@@ -137,6 +139,9 @@ impl<'a> OverflowableItem<'a> {
                     matches!(meta_item.kind, ast::MetaItemKind::Word)
                 }
             },
+            // FIXME: Why don't we consider `SegmentParam` to be simple?
+            // FIXME: If we also fix `SegmentParam`, then we should apply the same
+            // heuristic to `PreciseCapturingArg`.
             _ => false,
         }
     }
@@ -244,7 +249,15 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types {
     }
 }
 
-impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat);
+impl_into_overflowable_item_for_ast_node!(
+    Expr,
+    GenericParam,
+    NestedMetaItem,
+    FieldDef,
+    Ty,
+    Pat,
+    PreciseCapturingArg
+);
 impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]);
 
 pub(crate) fn into_overflowable_list<'a, T>(
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 28911f8af1d..1ee691b4ade 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -203,3 +203,12 @@ impl Spanned for ast::NestedMetaItem {
         self.span()
     }
 }
+
+impl Spanned for ast::PreciseCapturingArg {
+    fn span(&self) -> Span {
+        match self {
+            ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span,
+            ast::PreciseCapturingArg::Arg(path, _) => path.span,
+        }
+    }
+}
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index c12f271bc5d..c0bf9482b11 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -177,6 +177,17 @@ impl<'a> Rewrite for SegmentParam<'a> {
     }
 }
 
+impl Rewrite for ast::PreciseCapturingArg {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        match self {
+            ast::PreciseCapturingArg::Lifetime(lt) => lt.rewrite(context, shape),
+            ast::PreciseCapturingArg::Arg(p, _) => {
+                rewrite_path(context, PathContext::Type, &None, p, shape)
+            }
+        }
+    }
+}
+
 impl Rewrite for ast::AssocItemConstraint {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         use ast::AssocItemConstraintKind::{Bound, Equality};
@@ -564,9 +575,10 @@ impl Rewrite for ast::GenericBound {
                     .map(|s| format!("{constness}{asyncness}{polarity}{s}"))
                     .map(|s| if has_paren { format!("({})", s) } else { s })
             }
+            ast::GenericBound::Use(ref args, span) => {
+                overflow::rewrite_with_angle_brackets(context, "use", args.iter(), shape, span)
+            }
             ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape),
-            // FIXME(precise_capturing): Should implement formatting before stabilization.
-            ast::GenericBound::Use(..) => None,
         }
     }
 }
@@ -933,9 +945,7 @@ fn rewrite_bare_fn(
 fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {
     let is_trait = |b: &ast::GenericBound| match b {
         ast::GenericBound::Outlives(..) => false,
-        ast::GenericBound::Trait(..) => true,
-        // FIXME(precise_capturing): This ordering fn should be reworked.
-        ast::GenericBound::Use(..) => false,
+        ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => true,
     };
     let is_lifetime = |b: &ast::GenericBound| !is_trait(b);
     let last_trait_index = generic_bounds.iter().rposition(is_trait);
@@ -969,9 +979,8 @@ fn join_bounds_inner(
     let generic_bounds_in_order = is_generic_bounds_in_order(items);
     let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b {
         ast::GenericBound::Outlives(..) => true,
-        ast::GenericBound::Trait(..) => last_line_extendable(s),
-        // FIXME(precise_capturing): This ordering fn should be reworked.
-        ast::GenericBound::Use(..) => true,
+        // We treat `use<>` like a trait bound here.
+        ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => last_line_extendable(s),
     };
 
     // Whether a GenericBound item is a PathSegment segment that includes internal array
@@ -993,6 +1002,7 @@ fn join_bounds_inner(
                 }
             }
         }
+        ast::GenericBound::Use(args, _) => args.len() > 1,
         _ => false,
     };
 
diff --git a/src/tools/rustfmt/tests/source/precise-capturing.rs b/src/tools/rustfmt/tests/source/precise-capturing.rs
new file mode 100644
index 00000000000..b61cceeffe8
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/precise-capturing.rs
@@ -0,0 +1,9 @@
+fn hello() -> impl
+use<'a> + Sized {}
+
+fn all_three() -> impl Sized + use<'a> + 'a;
+
+fn pathological() -> impl use<'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a,
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a,
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a> + Sized {}
diff --git a/src/tools/rustfmt/tests/target/precise-capturing.rs b/src/tools/rustfmt/tests/target/precise-capturing.rs
new file mode 100644
index 00000000000..d21374f44c1
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/precise-capturing.rs
@@ -0,0 +1,55 @@
+fn hello() -> impl use<'a> + Sized {}
+
+fn all_three() -> impl Sized + use<'a> + 'a;
+
+fn pathological() -> impl use<
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+> + Sized {
+}
diff --git a/tests/ui/asm/arm-low-dreg.rs b/tests/ui/asm/arm-low-dreg.rs
new file mode 100644
index 00000000000..e9ff0117e2d
--- /dev/null
+++ b/tests/ui/asm/arm-low-dreg.rs
@@ -0,0 +1,33 @@
+//@ build-pass
+//@ compile-flags: --target=armv7-unknown-linux-gnueabihf
+//@ needs-llvm-components: arm
+#![feature(no_core, rustc_attrs, decl_macro, lang_items)]
+#![crate_type = "rlib"]
+#![no_std]
+#![no_core]
+
+// We accidentally classified "d0"..="d15" as dregs, even though they are in dreg_low16,
+// and thus didn't compile them on platforms with only 16 dregs.
+// Highlighted in https://github.com/rust-lang/rust/issues/126797
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for f64 {}
+
+#[rustc_builtin_macro]
+pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
+    /* compiler built-in */
+}
+
+
+fn f(x: f64) -> f64 {
+    let out: f64;
+    unsafe {
+        asm!("vmov.f64 d1, d0", out("d1") out, in("d0") x);
+    }
+    out
+}
diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
index 1c07a5bf8ba..ea82bac6df0 100644
--- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
+++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
@@ -9,12 +9,6 @@ help: escape `unsafe` to use it as an identifier
 LL | #[unsafe(r#unsafe(no_mangle))]
    |          ++
 
-error: cannot find attribute `r#unsafe` in this scope
-  --> $DIR/double-unsafe-attributes.rs:3:10
-   |
-LL | #[unsafe(unsafe(no_mangle))]
-   |          ^^^^^^
-
 error: `r#unsafe` is not an unsafe attribute
   --> $DIR/double-unsafe-attributes.rs:3:3
    |
@@ -23,5 +17,11 @@ LL | #[unsafe(unsafe(no_mangle))]
    |
    = note: extraneous unsafe is not allowed in attributes
 
+error: cannot find attribute `r#unsafe` in this scope
+  --> $DIR/double-unsafe-attributes.rs:3:10
+   |
+LL | #[unsafe(unsafe(no_mangle))]
+   |          ^^^^^^
+
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed b/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed
new file mode 100644
index 00000000000..30fd0028f19
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed
@@ -0,0 +1,34 @@
+//@ run-rustfix
+#![allow(unreachable_code, dead_code)]
+
+fn main() {
+    fn mismatch_types1() -> i32 {
+        match 1 {
+            x => return dbg!(x), //~ ERROR mismatched types
+        }
+        todo!()
+    }
+
+    fn mismatch_types2() -> i32 {
+        match 2 {
+            x => {
+                return dbg!(x) //~ ERROR mismatched types
+            }
+        }
+        todo!()
+    }
+
+    fn mismatch_types3() -> i32 {
+        match 1 {
+            _ => return dbg!(1) //~ ERROR mismatched types
+        }
+        todo!()
+    }
+
+    fn mismatch_types4() -> i32 {
+        match 1 {
+            _ => {return dbg!(1)} //~ ERROR mismatched types
+        }
+        todo!()
+    }
+}
diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.rs b/tests/ui/mismatched_types/mismatched-types-issue-126222.rs
new file mode 100644
index 00000000000..59178702489
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.rs
@@ -0,0 +1,34 @@
+//@ run-rustfix
+#![allow(unreachable_code, dead_code)]
+
+fn main() {
+    fn mismatch_types1() -> i32 {
+        match 1 {
+            x => dbg!(x), //~ ERROR mismatched types
+        }
+        todo!()
+    }
+
+    fn mismatch_types2() -> i32 {
+        match 2 {
+            x => {
+                dbg!(x) //~ ERROR mismatched types
+            }
+        }
+        todo!()
+    }
+
+    fn mismatch_types3() -> i32 {
+        match 1 {
+            _ => dbg!(1) //~ ERROR mismatched types
+        }
+        todo!()
+    }
+
+    fn mismatch_types4() -> i32 {
+        match 1 {
+            _ => {dbg!(1)} //~ ERROR mismatched types
+        }
+        todo!()
+    }
+}
diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr
new file mode 100644
index 00000000000..2a8f9867abb
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr
@@ -0,0 +1,51 @@
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types-issue-126222.rs:7:18
+   |
+LL |             x => dbg!(x),
+   |                  ^^^^^^^ expected `()`, found integer
+   |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might have meant to return this value
+   |
+LL |             x => return dbg!(x),
+   |                  ++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types-issue-126222.rs:15:17
+   |
+LL |                 dbg!(x)
+   |                 ^^^^^^^ expected `()`, found integer
+   |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might have meant to return this value
+   |
+LL |                 return dbg!(x)
+   |                 ++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types-issue-126222.rs:23:18
+   |
+LL |             _ => dbg!(1)
+   |                  ^^^^^^^ expected `()`, found integer
+   |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might have meant to return this value
+   |
+LL |             _ => return dbg!(1)
+   |                  ++++++
+
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types-issue-126222.rs:30:19
+   |
+LL |             _ => {dbg!(1)}
+   |                   ^^^^^^^ expected `()`, found integer
+   |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might have meant to return this value
+   |
+LL |             _ => {return dbg!(1)}
+   |                   ++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs
new file mode 100644
index 00000000000..c6f9115cde7
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs
@@ -0,0 +1,9 @@
+#![deny(rust_2024_compatibility)]
+#![feature(unsafe_attributes)]
+
+#[no_mangle]
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+extern "C" fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
new file mode 100644
index 00000000000..f0689d9883c
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
@@ -0,0 +1,21 @@
+error: unsafe attribute used without unsafe
+  --> $DIR/in_2024_compatibility.rs:4:3
+   |
+LL | #[no_mangle]
+   |   ^^^^^^^^^ usage of unsafe attribute
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+note: the lint level is defined here
+  --> $DIR/in_2024_compatibility.rs:1:9
+   |
+LL | #![deny(rust_2024_compatibility)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(unsafe_attr_outside_unsafe)]` implied by `#[deny(rust_2024_compatibility)]`
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | #[unsafe(no_mangle)]
+   |   +++++++         +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs
new file mode 100644
index 00000000000..279ced2525a
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs
@@ -0,0 +1,12 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+#![feature(unsafe_attributes)]
+
+#[unsafe(no_mangle)]
+extern "C" fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
new file mode 100644
index 00000000000..6ebdff0334c
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
@@ -0,0 +1,61 @@
+//@ run-rustfix
+#![feature(unsafe_attributes)]
+#![deny(unsafe_attr_outside_unsafe)]
+
+macro_rules! tt {
+    ($e:tt) => {
+        #$e
+        extern fn foo() {}
+    }
+}
+
+macro_rules! ident {
+    ($e:ident) => {
+        #[unsafe($e)]
+        //~^ ERROR: unsafe attribute used without unsafe
+        //~| WARN this is accepted in the current edition
+        extern fn bar() {}
+    }
+}
+
+macro_rules! ident2 {
+    ($e:ident, $l:literal) => {
+        #[unsafe($e = $l)]
+        //~^ ERROR: unsafe attribute used without unsafe
+        //~| WARN this is accepted in the current edition
+        extern fn bars() {}
+    }
+}
+
+macro_rules! meta {
+    ($m:meta) => {
+        #[$m]
+        extern fn baz() {}
+    }
+}
+
+macro_rules! meta2 {
+    ($m:meta) => {
+        #[$m]
+        extern fn baw() {}
+    }
+}
+
+tt!([unsafe(no_mangle)]);
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+ident!(no_mangle);
+meta!(unsafe(no_mangle));
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+meta2!(unsafe(export_name = "baw"));
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+ident2!(export_name, "bars");
+
+#[unsafe(no_mangle)]
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+extern "C" fn one() {}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
new file mode 100644
index 00000000000..c78ff45ea4c
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
@@ -0,0 +1,61 @@
+//@ run-rustfix
+#![feature(unsafe_attributes)]
+#![deny(unsafe_attr_outside_unsafe)]
+
+macro_rules! tt {
+    ($e:tt) => {
+        #$e
+        extern fn foo() {}
+    }
+}
+
+macro_rules! ident {
+    ($e:ident) => {
+        #[$e]
+        //~^ ERROR: unsafe attribute used without unsafe
+        //~| WARN this is accepted in the current edition
+        extern fn bar() {}
+    }
+}
+
+macro_rules! ident2 {
+    ($e:ident, $l:literal) => {
+        #[$e = $l]
+        //~^ ERROR: unsafe attribute used without unsafe
+        //~| WARN this is accepted in the current edition
+        extern fn bars() {}
+    }
+}
+
+macro_rules! meta {
+    ($m:meta) => {
+        #[$m]
+        extern fn baz() {}
+    }
+}
+
+macro_rules! meta2 {
+    ($m:meta) => {
+        #[$m]
+        extern fn baw() {}
+    }
+}
+
+tt!([no_mangle]);
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+ident!(no_mangle);
+meta!(no_mangle);
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+meta2!(export_name = "baw");
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+ident2!(export_name, "bars");
+
+#[no_mangle]
+//~^ ERROR: unsafe attribute used without unsafe
+//~| WARN this is accepted in the current edition
+extern "C" fn one() {}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
new file mode 100644
index 00000000000..c95984f58ec
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
@@ -0,0 +1,93 @@
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:44:6
+   |
+LL | tt!([no_mangle]);
+   |      ^^^^^^^^^ usage of unsafe attribute
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+note: the lint level is defined here
+  --> $DIR/unsafe-attributes-fix.rs:3:9
+   |
+LL | #![deny(unsafe_attr_outside_unsafe)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | tt!([unsafe(no_mangle)]);
+   |      +++++++         +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:14:11
+   |
+LL |         #[$e]
+   |           ^^ usage of unsafe attribute
+...
+LL | ident!(no_mangle);
+   | ----------------- in this macro invocation
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+   = note: this error originates in the macro `ident` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: wrap the attribute in `unsafe(...)`
+   |
+LL |         #[unsafe($e)]
+   |           +++++++  +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:48:7
+   |
+LL | meta!(no_mangle);
+   |       ^^^^^^^^^ usage of unsafe attribute
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | meta!(unsafe(no_mangle));
+   |       +++++++         +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:51:8
+   |
+LL | meta2!(export_name = "baw");
+   |        ^^^^^^^^^^^ usage of unsafe attribute
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | meta2!(unsafe(export_name = "baw"));
+   |        +++++++                   +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:23:11
+   |
+LL |         #[$e = $l]
+   |           ^^ usage of unsafe attribute
+...
+LL | ident2!(export_name, "bars");
+   | ---------------------------- in this macro invocation
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+   = note: this error originates in the macro `ident2` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: wrap the attribute in `unsafe(...)`
+   |
+LL |         #[unsafe($e = $l)]
+   |           +++++++       +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes-fix.rs:56:3
+   |
+LL | #[no_mangle]
+   |   ^^^^^^^^^ usage of unsafe attribute
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | #[unsafe(no_mangle)]
+   |   +++++++         +
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr
new file mode 100644
index 00000000000..35475d66716
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr
@@ -0,0 +1,13 @@
+error: unsafe attribute used without unsafe
+  --> $DIR/unsafe-attributes.rs:9:3
+   |
+LL | #[no_mangle]
+   |   ^^^^^^^^^ usage of unsafe attribute
+   |
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | #[unsafe(no_mangle)]
+   |   +++++++         +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs
new file mode 100644
index 00000000000..3a6af9dfb2b
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs
@@ -0,0 +1,12 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2021] check-pass
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+
+#![feature(unsafe_attributes)]
+
+#[no_mangle] //[edition2024]~ ERROR: unsafe attribute used without unsafe
+extern "C" fn foo() {}
+
+fn main() {}