about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-09-27 22:30:56 +0000
committerbors <bors@rust-lang.org>2025-09-27 22:30:56 +0000
commit848e6746fe03dfd703075c5077312b63877d51d6 (patch)
treeeba347843510a17e763b7a896a3955759784b546
parent4082d6a3f0347c2fc4b8c8d5a6a38ed7248fa161 (diff)
parentbd2e18671d4eb0c2cf33965748c270a8ec358557 (diff)
downloadrust-848e6746fe03dfd703075c5077312b63877d51d6.tar.gz
rust-848e6746fe03dfd703075c5077312b63877d51d6.zip
Auto merge of #147104 - matthiaskrgr:rollup-gap1v0w, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#146037 (Introduce CoerceShared lang item and trait, and basic Reborrow tests)
 - rust-lang/rust#146732 (tests: relax expectations after llvm change 902ddda120a5)
 - rust-lang/rust#147018 (re-order normalizations in run-make linker-warning test)
 - rust-lang/rust#147032 (Fix doctest compilation time display)
 - rust-lang/rust#147046 (Rename `rust.use-lld` to `rust.bootstrap-override-lld`)
 - rust-lang/rust#147050 (PassWrapper: update for new PGOOptions args in LLVM 22)
 - rust-lang/rust#147075 (Make `def_path_hash_to_def_id` not panic when passed an invalid hash)
 - rust-lang/rust#147076 (update issue number for more_float_constants)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--bootstrap.example.toml7
-rw-r--r--compiler/rustc_hir/src/lang_items.rs1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp18
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs9
-rw-r--r--compiler/rustc_middle/src/hooks/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/marker.rs8
-rw-r--r--library/core/src/num/f128.rs12
-rw-r--r--library/core/src/num/f16.rs12
-rw-r--r--library/core/src/num/f32.rs12
-rw-r--r--library/core/src/num/f64.rs12
-rw-r--r--library/core/src/ops/mod.rs3
-rw-r--r--library/core/src/ops/reborrow.rs16
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs4
-rw-r--r--src/bootstrap/src/core/config/config.rs20
-rw-r--r--src/bootstrap/src/core/config/mod.rs2
-rw-r--r--src/bootstrap/src/core/config/tests.rs36
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs49
-rw-r--r--src/bootstrap/src/lib.rs12
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/helpers.rs28
-rw-r--r--src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile2
-rw-r--r--src/librustdoc/doctest.rs10
-rw-r--r--tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs7
-rw-r--r--tests/codegen-llvm/vec_pop_push_noop.rs5
-rw-r--r--tests/codegen-llvm/vecdeque_pop_push.rs5
-rw-r--r--tests/run-make/doctests-compilation-time-info/rmake.rs119
-rw-r--r--tests/run-make/doctests-merge/doctest-2024.stdout1
-rw-r--r--tests/run-make/doctests-merge/rmake.rs2
-rw-r--r--tests/run-make/linker-warning/rmake.rs2
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout6
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout7
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.rs2
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.rs2
-rw-r--r--tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout5
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-reborrow.stderr4
-rw-r--r--tests/ui/reborrow/custom_mut.rs13
-rw-r--r--tests/ui/reborrow/custom_mut.stderr29
-rw-r--r--tests/ui/reborrow/custom_mut_coerce_shared.rs28
-rw-r--r--tests/ui/reborrow/custom_mut_coerce_shared.stderr19
-rw-r--r--tests/ui/reborrow/option_mut.rs7
-rw-r--r--tests/ui/reborrow/option_mut.stderr21
-rw-r--r--tests/ui/reborrow/option_mut_coerce_shared.rs11
-rw-r--r--tests/ui/reborrow/option_mut_coerce_shared.stderr23
-rw-r--r--tests/ui/reborrow/pin_mut.rs10
-rw-r--r--tests/ui/reborrow/pin_mut.stderr21
-rw-r--r--tests/ui/reborrow/pin_mut_coerce_shared.rs13
-rw-r--r--tests/ui/reborrow/pin_mut_coerce_shared.stderr19
55 files changed, 576 insertions, 114 deletions
diff --git a/bootstrap.example.toml b/bootstrap.example.toml
index 0cd571134ef..0a39c6d8f24 100644
--- a/bootstrap.example.toml
+++ b/bootstrap.example.toml
@@ -768,8 +768,7 @@
 # make this default to false.
 #rust.lld = false in all cases, except on `x86_64-unknown-linux-gnu` as described above, where it is true
 
-# Indicates whether LLD will be used to link Rust crates during bootstrap on
-# supported platforms.
+# Indicates if we should override the linker used to link Rust crates during bootstrap to be LLD.
 # If set to `true` or `"external"`, a global `lld` binary that has to be in $PATH
 # will be used.
 # If set to `"self-contained"`, rust-lld from the snapshot compiler will be used.
@@ -777,7 +776,7 @@
 # On MSVC, LLD will not be used if we're cross linking.
 #
 # Explicitly setting the linker for a target will override this option when targeting MSVC.
-#rust.use-lld = false
+#rust.bootstrap-override-lld = false
 
 # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
 # sysroot.
@@ -950,7 +949,7 @@
 # Linker to be used to bootstrap Rust code. Note that the
 # default value is platform specific, and if not specified it may also depend on
 # what platform is crossing to what platform.
-# Setting this will override the `use-lld` option for Rust code when targeting MSVC.
+# Setting this will override the `bootstrap-override-lld` option for Rust code when targeting MSVC.
 #linker = "cc" (path)
 
 # Should rustc and the standard library be built with split debuginfo? Default
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 2e099a97b65..311cf8f995c 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -440,6 +440,7 @@ language_item_table! {
 
     // Reborrowing related lang-items
     Reborrow,                sym::reborrow,            reborrow,                   Target::Trait,          GenericRequirement::Exact(0);
+    CoerceShared,            sym::coerce_shared,       coerce_shared,              Target::Trait,          GenericRequirement::Exact(0);
 }
 
 /// The requirement imposed on the generics of a lang item
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 013d68fa3e4..2e9fd6754f1 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -569,25 +569,43 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   }
 
   std::optional<PGOOptions> PGOOpt;
+#if LLVM_VERSION_LT(22, 0)
   auto FS = vfs::getRealFileSystem();
+#endif
   if (PGOGenPath) {
     assert(!PGOUsePath && !PGOSampleUsePath);
     PGOOpt = PGOOptions(
+#if LLVM_VERSION_GE(22, 0)
+        PGOGenPath, "", "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
+#else
         PGOGenPath, "", "", "", FS, PGOOptions::IRInstr, PGOOptions::NoCSAction,
+#endif
         PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   } else if (PGOUsePath) {
     assert(!PGOSampleUsePath);
     PGOOpt = PGOOptions(
+#if LLVM_VERSION_GE(22, 0)
+        PGOUsePath, "", "", "", PGOOptions::IRUse, PGOOptions::NoCSAction,
+#else
         PGOUsePath, "", "", "", FS, PGOOptions::IRUse, PGOOptions::NoCSAction,
+#endif
         PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   } else if (PGOSampleUsePath) {
     PGOOpt =
+#if LLVM_VERSION_GE(22, 0)
+        PGOOptions(PGOSampleUsePath, "", "", "", PGOOptions::SampleUse,
+#else
         PGOOptions(PGOSampleUsePath, "", "", "", FS, PGOOptions::SampleUse,
+#endif
                    PGOOptions::NoCSAction, PGOOptions::ColdFuncOpt::Default,
                    DebugInfoForProfiling);
   } else if (DebugInfoForProfiling) {
     PGOOpt = PGOOptions(
+#if LLVM_VERSION_GE(22, 0)
+        "", "", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
+#else
         "", "", "", "", FS, PGOOptions::NoAction, PGOOptions::NoCSAction,
+#endif
         PGOOptions::ColdFuncOpt::Default, DebugInfoForProfiling);
   }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 0c8d1f32e99..b895feb9062 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1555,7 +1555,7 @@ impl<'a> CrateMetadataRef<'a> {
     }
 
     #[inline]
-    fn def_path_hash_to_def_index(self, hash: DefPathHash) -> DefIndex {
+    fn def_path_hash_to_def_index(self, hash: DefPathHash) -> Option<DefIndex> {
         self.def_path_hash_map.def_path_hash_to_def_index(&hash)
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 11fef3be5d0..df3add316ec 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -691,8 +691,8 @@ fn provide_cstore_hooks(providers: &mut Providers) {
             .get(&stable_crate_id)
             .unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"));
         assert_ne!(cnum, LOCAL_CRATE);
-        let def_index = cstore.get_crate_data(cnum).def_path_hash_to_def_index(hash);
-        DefId { krate: cnum, index: def_index }
+        let def_index = cstore.get_crate_data(cnum).def_path_hash_to_def_index(hash)?;
+        Some(DefId { krate: cnum, index: def_index })
     };
 
     providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| {
diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
index f3917b55782..a17b3e1047d 100644
--- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
+++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
@@ -12,11 +12,12 @@ pub(crate) enum DefPathHashMapRef<'tcx> {
 
 impl DefPathHashMapRef<'_> {
     #[inline]
-    pub(crate) fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
+    pub(crate) fn def_path_hash_to_def_index(
+        &self,
+        def_path_hash: &DefPathHash,
+    ) -> Option<DefIndex> {
         match *self {
-            DefPathHashMapRef::OwnedFromMetadata(ref map) => {
-                map.get(&def_path_hash.local_hash()).unwrap()
-            }
+            DefPathHashMapRef::OwnedFromMetadata(ref map) => map.get(&def_path_hash.local_hash()),
             DefPathHashMapRef::BorrowedFromTcx(_) => {
                 panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization")
             }
diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs
index 9d2f0a45237..dc6a3334a4c 100644
--- a/compiler/rustc_middle/src/hooks/mod.rs
+++ b/compiler/rustc_middle/src/hooks/mod.rs
@@ -77,7 +77,7 @@ declare_hooks! {
     /// session, if it still exists. This is used during incremental compilation to
     /// turn a deserialized `DefPathHash` into its current `DefId`.
     /// Will fetch a DefId from a DefPathHash for a foreign crate.
-    hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId;
+    hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> Option<DefId>;
 
     /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
     /// can just link to the upstream crate and therefore don't need a mono item.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index a42af7bb3e3..fe3fa024cd5 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2012,7 +2012,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
             Some(self.untracked.definitions.read().local_def_path_hash_to_def_id(hash)?.to_def_id())
         } else {
-            Some(self.def_path_hash_to_def_id_extern(hash, stable_crate_id))
+            self.def_path_hash_to_def_id_extern(hash, stable_crate_id)
         }
     }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index cd422da0c1c..63b0de377c9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -679,6 +679,7 @@ symbols! {
         cmpxchg16b_target_feature,
         cmse_nonsecure_entry,
         coerce_pointee_validated,
+        coerce_shared,
         coerce_unsized,
         cold,
         cold_path,
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1c100312a9a..4b767d8d622 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1341,11 +1341,3 @@ pub macro CoercePointee($item:item) {
 pub trait CoercePointeeValidated {
     /* compiler built-in */
 }
-
-/// Allows value to be reborrowed as exclusive, creating a copy of the value
-/// that disables the source for reads and writes for the lifetime of the copy.
-#[lang = "reborrow"]
-#[unstable(feature = "reborrow", issue = "145612")]
-pub trait Reborrow {
-    // Empty.
-}
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 73ca3fbb142..4fe4735e304 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -33,12 +33,12 @@ pub mod consts {
 
     /// The golden ratio (φ)
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const PHI: f128 = 1.61803398874989484820458683436563811772030917980576286213545_f128;
 
     /// The Euler-Mascheroni constant (γ)
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const EGAMMA: f128 = 0.577215664901532860606512090082402431042159335939923598805767_f128;
 
     /// π/2
@@ -67,14 +67,14 @@ pub mod consts {
 
     /// 1/sqrt(π)
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_PI: f128 =
         0.564189583547756286948079451560772585844050629328998856844086_f128;
 
     /// 1/sqrt(2π)
     #[doc(alias = "FRAC_1_SQRT_TAU")]
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_2PI: f128 =
         0.398942280401432677939946059934381868475858631164934657665926_f128;
 
@@ -98,12 +98,12 @@ pub mod consts {
 
     /// sqrt(3)
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const SQRT_3: f128 = 1.73205080756887729352744634150587236694280525381038062805581_f128;
 
     /// 1/sqrt(3)
     #[unstable(feature = "f128", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_3: f128 =
         0.577350269189625764509148780501957455647601751270126876018602_f128;
 
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index a9dbade0e65..0bea6bc8801 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -35,12 +35,12 @@ pub mod consts {
 
     /// The golden ratio (φ)
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const PHI: f16 = 1.618033988749894848204586834365638118_f16;
 
     /// The Euler-Mascheroni constant (γ)
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const EGAMMA: f16 = 0.577215664901532860606512090082402431_f16;
 
     /// π/2
@@ -69,13 +69,13 @@ pub mod consts {
 
     /// 1/sqrt(π)
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_PI: f16 = 0.564189583547756286948079451560772586_f16;
 
     /// 1/sqrt(2π)
     #[doc(alias = "FRAC_1_SQRT_TAU")]
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_2PI: f16 = 0.398942280401432677939946059934381868_f16;
 
     /// 2/π
@@ -96,12 +96,12 @@ pub mod consts {
 
     /// sqrt(3)
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const SQRT_3: f16 = 1.732050807568877293527446341505872367_f16;
 
     /// 1/sqrt(3)
     #[unstable(feature = "f16", issue = "116909")]
-    // Also, #[unstable(feature = "more_float_constants", issue = "103883")]
+    // Also, #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_3: f16 = 0.577350269189625764509148780501957456_f16;
 
     /// Euler's number (e)
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 53474cd3e90..e380cc698f5 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -291,11 +291,11 @@ pub mod consts {
     pub const TAU: f32 = 6.28318530717958647692528676655900577_f32;
 
     /// The golden ratio (φ)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const PHI: f32 = 1.618033988749894848204586834365638118_f32;
 
     /// The Euler-Mascheroni constant (γ)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const EGAMMA: f32 = 0.577215664901532860606512090082402431_f32;
 
     /// π/2
@@ -323,12 +323,12 @@ pub mod consts {
     pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
 
     /// 1/sqrt(π)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32;
 
     /// 1/sqrt(2π)
     #[doc(alias = "FRAC_1_SQRT_TAU")]
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_2PI: f32 = 0.398942280401432677939946059934381868_f32;
 
     /// 2/π
@@ -348,11 +348,11 @@ pub mod consts {
     pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
 
     /// sqrt(3)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const SQRT_3: f32 = 1.732050807568877293527446341505872367_f32;
 
     /// 1/sqrt(3)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_3: f32 = 0.577350269189625764509148780501957456_f32;
 
     /// Euler's number (e)
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 78113a60bbc..ff7449fd996 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -291,11 +291,11 @@ pub mod consts {
     pub const TAU: f64 = 6.28318530717958647692528676655900577_f64;
 
     /// The golden ratio (φ)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const PHI: f64 = 1.618033988749894848204586834365638118_f64;
 
     /// The Euler-Mascheroni constant (γ)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const EGAMMA: f64 = 0.577215664901532860606512090082402431_f64;
 
     /// π/2
@@ -323,12 +323,12 @@ pub mod consts {
     pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
 
     /// 1/sqrt(π)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_PI: f64 = 0.564189583547756286948079451560772586_f64;
 
     /// 1/sqrt(2π)
     #[doc(alias = "FRAC_1_SQRT_TAU")]
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_2PI: f64 = 0.398942280401432677939946059934381868_f64;
 
     /// 2/π
@@ -348,11 +348,11 @@ pub mod consts {
     pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64;
 
     /// sqrt(3)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const SQRT_3: f64 = 1.732050807568877293527446341505872367_f64;
 
     /// 1/sqrt(3)
-    #[unstable(feature = "more_float_constants", issue = "103883")]
+    #[unstable(feature = "more_float_constants", issue = "146939")]
     pub const FRAC_1_SQRT_3: f64 = 0.577350269189625764509148780501957456_f64;
 
     /// Euler's number (e)
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index 87dd873fdb5..ab1ad407ee2 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -149,6 +149,7 @@ mod function;
 mod index;
 mod index_range;
 mod range;
+mod reborrow;
 mod try_trait;
 mod unsize;
 
@@ -189,6 +190,8 @@ pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
 pub use self::range::{OneSidedRange, OneSidedRangeBound};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
+#[unstable(feature = "reborrow", issue = "145612")]
+pub use self::reborrow::{CoerceShared, Reborrow};
 #[unstable(feature = "try_trait_v2_residual", issue = "91285")]
 pub use self::try_trait::Residual;
 #[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
diff --git a/library/core/src/ops/reborrow.rs b/library/core/src/ops/reborrow.rs
new file mode 100644
index 00000000000..f83f4233a4d
--- /dev/null
+++ b/library/core/src/ops/reborrow.rs
@@ -0,0 +1,16 @@
+/// Allows value to be reborrowed as exclusive, creating a copy of the value
+/// that disables the source for reads and writes for the lifetime of the copy.
+#[lang = "reborrow"]
+#[unstable(feature = "reborrow", issue = "145612")]
+pub trait Reborrow {
+    // Empty.
+}
+
+/// Allows reborrowable value to be reborrowed as shared, creating a copy
+/// that disables the source for writes for the lifetime of the copy.
+#[lang = "coerce_shared"]
+#[unstable(feature = "reborrow", issue = "145612")]
+pub trait CoerceShared: Reborrow {
+    /// The type of this value when reborrowed as shared.
+    type Target: Copy;
+}
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 884b5750974..96b4e15433f 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1221,7 +1221,7 @@ pub fn rustc_cargo(
     // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
     // with direct references to protected symbols, so for now we only use protected symbols if
     // linking with LLD is enabled.
-    if builder.build.config.lld_mode.is_used() {
+    if builder.build.config.bootstrap_override_lld.is_used() {
         cargo.rustflag("-Zdefault-visibility=protected");
     }
 
@@ -1258,7 +1258,7 @@ pub fn rustc_cargo(
     // is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
     // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
     // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
-    if builder.config.lld_mode.is_used() && !build_compiler.host.is_msvc() {
+    if builder.config.bootstrap_override_lld.is_used() && !build_compiler.host.is_msvc() {
         cargo.rustflag("-Clink-args=-Wl,--icf=all");
     }
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 6d9e3b54156..271ce4cb950 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -41,7 +41,7 @@ use crate::core::config::toml::gcc::Gcc;
 use crate::core::config::toml::install::Install;
 use crate::core::config::toml::llvm::Llvm;
 use crate::core::config::toml::rust::{
-    LldMode, Rust, RustOptimize, check_incompatible_options_for_ci_rustc,
+    BootstrapOverrideLld, Rust, RustOptimize, check_incompatible_options_for_ci_rustc,
     default_lld_opt_in_targets, parse_codegen_backends,
 };
 use crate::core::config::toml::target::Target;
@@ -174,7 +174,7 @@ pub struct Config {
     pub llvm_from_ci: bool,
     pub llvm_build_config: HashMap<String, String>,
 
-    pub lld_mode: LldMode,
+    pub bootstrap_override_lld: BootstrapOverrideLld,
     pub lld_enabled: bool,
     pub llvm_tools_enabled: bool,
     pub llvm_bitcode_linker_enabled: bool,
@@ -567,7 +567,8 @@ impl Config {
             frame_pointers: rust_frame_pointers,
             stack_protector: rust_stack_protector,
             strip: rust_strip,
-            lld_mode: rust_lld_mode,
+            bootstrap_override_lld: rust_bootstrap_override_lld,
+            bootstrap_override_lld_legacy: rust_bootstrap_override_lld_legacy,
             std_features: rust_std_features,
             break_on_ice: rust_break_on_ice,
         } = toml.rust.unwrap_or_default();
@@ -615,6 +616,15 @@ impl Config {
 
         let Gcc { download_ci_gcc: gcc_download_ci_gcc } = toml.gcc.unwrap_or_default();
 
+        if rust_bootstrap_override_lld.is_some() && rust_bootstrap_override_lld_legacy.is_some() {
+            panic!(
+                "Cannot use both `rust.use-lld` and `rust.bootstrap-override-lld`. Please use only `rust.bootstrap-override-lld`"
+            );
+        }
+
+        let bootstrap_override_lld =
+            rust_bootstrap_override_lld.or(rust_bootstrap_override_lld_legacy).unwrap_or_default();
+
         if rust_optimize.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) {
             eprintln!(
                 "WARNING: setting `optimize` to `false` is known to cause errors and \
@@ -960,7 +970,7 @@ impl Config {
 
         let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx, &out));
 
-        if matches!(rust_lld_mode.unwrap_or_default(), LldMode::SelfContained)
+        if matches!(bootstrap_override_lld, BootstrapOverrideLld::SelfContained)
             && !lld_enabled
             && flags_stage.unwrap_or(0) > 0
         {
@@ -1172,6 +1182,7 @@ impl Config {
             backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false),
             bindir: install_bindir.map(PathBuf::from).unwrap_or("bin".into()),
             bootstrap_cache_path: build_bootstrap_cache_path,
+            bootstrap_override_lld,
             bypass_bootstrap_lock: flags_bypass_bootstrap_lock,
             cargo_info,
             cargo_native_static: build_cargo_native_static.unwrap_or(false),
@@ -1238,7 +1249,6 @@ impl Config {
             libdir: install_libdir.map(PathBuf::from),
             library_docs_private_items: build_library_docs_private_items.unwrap_or(false),
             lld_enabled,
-            lld_mode: rust_lld_mode.unwrap_or_default(),
             lldb: build_lldb.map(PathBuf::from),
             llvm_allow_old_toolchain: llvm_allow_old_toolchain.unwrap_or(false),
             llvm_assertions,
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 05a5dfc0bc5..56b87823a36 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -37,7 +37,7 @@ use serde_derive::Deserialize;
 pub use target_selection::TargetSelection;
 pub use toml::BUILDER_CONFIG_FILENAME;
 pub use toml::change_id::ChangeId;
-pub use toml::rust::LldMode;
+pub use toml::rust::BootstrapOverrideLld;
 pub use toml::target::Target;
 
 use crate::Display;
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 4f2df76a156..e19604d4ab1 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -17,7 +17,9 @@ use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
 use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS;
 use crate::core::build_steps::{llvm, test};
 use crate::core::config::toml::TomlConfig;
-use crate::core::config::{CompilerBuiltins, LldMode, StringOrBool, Target, TargetSelection};
+use crate::core::config::{
+    BootstrapOverrideLld, CompilerBuiltins, StringOrBool, Target, TargetSelection,
+};
 use crate::utils::tests::TestCtx;
 use crate::utils::tests::git::git_test;
 
@@ -222,11 +224,33 @@ fn verify_file_integrity() {
 
 #[test]
 fn rust_lld() {
-    assert!(matches!(parse("").lld_mode, LldMode::Unused));
-    assert!(matches!(parse("rust.use-lld = \"self-contained\"").lld_mode, LldMode::SelfContained));
-    assert!(matches!(parse("rust.use-lld = \"external\"").lld_mode, LldMode::External));
-    assert!(matches!(parse("rust.use-lld = true").lld_mode, LldMode::External));
-    assert!(matches!(parse("rust.use-lld = false").lld_mode, LldMode::Unused));
+    assert!(matches!(parse("").bootstrap_override_lld, BootstrapOverrideLld::None));
+    assert!(matches!(
+        parse("rust.bootstrap-override-lld = \"self-contained\"").bootstrap_override_lld,
+        BootstrapOverrideLld::SelfContained
+    ));
+    assert!(matches!(
+        parse("rust.bootstrap-override-lld = \"external\"").bootstrap_override_lld,
+        BootstrapOverrideLld::External
+    ));
+    assert!(matches!(
+        parse("rust.bootstrap-override-lld = true").bootstrap_override_lld,
+        BootstrapOverrideLld::External
+    ));
+    assert!(matches!(
+        parse("rust.bootstrap-override-lld = false").bootstrap_override_lld,
+        BootstrapOverrideLld::None
+    ));
+
+    // Also check the legacy options
+    assert!(matches!(
+        parse("rust.use-lld = true").bootstrap_override_lld,
+        BootstrapOverrideLld::External
+    ));
+    assert!(matches!(
+        parse("rust.use-lld = false").bootstrap_override_lld,
+        BootstrapOverrideLld::None
+    ));
 }
 
 #[test]
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index e5987d7040a..ca9e0d0bc98 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -45,7 +45,9 @@ define_config! {
         codegen_backends: Option<Vec<String>> = "codegen-backends",
         llvm_bitcode_linker: Option<bool> = "llvm-bitcode-linker",
         lld: Option<bool> = "lld",
-        lld_mode: Option<LldMode> = "use-lld",
+        bootstrap_override_lld: Option<BootstrapOverrideLld> = "bootstrap-override-lld",
+        // FIXME: Remove this option in Spring 2026
+        bootstrap_override_lld_legacy: Option<BootstrapOverrideLld> = "use-lld",
         llvm_tools: Option<bool> = "llvm-tools",
         deny_warnings: Option<bool> = "deny-warnings",
         backtrace_on_ice: Option<bool> = "backtrace-on-ice",
@@ -70,22 +72,33 @@ define_config! {
     }
 }
 
-/// LLD in bootstrap works like this:
-/// - Self-contained lld: use `rust-lld` from the compiler's sysroot
+/// Determines if we should override the linker used for linking Rust code built
+/// during the bootstrapping process to be LLD.
+///
+/// The primary use-case for this is to make local (re)builds of Rust code faster
+/// when using bootstrap.
+///
+/// This does not affect the *behavior* of the built/distributed compiler when invoked
+/// outside of bootstrap.
+/// It might affect its performance/binary size though, as that can depend on the
+/// linker that links rustc.
+///
+/// There are two ways of overriding the linker to be LLD:
+/// - Self-contained LLD: use `rust-lld` from the compiler's sysroot
 /// - External: use an external `lld` binary
 ///
 /// It is configured depending on the target:
 /// 1) Everything except MSVC
-/// - Self-contained: `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker`
-/// - External: `-Clinker-flavor=gnu-lld-cc`
+/// - Self-contained: `-Clinker-features=+lld -Clink-self-contained=+linker`
+/// - External: `-Clinker-features=+lld`
 /// 2) MSVC
 /// - Self-contained: `-Clinker=<path to rust-lld>`
 /// - External: `-Clinker=lld`
 #[derive(Copy, Clone, Default, Debug, PartialEq)]
-pub enum LldMode {
-    /// Do not use LLD
+pub enum BootstrapOverrideLld {
+    /// Do not override the linker LLD
     #[default]
-    Unused,
+    None,
     /// Use `rust-lld` from the compiler's sysroot
     SelfContained,
     /// Use an externally provided `lld` binary.
@@ -94,16 +107,16 @@ pub enum LldMode {
     External,
 }
 
-impl LldMode {
+impl BootstrapOverrideLld {
     pub fn is_used(&self) -> bool {
         match self {
-            LldMode::SelfContained | LldMode::External => true,
-            LldMode::Unused => false,
+            BootstrapOverrideLld::SelfContained | BootstrapOverrideLld::External => true,
+            BootstrapOverrideLld::None => false,
         }
     }
 }
 
-impl<'de> Deserialize<'de> for LldMode {
+impl<'de> Deserialize<'de> for BootstrapOverrideLld {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
     where
         D: Deserializer<'de>,
@@ -111,7 +124,7 @@ impl<'de> Deserialize<'de> for LldMode {
         struct LldModeVisitor;
 
         impl serde::de::Visitor<'_> for LldModeVisitor {
-            type Value = LldMode;
+            type Value = BootstrapOverrideLld;
 
             fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                 formatter.write_str("one of true, 'self-contained' or 'external'")
@@ -121,7 +134,7 @@ impl<'de> Deserialize<'de> for LldMode {
             where
                 E: serde::de::Error,
             {
-                Ok(if v { LldMode::External } else { LldMode::Unused })
+                Ok(if v { BootstrapOverrideLld::External } else { BootstrapOverrideLld::None })
             }
 
             fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
@@ -129,8 +142,8 @@ impl<'de> Deserialize<'de> for LldMode {
                 E: serde::de::Error,
             {
                 match v {
-                    "external" => Ok(LldMode::External),
-                    "self-contained" => Ok(LldMode::SelfContained),
+                    "external" => Ok(BootstrapOverrideLld::External),
+                    "self-contained" => Ok(BootstrapOverrideLld::SelfContained),
                     _ => Err(E::custom(format!("unknown mode {v}"))),
                 }
             }
@@ -311,7 +324,6 @@ pub fn check_incompatible_options_for_ci_rustc(
         lto,
         stack_protector,
         strip,
-        lld_mode,
         jemalloc,
         rpath,
         channel,
@@ -359,6 +371,8 @@ pub fn check_incompatible_options_for_ci_rustc(
         frame_pointers: _,
         break_on_ice: _,
         parallel_frontend_threads: _,
+        bootstrap_override_lld: _,
+        bootstrap_override_lld_legacy: _,
     } = ci_rust_config;
 
     // There are two kinds of checks for CI rustc incompatible options:
@@ -374,7 +388,6 @@ pub fn check_incompatible_options_for_ci_rustc(
     err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc, "rust");
     err!(current_rust_config.rpath, rpath, "rust");
     err!(current_rust_config.strip, strip, "rust");
-    err!(current_rust_config.lld_mode, lld_mode, "rust");
     err!(current_rust_config.llvm_tools, llvm_tools, "rust");
     err!(current_rust_config.llvm_bitcode_linker, llvm_bitcode_linker, "rust");
     err!(current_rust_config.jemalloc, jemalloc, "rust");
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 4f4d35673d5..d798639cc96 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -35,7 +35,7 @@ use utils::exec::ExecutionContext;
 
 use crate::core::builder;
 use crate::core::builder::Kind;
-use crate::core::config::{DryRun, LldMode, LlvmLibunwind, TargetSelection, flags};
+use crate::core::config::{BootstrapOverrideLld, DryRun, LlvmLibunwind, TargetSelection, flags};
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{self, dir_is_empty, exe, libdir, set_file_times, split_debuginfo};
 
@@ -1358,14 +1358,14 @@ impl Build {
             && !target.is_msvc()
         {
             Some(self.cc(target))
-        } else if self.config.lld_mode.is_used()
+        } else if self.config.bootstrap_override_lld.is_used()
             && self.is_lld_direct_linker(target)
             && self.host_target == target
         {
-            match self.config.lld_mode {
-                LldMode::SelfContained => Some(self.initial_lld.clone()),
-                LldMode::External => Some("lld".into()),
-                LldMode::Unused => None,
+            match self.config.bootstrap_override_lld {
+                BootstrapOverrideLld::SelfContained => Some(self.initial_lld.clone()),
+                BootstrapOverrideLld::External => Some("lld".into()),
+                BootstrapOverrideLld::None => None,
             }
         } else {
             None
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 6b187578c31..f311c84bec9 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -556,4 +556,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "New option `build.windows-rc` that will override which resource compiler on Windows will be used to compile Rust.",
     },
+    ChangeInfo {
+        change_id: 99999,
+        severity: ChangeSeverity::Warning,
+        summary: "The `rust.use-lld` option has been renamed to `rust.bootstrap-override-lld`. Note that it only serves for overriding the linker used when building Rust code in bootstrap to be LLD.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index e802c0214dd..faada9a111d 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -12,7 +12,7 @@ use std::{env, fs, io, panic, str};
 
 use object::read::archive::ArchiveFile;
 
-use crate::LldMode;
+use crate::BootstrapOverrideLld;
 use crate::core::builder::Builder;
 use crate::core::config::{Config, TargetSelection};
 use crate::utils::exec::{BootstrapCommand, command};
@@ -357,15 +357,19 @@ pub fn get_clang_cl_resource_dir(builder: &Builder<'_>, clang_cl_path: &str) ->
 /// Returns a flag that configures LLD to use only a single thread.
 /// If we use an external LLD, we need to find out which version is it to know which flag should we
 /// pass to it (LLD older than version 10 had a different flag).
-fn lld_flag_no_threads(builder: &Builder<'_>, lld_mode: LldMode, is_windows: bool) -> &'static str {
+fn lld_flag_no_threads(
+    builder: &Builder<'_>,
+    bootstrap_override_lld: BootstrapOverrideLld,
+    is_windows: bool,
+) -> &'static str {
     static LLD_NO_THREADS: OnceLock<(&'static str, &'static str)> = OnceLock::new();
 
     let new_flags = ("/threads:1", "--threads=1");
     let old_flags = ("/no-threads", "--no-threads");
 
     let (windows_flag, other_flag) = LLD_NO_THREADS.get_or_init(|| {
-        let newer_version = match lld_mode {
-            LldMode::External => {
+        let newer_version = match bootstrap_override_lld {
+            BootstrapOverrideLld::External => {
                 let mut cmd = command("lld");
                 cmd.arg("-flavor").arg("ld").arg("--version");
                 let out = cmd.run_capture_stdout(builder).stdout();
@@ -422,24 +426,28 @@ pub fn linker_flags(
     lld_threads: LldThreads,
 ) -> Vec<String> {
     let mut args = vec![];
-    if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() {
-        match builder.config.lld_mode {
-            LldMode::External => {
+    if !builder.is_lld_direct_linker(target) && builder.config.bootstrap_override_lld.is_used() {
+        match builder.config.bootstrap_override_lld {
+            BootstrapOverrideLld::External => {
                 args.push("-Clinker-features=+lld".to_string());
                 args.push("-Zunstable-options".to_string());
             }
-            LldMode::SelfContained => {
+            BootstrapOverrideLld::SelfContained => {
                 args.push("-Clinker-features=+lld".to_string());
                 args.push("-Clink-self-contained=+linker".to_string());
                 args.push("-Zunstable-options".to_string());
             }
-            LldMode::Unused => unreachable!(),
+            BootstrapOverrideLld::None => unreachable!(),
         };
 
         if matches!(lld_threads, LldThreads::No) {
             args.push(format!(
                 "-Clink-arg=-Wl,{}",
-                lld_flag_no_threads(builder, builder.config.lld_mode, target.is_windows())
+                lld_flag_no_threads(
+                    builder,
+                    builder.config.bootstrap_override_lld,
+                    target.is_windows()
+                )
             ));
         }
     }
diff --git a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
index e726329753f..3abca36fe70 100644
--- a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
+++ b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
@@ -91,7 +91,7 @@ ENV RUST_CONFIGURE_ARGS \
       --set llvm.ninja=false \
       --set rust.debug-assertions=false \
       --set rust.jemalloc \
-      --set rust.use-lld=true \
+      --set rust.bootstrap-override-lld=true \
       --set rust.lto=thin \
       --set rust.codegen-units=1
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 01f19eac1d2..cb574787619 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -92,7 +92,7 @@ ENV RUST_CONFIGURE_ARGS \
       --set llvm.ninja=false \
       --set llvm.libzstd=true \
       --set rust.jemalloc \
-      --set rust.use-lld=true \
+      --set rust.bootstrap-override-lld=true \
       --set rust.lto=thin \
       --set rust.codegen-units=1
 
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 95bd31729de..9499258f983 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -404,11 +404,15 @@ pub(crate) fn run_tests(
             std::mem::drop(temp_dir.take());
             times.display_times();
         });
+    } else {
+        // If the first condition branch exited successfully, `test_main_with_exit_callback` will
+        // not exit the process. So to prevent displaying the times twice, we put it behind an
+        // `else` condition.
+        times.display_times();
     }
+    // We ensure temp dir destructor is called.
+    std::mem::drop(temp_dir);
     if nb_errors != 0 {
-        // We ensure temp dir destructor is called.
-        std::mem::drop(temp_dir);
-        times.display_times();
         std::process::exit(test::ERROR_EXIT_CODE);
     }
 }
diff --git a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
index 853a1ff36b1..a0b453fac8e 100644
--- a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
+++ b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -22,8 +25,8 @@ pub unsafe fn update(s: *mut State) {
     // CHECK-NOT: memcpy
     // CHECK-NOT: 75{{3|4}}
 
-    // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1
-    // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1
+    // old: %[[TAG:.+]] = load i8, ptr %s, align 1
+    // old-NEXT: trunc nuw i8 %[[TAG]] to i1
 
     // CHECK-NOT: load
     // CHECK-NOT: store
diff --git a/tests/codegen-llvm/vec_pop_push_noop.rs b/tests/codegen-llvm/vec_pop_push_noop.rs
index 3e375219fe0..977c220b3ba 100644
--- a/tests/codegen-llvm/vec_pop_push_noop.rs
+++ b/tests/codegen-llvm/vec_pop_push_noop.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -7,7 +10,7 @@
 pub fn noop(v: &mut Vec<u8>) {
     // CHECK-NOT: grow_one
     // CHECK-NOT: call
-    // CHECK: tail call void @llvm.assume
+    // old: tail call void @llvm.assume
     // CHECK-NOT: grow_one
     // CHECK-NOT: call
     // CHECK: {{ret|[}]}}
diff --git a/tests/codegen-llvm/vecdeque_pop_push.rs b/tests/codegen-llvm/vecdeque_pop_push.rs
index 5afa1b2248b..6f9ad6674d6 100644
--- a/tests/codegen-llvm/vecdeque_pop_push.rs
+++ b/tests/codegen-llvm/vecdeque_pop_push.rs
@@ -1,4 +1,7 @@
 //@ compile-flags: -Copt-level=3
+//@ revisions: new old
+//@ [old] max-llvm-major-version: 21
+//@ [new] min-llvm-version: 22
 
 #![crate_type = "lib"]
 
@@ -8,7 +11,7 @@ use std::collections::VecDeque;
 // CHECK-LABEL: @noop_back(
 pub fn noop_back(v: &mut VecDeque<u8>) {
     // CHECK-NOT: grow
-    // CHECK: tail call void @llvm.assume
+    // old: tail call void @llvm.assume
     // CHECK-NOT: grow
     // CHECK: ret
     if let Some(x) = v.pop_back() {
diff --git a/tests/run-make/doctests-compilation-time-info/rmake.rs b/tests/run-make/doctests-compilation-time-info/rmake.rs
new file mode 100644
index 00000000000..2bcf664923f
--- /dev/null
+++ b/tests/run-make/doctests-compilation-time-info/rmake.rs
@@ -0,0 +1,119 @@
+//@ ignore-cross-compile (needs to run doctests)
+
+use run_make_support::rfs::write;
+use run_make_support::{cwd, rustdoc};
+
+fn assert_presence_of_compilation_time_report(
+    content: &str,
+    success: bool,
+    should_contain_compile_time: bool,
+) {
+    let mut cmd = rustdoc();
+    let file = cwd().join("foo.rs");
+
+    write(&file, content);
+    cmd.input(&file).arg("--test").edition("2024").env("RUST_BACKTRACE", "0");
+    let output = if success { cmd.run() } else { cmd.run_fail() };
+
+    assert_eq!(
+        output
+            .stdout_utf8()
+            .split("all doctests ran in ")
+            .last()
+            .is_some_and(|s| s.contains("; merged doctests compilation took")),
+        should_contain_compile_time,
+    );
+}
+
+fn main() {
+    // Checking with only successful merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```",
+        true,
+        true,
+    );
+    // Checking with only failing merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of successful doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```
+//!
+//! ```compile_fail
+//! let x
+//! ```",
+        true,
+        true,
+    );
+    // Checking with mix of failing doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```
+//!
+//! ```compile_fail
+//! let x
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of failing doctests (v2).
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! let x = 12;
+//! ```
+//!
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        true,
+    );
+    // Checking with mix of failing doctests (v3).
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```
+//! panic!();
+//! ```
+//!
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        true,
+    );
+    // Checking with successful non-merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```compile_fail
+//! let x
+//! ```",
+        true,
+        // If there is no merged doctests, then we should not display compilation time.
+        false,
+    );
+    // Checking with failing non-merged doctests.
+    assert_presence_of_compilation_time_report(
+        "\
+//! ```compile_fail
+//! let x = 12;
+//! ```",
+        false,
+        // If there is no merged doctests, then we should not display compilation time.
+        false,
+    );
+}
diff --git a/tests/run-make/doctests-merge/doctest-2024.stdout b/tests/run-make/doctests-merge/doctest-2024.stdout
index 7da08d68faa..a7e139bbd23 100644
--- a/tests/run-make/doctests-merge/doctest-2024.stdout
+++ b/tests/run-make/doctests-merge/doctest-2024.stdout
@@ -5,3 +5,4 @@ test doctest.rs - init (line 8) ... ok
 
 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs
index 7893d4988eb..f2a1e8e13dd 100644
--- a/tests/run-make/doctests-merge/rmake.rs
+++ b/tests/run-make/doctests-merge/rmake.rs
@@ -20,6 +20,8 @@ fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Pa
         .expected_file(stdout_file)
         .actual_text("output", output.stdout_utf8())
         .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME")
+        .normalize(r#"ran in \d+\.\d+s"#, "ran in $$TIME")
+        .normalize(r#"compilation took \d+\.\d+s"#, "compilation took $$TIME")
         .run();
 }
 
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
index b0c40dd171d..a31b08d6c69 100644
--- a/tests/run-make/linker-warning/rmake.rs
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -61,13 +61,13 @@ fn main() {
         diff()
             .expected_file("short-error.txt")
             .actual_text("(linker error)", out.stderr())
-            .normalize("libpanic_abort", "libpanic_unwind")
             .normalize(
                 regex::escape(
                     run_make_support::build_root().canonicalize().unwrap().to_str().unwrap(),
                 ),
                 "/build-root",
             )
+            .normalize("libpanic_abort", "libpanic_unwind")
             .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"")
             .normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"")
             .run();
diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
index 0e2e30390ad..2ff7174577e 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
+++ b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout
@@ -1,8 +1,8 @@
 
 running 3 tests
-test $DIR/doctest-output.rs - (line 12) ... ok
-test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok
-test $DIR/doctest-output.rs - foo::bar (line 22) ... ok
+test $DIR/doctest-output.rs - (line 14) ... ok
+test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok
+test $DIR/doctest-output.rs - foo::bar (line 24) ... ok
 
 test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
index 0e2e30390ad..20bfd7e7086 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
+++ b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout
@@ -1,8 +1,9 @@
 
 running 3 tests
-test $DIR/doctest-output.rs - (line 12) ... ok
-test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok
-test $DIR/doctest-output.rs - foo::bar (line 22) ... ok
+test $DIR/doctest-output.rs - (line 14) ... ok
+test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok
+test $DIR/doctest-output.rs - foo::bar (line 24) ... ok
 
 test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs
index 04bd1813b4c..943f59e8b15 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.rs
+++ b/tests/rustdoc-ui/doctest/doctest-output.rs
@@ -7,6 +7,8 @@
 //@[edition2024]compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
+//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
 //@ check-pass
 
 //! ```
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
index 7dac64e6de4..f92bea74bfe 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs
@@ -2,6 +2,8 @@
 //@ compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
 //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME"
+//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME"
 //@ check-pass
 
 /// ```ignore (test)
diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
index a32da0aeb96..6714cdb0b80 100644
--- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
+++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout
@@ -1,7 +1,8 @@
 
 running 2 tests
-test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored
-test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok
+test $DIR/merged-ignore-no_run.rs - ignored (line 9) ... ignored
+test $DIR/merged-ignore-no_run.rs - no_run (line 14) - compile ... ok
 
 test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME
 
+all doctests ran in $TIME; merged doctests compilation took $TIME
diff --git a/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs
new file mode 100644
index 00000000000..c8ca4537089
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.rs
@@ -0,0 +1,3 @@
+use std::ops::CoerceShared; //~ ERROR  use of unstable library feature `reborrow`
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr
new file mode 100644
index 00000000000..dbbbcdf2fd5
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-reborrow-coerce-shared.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature `reborrow`
+  --> $DIR/feature-gate-reborrow-coerce-shared.rs:1:5
+   |
+LL | use std::ops::CoerceShared;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #145612 <https://github.com/rust-lang/rust/issues/145612> for more information
+   = help: add `#![feature(reborrow)]` 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 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-reborrow.rs b/tests/ui/feature-gates/feature-gate-reborrow.rs
index f016f6c6bfa..96eecfb28a1 100644
--- a/tests/ui/feature-gates/feature-gate-reborrow.rs
+++ b/tests/ui/feature-gates/feature-gate-reborrow.rs
@@ -1,3 +1,3 @@
-use std::marker::Reborrow; //~ ERROR  use of unstable library feature `reborrow`
+use std::ops::Reborrow; //~ ERROR  use of unstable library feature `reborrow`
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-reborrow.stderr b/tests/ui/feature-gates/feature-gate-reborrow.stderr
index 5e3033f3bf1..1224909f564 100644
--- a/tests/ui/feature-gates/feature-gate-reborrow.stderr
+++ b/tests/ui/feature-gates/feature-gate-reborrow.stderr
@@ -1,8 +1,8 @@
 error[E0658]: use of unstable library feature `reborrow`
   --> $DIR/feature-gate-reborrow.rs:1:5
    |
-LL | use std::marker::Reborrow;
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL | use std::ops::Reborrow;
+   |     ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #145612 <https://github.com/rust-lang/rust/issues/145612> for more information
    = help: add `#![feature(reborrow)]` to the crate attributes to enable
diff --git a/tests/ui/reborrow/custom_mut.rs b/tests/ui/reborrow/custom_mut.rs
new file mode 100644
index 00000000000..1e7c4693238
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut.rs
@@ -0,0 +1,13 @@
+#![feature(reborrow)]
+use std::ops::Reborrow;
+
+struct CustomMut<'a, T>(&'a mut T);
+impl<'a, T> Reborrow for CustomMut<'a, T> {}
+
+fn method(a: CustomMut<'_, ()>) {}
+
+fn main() {
+    let a = CustomMut(&mut ());
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/custom_mut.stderr b/tests/ui/reborrow/custom_mut.stderr
new file mode 100644
index 00000000000..3b3f47b62d6
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut.stderr
@@ -0,0 +1,29 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/custom_mut.rs:12:20
+   |
+LL |     let a = CustomMut(&mut ());
+   |         - move occurs because `a` has type `CustomMut<'_, ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/custom_mut.rs:7:14
+   |
+LL | fn method(a: CustomMut<'_, ()>) {}
+   |    ------    ^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+note: if `CustomMut<'_, ()>` implemented `Clone`, you could clone the value
+  --> $DIR/custom_mut.rs:4:1
+   |
+LL | struct CustomMut<'a, T>(&'a mut T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |     let _ = method(a);
+   |                    - you could clone this value
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.rs b/tests/ui/reborrow/custom_mut_coerce_shared.rs
new file mode 100644
index 00000000000..e2d25835c09
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut_coerce_shared.rs
@@ -0,0 +1,28 @@
+#![feature(reborrow)]
+use std::ops::{CoerceShared, Reborrow};
+
+struct CustomMut<'a, T>(&'a mut T);
+impl<'a, T> Reborrow for CustomMut<'a, T> {}
+impl<'a, T> CoerceShared for CustomMut<'a, T> {
+    type Target = CustomRef<'a, T>;
+}
+
+struct CustomRef<'a, T>(&'a T);
+
+impl<'a, T> Clone for CustomRef<'a, T> {
+    fn clone(&self) -> Self {
+        Self(self.0)
+    }
+}
+impl<'a, T> Copy for CustomRef<'a, T> {}
+
+fn method(a: CustomRef<'_, ()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = CustomMut(&mut ());
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>`
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE expected struct `CustomRef<'_, ()>`
+}
diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.stderr b/tests/ui/reborrow/custom_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..508651badc0
--- /dev/null
+++ b/tests/ui/reborrow/custom_mut_coerce_shared.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/custom_mut_coerce_shared.rs:23:12
+   |
+LL |     method(a);
+   |     ------ ^ expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `CustomRef<'_, ()>`
+              found struct `CustomMut<'_, ()>`
+note: function defined here
+  --> $DIR/custom_mut_coerce_shared.rs:19:4
+   |
+LL | fn method(a: CustomRef<'_, ()>) {}
+   |    ^^^^^^ --------------------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/reborrow/option_mut.rs b/tests/ui/reborrow/option_mut.rs
new file mode 100644
index 00000000000..04d8301772d
--- /dev/null
+++ b/tests/ui/reborrow/option_mut.rs
@@ -0,0 +1,7 @@
+fn method(a: Option<&mut ()>) {}
+
+fn main() {
+    let a = Some(&mut ());
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/option_mut.stderr b/tests/ui/reborrow/option_mut.stderr
new file mode 100644
index 00000000000..d665e266079
--- /dev/null
+++ b/tests/ui/reborrow/option_mut.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/option_mut.rs:6:20
+   |
+LL |     let a = Some(&mut ());
+   |         - move occurs because `a` has type `Option<&mut ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/option_mut.rs:1:14
+   |
+LL | fn method(a: Option<&mut ()>) {}
+   |    ------    ^^^^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/option_mut_coerce_shared.rs b/tests/ui/reborrow/option_mut_coerce_shared.rs
new file mode 100644
index 00000000000..95d33ed94dd
--- /dev/null
+++ b/tests/ui/reborrow/option_mut_coerce_shared.rs
@@ -0,0 +1,11 @@
+fn method(a: Option<&()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = Some(&mut ());
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE types differ in mutability
+    //~| NOTE expected enum `Option<&()>`
+    //~| NOTE    found enum `Option<&mut ()>`
+}
diff --git a/tests/ui/reborrow/option_mut_coerce_shared.stderr b/tests/ui/reborrow/option_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..6ca1a237461
--- /dev/null
+++ b/tests/ui/reborrow/option_mut_coerce_shared.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/option_mut_coerce_shared.rs:5:12
+   |
+LL |     method(a);
+   |     ------ ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected enum `Option<&()>`
+              found enum `Option<&mut ()>`
+note: function defined here
+  --> $DIR/option_mut_coerce_shared.rs:1:4
+   |
+LL | fn method(a: Option<&()>) {}
+   |    ^^^^^^ --------------
+help: try using `.as_deref()` to convert `Option<&mut ()>` to `Option<&()>`
+   |
+LL |     method(a.as_deref());
+   |             +++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/reborrow/pin_mut.rs b/tests/ui/reborrow/pin_mut.rs
new file mode 100644
index 00000000000..959cb14f8c9
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut.rs
@@ -0,0 +1,10 @@
+use std::pin::Pin;
+
+fn method(a: Pin<&mut ()>) {}
+
+fn main() {
+    let a = &mut ();
+    let a = Pin::new(a);
+    let _ = method(a);
+    let _ = method(a); //~ERROR use of moved value: `a`
+}
diff --git a/tests/ui/reborrow/pin_mut.stderr b/tests/ui/reborrow/pin_mut.stderr
new file mode 100644
index 00000000000..64e3f603e11
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `a`
+  --> $DIR/pin_mut.rs:9:20
+   |
+LL |     let a = Pin::new(a);
+   |         - move occurs because `a` has type `Pin<&mut ()>`, which does not implement the `Copy` trait
+LL |     let _ = method(a);
+   |                    - value moved here
+LL |     let _ = method(a);
+   |                    ^ value used here after move
+   |
+note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary
+  --> $DIR/pin_mut.rs:3:14
+   |
+LL | fn method(a: Pin<&mut ()>) {}
+   |    ------    ^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.rs b/tests/ui/reborrow/pin_mut_coerce_shared.rs
new file mode 100644
index 00000000000..06af0b765d0
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut_coerce_shared.rs
@@ -0,0 +1,13 @@
+use std::pin::Pin;
+
+fn method(a: Pin<&()>) {}  //~NOTE function defined here
+
+fn main() {
+    let a = &mut ();
+    let a = Pin::new(a);
+    method(a);
+    //~^ ERROR mismatched types
+    //~| NOTE arguments to this function are incorrect
+    //~| NOTE types differ in mutability
+    //~| NOTE expected struct `Pin<&()>`
+}
diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.stderr b/tests/ui/reborrow/pin_mut_coerce_shared.stderr
new file mode 100644
index 00000000000..74ecf4de4c7
--- /dev/null
+++ b/tests/ui/reborrow/pin_mut_coerce_shared.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/pin_mut_coerce_shared.rs:8:12
+   |
+LL |     method(a);
+   |     ------ ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `Pin<&()>`
+              found struct `Pin<&mut ()>`
+note: function defined here
+  --> $DIR/pin_mut_coerce_shared.rs:3:4
+   |
+LL | fn method(a: Pin<&()>) {}
+   |    ^^^^^^ -----------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.