about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-17 19:21:44 +0000
committerbors <bors@rust-lang.org>2024-04-17 19:21:44 +0000
commitd261b5308111fa95427fcfdfd53a8331dd44a2b6 (patch)
tree8a985a2ac605d07089841ac906e13601c9d06390
parent9776f647e67cadaa8c5f56a04c933c72fe27ccbc (diff)
parent7c3c2716ff46fb3276c16bdaea226e5a5abc08c0 (diff)
downloadrust-d261b5308111fa95427fcfdfd53a8331dd44a2b6.tar.gz
rust-d261b5308111fa95427fcfdfd53a8331dd44a2b6.zip
Auto merge of #3481 - RalfJung:rustup, r=RalfJung
Rustup
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs27
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs35
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/traits.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs8
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--library/alloc/src/boxed.rs26
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs6
-rw-r--r--library/alloc/src/collections/btree/set.rs4
-rw-r--r--library/alloc/src/collections/linked_list.rs22
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs8
-rw-r--r--library/alloc/src/string.rs4
-rw-r--r--library/alloc/src/vec/mod.rs26
-rw-r--r--library/core/src/cell.rs6
-rw-r--r--library/core/src/cmp.rs4
-rw-r--r--library/core/src/task/wake.rs36
-rw-r--r--library/std/src/collections/hash/map.rs4
-rw-r--r--library/std/src/collections/hash/set.rs4
-rw-r--r--library/std/src/ffi/os_str.rs4
-rw-r--r--library/std/src/io/cursor.rs6
-rw-r--r--library/std/src/io/util.rs6
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/path.rs4
-rw-r--r--src/ci/docker/README.md11
-rwxr-xr-xsrc/ci/docker/run.sh20
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs11
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs18
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs12
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs10
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs2
-rw-r--r--src/tools/miri/src/machine.rs22
-rw-r--r--src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr2
-rw-r--r--tests/run-make/issue-107495-archive-permissions/foo.rs1
-rw-r--r--tests/run-make/issue-107495-archive-permissions/rmake.rs31
-rw-r--r--tests/ui/abi/anon-extern-mod.rs6
-rw-r--r--tests/ui/abi/c-stack-as-value.rs6
-rw-r--r--tests/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs5
-rw-r--r--tests/ui/abi/foreign/auxiliary/foreign_lib.rs24
-rw-r--r--tests/ui/abi/foreign/foreign-dupe.rs3
-rw-r--r--tests/ui/abi/foreign/foreign-no-abi.rs21
-rw-r--r--tests/ui/attributes/item-attributes.rs2
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs3
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr23
-rw-r--r--tests/ui/coherence/coherence-orphan.rs3
-rw-r--r--tests/ui/coherence/coherence-orphan.stderr31
-rw-r--r--tests/ui/error-codes/E0117.rs1
-rw-r--r--tests/ui/error-codes/E0117.stderr14
-rw-r--r--tests/ui/extern/issue-1251.rs5
-rw-r--r--tests/ui/inference/dont-collect-stmts-from-parent-body.rs15
-rw-r--r--tests/ui/inference/dont-collect-stmts-from-parent-body.stderr24
-rw-r--r--tests/ui/issues/issue-67535.rs6
-rw-r--r--tests/ui/issues/issue-67535.stderr41
-rw-r--r--tests/ui/weird-exprs.rs15
-rw-r--r--tests/ui/wf/conflicting-impls.rs20
-rw-r--r--tests/ui/wf/conflicting-impls.stderr12
-rw-r--r--triagebot.toml48
62 files changed, 471 insertions, 286 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index d336973d2b9..c99118f5156 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -13,7 +13,7 @@ use object::read::macho::FatArch;
 use tempfile::Builder as TempFileBuilder;
 
 use std::error::Error;
-use std::fs::File;
+use std::fs::{self, File};
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 
@@ -280,12 +280,21 @@ impl<'a> ArArchiveBuilder<'a> {
         // This prevents programs (including rustc) from attempting to read a partial archive.
         // It also enables writing an archive with the same filename as a dependency on Windows as
         // required by a test.
-        let mut archive_tmpfile = TempFileBuilder::new()
+        // The tempfile crate currently uses 0o600 as mode for the temporary files and directories
+        // it creates. We need it to be the default mode for back compat reasons however. (See
+        // #107495) To handle this we are telling tempfile to create a temporary directory instead
+        // and then inside this directory create a file using File::create.
+        let archive_tmpdir = TempFileBuilder::new()
             .suffix(".temp-archive")
-            .tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
-            .map_err(|err| io_error_context("couldn't create a temp file", err))?;
+            .tempdir_in(output.parent().unwrap_or_else(|| Path::new("")))
+            .map_err(|err| {
+                io_error_context("couldn't create a directory for the temp file", err)
+            })?;
+        let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a");
+        let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
+            .map_err(|err| io_error_context("couldn't create the temp file", err))?;
 
-        write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
+        write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
 
         let any_entries = !entries.is_empty();
         drop(entries);
@@ -293,9 +302,11 @@ impl<'a> ArArchiveBuilder<'a> {
         // output archive to the same location as an input archive on Windows.
         drop(self.src_archives);
 
-        archive_tmpfile
-            .persist(output)
-            .map_err(|err| io_error_context("failed to rename archive file", err.error))?;
+        fs::rename(archive_tmpfile_path, output)
+            .map_err(|err| io_error_context("failed to rename archive file", err))?;
+        archive_tmpdir
+            .close()
+            .map_err(|err| io_error_context("failed to remove temporary directory", err))?;
 
         Ok(any_entries)
     }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 3aeae5ebf6d..7617cb57b3c 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -288,28 +288,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
     }
 
     /// Return the `AllocId` for the given thread-local static in the current thread.
-    fn thread_local_static_base_pointer(
+    fn thread_local_static_pointer(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         def_id: DefId,
     ) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
         throw_unsup!(ThreadLocalStatic(def_id))
     }
 
-    /// Return the root pointer for the given `extern static`.
-    fn extern_static_base_pointer(
+    /// Return the `AllocId` for the given `extern static`.
+    fn extern_static_pointer(
         ecx: &InterpCx<'mir, 'tcx, Self>,
         def_id: DefId,
     ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
 
-    /// Return a "base" pointer for the given allocation: the one that is used for direct
-    /// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
-    ///
-    /// Not called on `extern` or thread-local statics (those use the methods above).
-    fn adjust_alloc_base_pointer(
-        ecx: &InterpCx<'mir, 'tcx, Self>,
-        ptr: Pointer,
-    ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
-
     /// "Int-to-pointer cast"
     fn ptr_from_addr_cast(
         ecx: &InterpCx<'mir, 'tcx, Self>,
@@ -336,6 +327,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
 
     /// Called to adjust allocations to the Provenance and AllocExtra of this machine.
     ///
+    /// If `alloc` contains pointers, then they are all pointing to globals.
+    ///
     /// The way we construct allocations is to always first construct it without extra and then add
     /// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
     /// globals, and allocations created by Miri during evaluation.
@@ -354,6 +347,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         kind: Option<MemoryKind<Self::MemoryKind>>,
     ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
 
+    /// Return a "root" pointer for the given allocation: the one that is used for direct
+    /// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
+    ///
+    /// Not called on `extern` or thread-local statics (those use the methods above).
+    ///
+    /// `kind` is the kind of the allocation the pointer points to; it can be `None` when
+    /// it's a global and `GLOBAL_KIND` is `None`.
+    fn adjust_alloc_root_pointer(
+        ecx: &InterpCx<'mir, 'tcx, Self>,
+        ptr: Pointer,
+        kind: Option<MemoryKind<Self::MemoryKind>>,
+    ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
+
     /// Evaluate the inline assembly.
     ///
     /// This should take care of jumping to the next block (one of `targets`) when asm goto
@@ -592,7 +598,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
         Ok(alloc)
     }
 
-    fn extern_static_base_pointer(
+    fn extern_static_pointer(
         ecx: &InterpCx<$mir, $tcx, Self>,
         def_id: DefId,
     ) -> InterpResult<$tcx, Pointer> {
@@ -601,9 +607,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     }
 
     #[inline(always)]
-    fn adjust_alloc_base_pointer(
+    fn adjust_alloc_root_pointer(
         _ecx: &InterpCx<$mir, $tcx, Self>,
         ptr: Pointer<CtfeProvenance>,
+        _kind: Option<MemoryKind<Self::MemoryKind>>,
     ) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
         Ok(ptr)
     }
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index fbb0907f7d0..594e3b3212f 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -165,7 +165,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ///
     /// This function can fail only if `ptr` points to an `extern static`.
     #[inline]
-    pub fn global_base_pointer(
+    pub fn global_root_pointer(
         &self,
         ptr: Pointer<CtfeProvenance>,
     ) -> InterpResult<'tcx, Pointer<M::Provenance>> {
@@ -178,12 +178,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 bug!("global memory cannot point to thread-local static")
             }
             Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
-                return M::extern_static_base_pointer(self, def_id);
+                return M::extern_static_pointer(self, def_id);
+            }
+            None => {
+                assert!(
+                    self.memory.extra_fn_ptr_map.contains_key(&alloc_id),
+                    "{alloc_id:?} is neither global nor a function pointer"
+                );
             }
             _ => {}
         }
         // And we need to get the provenance.
-        M::adjust_alloc_base_pointer(self, ptr)
+        M::adjust_alloc_root_pointer(self, ptr, M::GLOBAL_KIND.map(MemoryKind::Machine))
     }
 
     pub fn fn_ptr(&mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>) -> Pointer<M::Provenance> {
@@ -197,9 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 id
             }
         };
-        // Functions are global allocations, so make sure we get the right base pointer.
+        // Functions are global allocations, so make sure we get the right root pointer.
         // We know this is not an `extern static` so this cannot fail.
-        self.global_base_pointer(Pointer::from(id)).unwrap()
+        self.global_root_pointer(Pointer::from(id)).unwrap()
     }
 
     pub fn allocate_ptr(
@@ -240,7 +246,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         );
         let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
         self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
-        M::adjust_alloc_base_pointer(self, Pointer::from(id))
+        M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
     }
 
     pub fn reallocate_ptr(
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 842fb6d204c..c120154ce2a 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -764,7 +764,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // Other cases need layout.
         let adjust_scalar = |scalar| -> InterpResult<'tcx, _> {
             Ok(match scalar {
-                Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size),
+                Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_root_pointer(ptr)?, size),
                 Scalar::Int(int) => Scalar::Int(int),
             })
         };
@@ -772,7 +772,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let imm = match val_val {
             mir::ConstValue::Indirect { alloc_id, offset } => {
                 // This is const data, no mutation allowed.
-                let ptr = self.global_base_pointer(Pointer::new(
+                let ptr = self.global_root_pointer(Pointer::new(
                     CtfeProvenance::from(alloc_id).as_immutable(),
                     offset,
                 ))?;
@@ -784,7 +784,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // This is const data, no mutation allowed.
                 let alloc_id = self.tcx.reserve_and_set_memory_alloc(data);
                 let ptr = Pointer::new(CtfeProvenance::from(alloc_id).as_immutable(), Size::ZERO);
-                Immediate::new_slice(self.global_base_pointer(ptr)?.into(), meta, self)
+                Immediate::new_slice(self.global_root_pointer(ptr)?.into(), meta, self)
             }
         };
         Ok(OpTy { op: Operand::Immediate(imm), layout })
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index e32aea39fc5..1549eddabbc 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -1010,7 +1010,7 @@ where
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
         // This must be an allocation in `tcx`
         let _ = self.tcx.global_alloc(raw.alloc_id);
-        let ptr = self.global_base_pointer(Pointer::from(raw.alloc_id))?;
+        let ptr = self.global_root_pointer(Pointer::from(raw.alloc_id))?;
         let layout = self.layout_of(raw.ty)?;
         Ok(self.ptr_to_mplace(ptr.into(), layout))
     }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index db6c2833b9d..c3f26da8a79 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -144,7 +144,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         use rustc_middle::mir::Rvalue::*;
         match *rvalue {
             ThreadLocalRef(did) => {
-                let ptr = M::thread_local_static_base_pointer(self, did)?;
+                let ptr = M::thread_local_static_pointer(self, did)?;
                 self.write_pointer(ptr, &dest)?;
             }
 
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index a9ca268a2a9..b603ef0d27a 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
 
         let vtable_symbolic_allocation = self.tcx.reserve_and_set_vtable_alloc(ty, poly_trait_ref);
-        let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
+        let vtable_ptr = self.global_root_pointer(Pointer::from(vtable_symbolic_allocation))?;
         Ok(vtable_ptr.into())
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 8c85d13650b..3881e240ced 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -660,8 +660,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         }
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
-                check_impl_items_against_trait(tcx, def_id, impl_trait_header);
-                check_on_unimplemented(tcx, def_id);
+                if tcx
+                    .ensure()
+                    .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
+                    .is_ok()
+                {
+                    check_impl_items_against_trait(tcx, def_id, impl_trait_header);
+                    check_on_unimplemented(tcx, def_id);
+                }
             }
         }
         DefKind::Trait => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 4a73ce2e640..d9e5289f632 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2011,12 +2011,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         for (span, code) in errors_causecode {
             self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
                 if let Some(fn_sig) = self.body_fn_sig()
-                    && let ExprBindingObligation(_, _, hir_id, ..) = code
+                    && let ExprBindingObligation(_, _, binding_hir_id, ..) = code
                     && !fn_sig.output().is_unit()
                 {
                     let mut block_num = 0;
                     let mut found_semi = false;
-                    for (_, node) in self.tcx.hir().parent_iter(hir_id) {
+                    for (hir_id, node) in self.tcx.hir().parent_iter(binding_hir_id) {
+                        // Don't proceed into parent bodies
+                        if hir_id.owner != binding_hir_id.owner {
+                            break;
+                        }
                         match node {
                             hir::Node::Stmt(stmt) => {
                                 if let hir::StmtKind::Semi(expr) = stmt.kind {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 1dbf435e8c7..255e688fbc1 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -952,7 +952,7 @@ impl<'tcx> InferCtxt<'tcx> {
             // a test for it.
             (_, ty::Infer(ty::TyVar(_))) => {}
             (ty::Infer(ty::TyVar(_)), _) => {}
-            _ if (r_a, r_b).has_opaque_types() => {
+            _ if r_a != r_b && (r_a, r_b).has_opaque_types() => {
                 span_bug!(
                     cause.span(),
                     "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}"
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index ed3ad8b39a5..e5d62447eb2 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2088,11 +2088,29 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
         self.to_vec_in(alloc).into_boxed_slice()
     }
 
-    fn clone_from(&mut self, other: &Self) {
-        if self.len() == other.len() {
-            self.clone_from_slice(&other);
+    /// Copies `source`'s contents into `self` without creating a new allocation,
+    /// so long as the two are of the same length.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = Box::new([5, 6, 7]);
+    /// let mut y = Box::new([8, 9, 10]);
+    /// let yp: *const [i32] = &*y;
+    ///
+    /// y.clone_from(&x);
+    ///
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // And no allocation occurred
+    /// assert_eq!(yp, &*y);
+    /// ```
+    fn clone_from(&mut self, source: &Self) {
+        if self.len() == source.len() {
+            self.clone_from_slice(&source);
         } else {
-            *self = other.clone();
+            *self = source.clone();
         }
     }
 }
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 83b2678f7f5..c54f0062824 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -385,6 +385,12 @@ impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
         BinaryHeap { data: self.data.clone() }
     }
 
+    /// Overwrites the contents of `self` with a clone of the contents of `source`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
+    ///
+    /// See [`Vec::clone_from()`] for more details.
     fn clone_from(&mut self, source: &Self) {
         self.data.clone_from(&source.data);
     }
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 7508ae468ae..b0bd6ef2d3c 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -116,8 +116,8 @@ impl<T: Clone, A: Allocator + Clone> Clone for BTreeSet<T, A> {
         BTreeSet { map: self.map.clone() }
     }
 
-    fn clone_from(&mut self, other: &Self) {
-        self.map.clone_from(&other.map);
+    fn clone_from(&mut self, source: &Self) {
+        self.map.clone_from(&source.map);
     }
 }
 
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 6dfb82ac807..1c90c171a15 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -2126,16 +2126,22 @@ impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
         list
     }
 
-    fn clone_from(&mut self, other: &Self) {
-        let mut iter_other = other.iter();
-        if self.len() > other.len() {
-            self.split_off(other.len());
+    /// Overwrites the contents of `self` with a clone of the contents of `source`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation of the nodes of the linked list. Additionally,
+    /// if the element type `T` overrides `clone_from()`, this will reuse the
+    /// resources of `self`'s elements as well.
+    fn clone_from(&mut self, source: &Self) {
+        let mut source_iter = source.iter();
+        if self.len() > source.len() {
+            self.split_off(source.len());
         }
-        for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
-            elem.clone_from(elem_other);
+        for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) {
+            elem.clone_from(source_elem);
         }
-        if !iter_other.is_empty() {
-            self.extend(iter_other.cloned());
+        if !source_iter.is_empty() {
+            self.extend(source_iter.cloned());
         }
     }
 }
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 693ecb0b6b4..4643a6bbe2e 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -113,9 +113,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
         deq
     }
 
-    fn clone_from(&mut self, other: &Self) {
+    /// Overwrites the contents of `self` with a clone of the contents of `source`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
+    fn clone_from(&mut self, source: &Self) {
         self.clear();
-        self.extend(other.iter().cloned());
+        self.extend(source.iter().cloned());
     }
 }
 
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 5d552c8f15c..082af1447ec 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2097,6 +2097,10 @@ impl Clone for String {
         String { vec: self.vec.clone() }
     }
 
+    /// Clones the contents of `source` into `self`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
     fn clone_from(&mut self, source: &Self) {
         self.vec.clone_from(&source.vec);
     }
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 465da39f184..1930be65bfb 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2846,8 +2846,30 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
         crate::slice::to_vec(&**self, alloc)
     }
 
-    fn clone_from(&mut self, other: &Self) {
-        crate::slice::SpecCloneIntoVec::clone_into(other.as_slice(), self);
+    /// Overwrites the contents of `self` with a clone of the contents of `source`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible. Additionally, if the element type
+    /// `T` overrides `clone_from()`, this will reuse the resources of `self`'s
+    /// elements as well.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = vec![5, 6, 7];
+    /// let mut y = vec![8, 9, 10];
+    /// let yp: *const i32 = y.as_ptr();
+    ///
+    /// y.clone_from(&x);
+    ///
+    /// // The value is the same
+    /// assert_eq!(x, y);
+    ///
+    /// // And no reallocation occurred
+    /// assert_eq!(yp, y.as_ptr());
+    /// ```
+    fn clone_from(&mut self, source: &Self) {
+        crate::slice::SpecCloneIntoVec::clone_into(source.as_slice(), self);
     }
 }
 
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 58b9ba4accb..ae0436bc520 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1277,11 +1277,11 @@ impl<T: Clone> Clone for RefCell<T> {
 
     /// # Panics
     ///
-    /// Panics if `other` is currently mutably borrowed.
+    /// Panics if `source` is currently mutably borrowed.
     #[inline]
     #[track_caller]
-    fn clone_from(&mut self, other: &Self) {
-        self.get_mut().clone_from(&other.borrow())
+    fn clone_from(&mut self, source: &Self) {
+        self.get_mut().clone_from(&source.borrow())
     }
 }
 
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index fa218600ed9..2fd9e17c994 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -688,8 +688,8 @@ impl<T: Clone> Clone for Reverse<T> {
     }
 
     #[inline]
-    fn clone_from(&mut self, other: &Self) {
-        self.0.clone_from(&other.0)
+    fn clone_from(&mut self, source: &Self) {
+        self.0.clone_from(&source.0)
     }
 }
 
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index fe39f6c0b56..7691721b91e 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -576,6 +576,42 @@ impl Clone for Waker {
         }
     }
 
+    /// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids cloning the waker if `self` is already the same waker.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::future::Future;
+    /// use std::pin::Pin;
+    /// use std::sync::{Arc, Mutex};
+    /// use std::task::{Context, Poll, Waker};
+    ///
+    /// struct Waiter {
+    ///     shared: Arc<Mutex<Shared>>,
+    /// }
+    ///
+    /// struct Shared {
+    ///     waker: Waker,
+    ///     // ...
+    /// }
+    ///
+    /// impl Future for Waiter {
+    ///     type Output = ();
+    ///     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+    ///         let mut shared = self.shared.lock().unwrap();
+    ///
+    ///         // update the waker
+    ///         shared.waker.clone_from(cx.waker());
+    ///
+    ///         // readiness logic ...
+    /// #       Poll::Ready(())
+    ///     }
+    /// }
+    ///
+    /// ```
     #[inline]
     fn clone_from(&mut self, source: &Self) {
         if !self.will_wake(source) {
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 2cc9afe9249..5039f0b6bb2 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1271,8 +1271,8 @@ where
     }
 
     #[inline]
-    fn clone_from(&mut self, other: &Self) {
-        self.base.clone_from(&other.base);
+    fn clone_from(&mut self, source: &Self) {
+        self.base.clone_from(&source.base);
     }
 }
 
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 3910100f212..f0a498fc7bb 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -978,6 +978,10 @@ where
         Self { base: self.base.clone() }
     }
 
+    /// Overwrites the contents of `self` with a clone of the contents of `source`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
     #[inline]
     fn clone_from(&mut self, other: &Self) {
         self.base.clone_from(&other.base);
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 8927e9a47fa..20ebe1c4f8a 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -606,6 +606,10 @@ impl Clone for OsString {
         OsString { inner: self.inner.clone() }
     }
 
+    /// Clones the contents of `source` into `self`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
     #[inline]
     fn clone_from(&mut self, source: &Self) {
         self.inner.clone_from(&source.inner)
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 49dde828c1f..5b782fff7e5 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -95,7 +95,7 @@ impl<T> Cursor<T> {
     /// # force_inference(&buff);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
     pub const fn new(inner: T) -> Cursor<T> {
         Cursor { pos: 0, inner }
     }
@@ -132,7 +132,7 @@ impl<T> Cursor<T> {
     /// let reference = buff.get_ref();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
     pub const fn get_ref(&self) -> &T {
         &self.inner
     }
@@ -178,7 +178,7 @@ impl<T> Cursor<T> {
     /// assert_eq!(buff.position(), 1);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+    #[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
     pub const fn position(&self) -> u64 {
         self.pos
     }
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index 16eaed15e72..266a447f06b 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -51,7 +51,7 @@ pub struct Empty;
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
 pub const fn empty() -> Empty {
     Empty
 }
@@ -173,7 +173,7 @@ pub struct Repeat {
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
 pub const fn repeat(byte: u8) -> Repeat {
     Repeat { byte }
 }
@@ -276,7 +276,7 @@ pub struct Sink;
 /// ```
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
+#[rustc_const_stable(feature = "const_io_structs", since = "CURRENT_RUSTC_VERSION")]
 pub const fn sink() -> Sink {
     Sink
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 72ae38cfa20..d152626d86a 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -407,7 +407,6 @@
 // tidy-alphabetical-start
 #![feature(const_collections_with_hasher)]
 #![feature(const_hash)]
-#![feature(const_io_structs)]
 #![feature(const_ip)]
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5f43d63bf84..0636f55771e 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1628,6 +1628,10 @@ impl Clone for PathBuf {
         PathBuf { inner: self.inner.clone() }
     }
 
+    /// Clones the contents of `source` into `self`.
+    ///
+    /// This method is preferred over simply assigning `source.clone()` to `self`,
+    /// as it avoids reallocation if possible.
     #[inline]
     fn clone_from(&mut self, source: &Self) {
         self.inner.clone_from(&source.inner)
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index 2e645683713..9af368ef445 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -14,7 +14,7 @@ for example:
 ./src/ci/docker/run.sh x86_64-gnu
 ```
 
-Images will output artifacts in an `obj` dir at the root of a repository. Note
+Images will output artifacts in an `obj/$image_name` dir at the root of a repository. Note
 that the script will overwrite the contents of this directory.
 
 To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e.g.:
@@ -22,12 +22,9 @@ To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e
 DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu
 ```
 
-**NOTE**: Re-using the same `obj` dir with different docker images with
-the same target triple (e.g. `dist-x86_64-linux` and `dist-various-1`)
-may result in strange linker errors, due shared library versions differing between platforms.
-
-If you encounter any issues when using multiple Docker images, try deleting your `obj` directory
-before running your command.
+**NOTE**: In CI, the script outputs the artifacts to the `obj` directory,
+while locally, to the `obj/$image_name` directory. This is primarily to prevent
+strange linker errors when using multiple Docker images.
 
 ## Filesystem layout
 
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 9d72fd8a55a..fcc507b572c 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -33,7 +33,13 @@ ci_dir="`dirname $script_dir`"
 src_dir="`dirname $ci_dir`"
 root_dir="`dirname $src_dir`"
 
-objdir=$root_dir/obj
+source "$ci_dir/shared.sh"
+
+if isCI; then
+    objdir=$root_dir/obj
+else
+    objdir=$root_dir/obj/$image
+fi
 dist=$objdir/build/dist
 
 
@@ -41,12 +47,10 @@ if [ -d "$root_dir/.git" ]; then
     IS_GIT_SOURCE=1
 fi
 
-source "$ci_dir/shared.sh"
-
 CACHE_DOMAIN="${CACHE_DOMAIN:-ci-caches.rust-lang.org}"
 
 if [ -f "$docker_dir/$image/Dockerfile" ]; then
-    if [ "$CI" != "" ]; then
+    if isCI; then
       hash_key=/tmp/.docker-hash-key.txt
       rm -f "${hash_key}"
       echo $image >> $hash_key
@@ -102,7 +106,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
     CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum}
 
     # On non-CI jobs, we don't do any caching.
-    if [[ "$CI" == "" ]];
+    if ! isCI;
     then
         retry docker build --rm -t rust-ci -f "$dockerfile" "$context"
     # On PR CI jobs, we don't have permissions to write to the registry cache,
@@ -289,7 +293,7 @@ else
   command=(/checkout/src/ci/run.sh)
 fi
 
-if [ "$CI" != "" ]; then
+if isCI; then
   # Get some needed information for $BASE_COMMIT
   #
   # This command gets the last merge commit which we'll use as base to list
@@ -339,7 +343,9 @@ docker \
   rust-ci \
   "${command[@]}"
 
-cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}"
+if isCI; then
+    cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}"
+fi
 
 if [ -f /.dockerenv ]; then
   rm -rf $objdir
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index bd87405da3d..f8f3016b15c 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-803e33a4460c82581bd01d4008d0f44aef1ddfe8
+c45dee5efd0c042e9d1e24559ebd0d6424d8aa70
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index fec39ec2b8e..3e00e6037c2 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -141,7 +141,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
     }
 
-    fn addr_from_alloc_id(&self, alloc_id: AllocId) -> InterpResult<'tcx, u64> {
+    fn addr_from_alloc_id(&self, alloc_id: AllocId, _kind: MemoryKind) -> InterpResult<'tcx, u64> {
         let ecx = self.eval_context_ref();
         let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
         let global_state = &mut *global_state;
@@ -283,16 +283,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     }
 
     /// Convert a relative (tcx) pointer to a Miri pointer.
-    fn ptr_from_rel_ptr(
+    fn adjust_alloc_root_pointer(
         &self,
         ptr: Pointer<CtfeProvenance>,
         tag: BorTag,
+        kind: MemoryKind,
     ) -> InterpResult<'tcx, Pointer<Provenance>> {
         let ecx = self.eval_context_ref();
 
         let (prov, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
         let alloc_id = prov.alloc_id();
-        let base_addr = ecx.addr_from_alloc_id(alloc_id)?;
+        let base_addr = ecx.addr_from_alloc_id(alloc_id, kind)?;
 
         // Add offset with the right kind of pointer-overflowing arithmetic.
         let dl = ecx.data_layout();
@@ -314,9 +315,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             ecx.alloc_id_from_addr(addr.bytes())?
         };
 
-        // This cannot fail: since we already have a pointer with that provenance, rel_ptr_to_addr
+        // This cannot fail: since we already have a pointer with that provenance, adjust_alloc_root_pointer
         // must have been called in the past, so we can just look up the address in the map.
-        let base_addr = ecx.addr_from_alloc_id(alloc_id).unwrap();
+        let base_addr = *ecx.machine.alloc_addresses.borrow().base_addr.get(&alloc_id).unwrap();
 
         // Wrapping "addr - base_addr"
         #[allow(clippy::cast_possible_wrap)] // we want to wrap here
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index f21315790a5..24e2a9a74bb 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -89,10 +89,10 @@ pub struct GlobalStateInner {
     borrow_tracker_method: BorrowTrackerMethod,
     /// Next unused pointer ID (tag).
     next_ptr_tag: BorTag,
-    /// Table storing the "base" tag for each allocation.
-    /// The base tag is the one used for the initial pointer.
+    /// Table storing the "root" tag for each allocation.
+    /// The root tag is the one used for the initial pointer.
     /// We need this in a separate table to handle cyclic statics.
-    base_ptr_tags: FxHashMap<AllocId, BorTag>,
+    root_ptr_tags: FxHashMap<AllocId, BorTag>,
     /// Next unused call ID (for protectors).
     next_call_id: CallId,
     /// All currently protected tags.
@@ -175,7 +175,7 @@ impl GlobalStateInner {
         GlobalStateInner {
             borrow_tracker_method,
             next_ptr_tag: BorTag::one(),
-            base_ptr_tags: FxHashMap::default(),
+            root_ptr_tags: FxHashMap::default(),
             next_call_id: NonZero::new(1).unwrap(),
             protected_tags: FxHashMap::default(),
             tracked_pointer_tags,
@@ -213,8 +213,8 @@ impl GlobalStateInner {
         }
     }
 
-    pub fn base_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag {
-        self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| {
+    pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag {
+        self.root_ptr_tags.get(&id).copied().unwrap_or_else(|| {
             let tag = self.new_ptr();
             if self.tracked_pointer_tags.contains(&tag) {
                 machine.emit_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(
@@ -223,14 +223,14 @@ impl GlobalStateInner {
                     None,
                 ));
             }
-            trace!("New allocation {:?} has base tag {:?}", id, tag);
-            self.base_ptr_tags.try_insert(id, tag).unwrap();
+            trace!("New allocation {:?} has rpot tag {:?}", id, tag);
+            self.root_ptr_tags.try_insert(id, tag).unwrap();
             tag
         })
     }
 
     pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) {
-        self.base_ptr_tags.retain(|id, _| allocs.is_live(*id));
+        self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
     }
 }
 
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
index 5a941ae9d03..cb677b86531 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
@@ -20,7 +20,7 @@ fn err_sb_ub<'tcx>(
 #[derive(Clone, Debug)]
 pub struct AllocHistory {
     id: AllocId,
-    base: (Item, Span),
+    root: (Item, Span),
     creations: smallvec::SmallVec<[Creation; 1]>,
     invalidations: smallvec::SmallVec<[Invalidation; 1]>,
     protectors: smallvec::SmallVec<[Protection; 1]>,
@@ -225,7 +225,7 @@ impl AllocHistory {
     pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_, '_>) -> Self {
         Self {
             id,
-            base: (item, machine.current_span()),
+            root: (item, machine.current_span()),
             creations: SmallVec::new(),
             invalidations: SmallVec::new(),
             protectors: SmallVec::new(),
@@ -342,15 +342,15 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
                 })
             })
             .or_else(|| {
-                // If we didn't find a retag that created this tag, it might be the base tag of
+                // If we didn't find a retag that created this tag, it might be the root tag of
                 // this allocation.
-                if self.history.base.0.tag() == tag {
+                if self.history.root.0.tag() == tag {
                     Some((
                         format!(
-                            "{tag:?} was created here, as the base tag for {:?}",
+                            "{tag:?} was created here, as the root tag for {:?}",
                             self.history.id
                         ),
-                        self.history.base.1.data(),
+                        self.history.root.1.data(),
                     ))
                 } else {
                     None
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index b4005515d9d..a6dd1d829cb 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -518,9 +518,9 @@ impl Stacks {
             // not through a pointer). That is, whenever we directly write to a local, this will pop
             // everything else off the stack, invalidating all previous pointers,
             // and in particular, *all* raw pointers.
-            MemoryKind::Stack => (state.base_ptr_tag(id, machine), Permission::Unique),
+            MemoryKind::Stack => (state.root_ptr_tag(id, machine), Permission::Unique),
             // Everything else is shared by default.
-            _ => (state.base_ptr_tag(id, machine), Permission::SharedReadWrite),
+            _ => (state.root_ptr_tag(id, machine), Permission::SharedReadWrite),
         };
         Stacks::new(size, perm, base_tag, id, machine)
     }
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
index 76430498e2b..bebd14d2f1e 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
@@ -47,7 +47,7 @@ impl Stack {
         let mut first_removed = None;
 
         // We never consider removing the bottom-most tag. For stacks without an unknown
-        // bottom this preserves the base tag.
+        // bottom this preserves the root tag.
         // Note that the algorithm below is based on considering the tag at read_idx - 1,
         // so precisely considering the tag at index 0 for removal when we have an unknown
         // bottom would complicate the implementation. The simplification of not considering
@@ -93,7 +93,7 @@ impl Stack {
                 self.unique_range = 0..self.len();
             }
 
-            // Replace any Items which have been collected with the base item, a known-good value.
+            // Replace any Items which have been collected with the root item, a known-good value.
             for i in 0..CACHE_LEN {
                 if self.cache.idx[i] >= first_removed {
                     self.cache.items[i] = self.borrows[0];
@@ -331,7 +331,7 @@ impl<'tcx> Stack {
         self.verify_cache_consistency();
     }
 
-    /// Construct a new `Stack` using the passed `Item` as the base tag.
+    /// Construct a new `Stack` using the passed `Item` as the root tag.
     pub fn new(item: Item) -> Self {
         Stack {
             borrows: vec![item],
@@ -438,8 +438,8 @@ impl<'tcx> Stack {
             let mut removed = 0;
             let mut cursor = 0;
             // Remove invalid entries from the cache by rotating them to the end of the cache, then
-            // keep track of how many invalid elements there are and overwrite them with the base tag.
-            // The base tag here serves as a harmless default value.
+            // keep track of how many invalid elements there are and overwrite them with the root tag.
+            // The root tag here serves as a harmless default value.
             for _ in 0..CACHE_LEN - 1 {
                 if self.cache.idx[cursor] >= start {
                     self.cache.idx[cursor..CACHE_LEN - removed].rotate_left(1);
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 492e324de45..fc5eb942a27 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -37,7 +37,7 @@ impl<'tcx> Tree {
         _kind: MemoryKind,
         machine: &MiriMachine<'_, 'tcx>,
     ) -> Self {
-        let tag = state.base_ptr_tag(id, machine); // Fresh tag for the root
+        let tag = state.root_ptr_tag(id, machine); // Fresh tag for the root
         let span = machine.current_span();
         Tree::new(tag, size, span)
     }
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 1d06d5c69d3..0bfc59e67db 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -503,7 +503,7 @@ pub struct MiriMachine<'mir, 'tcx> {
     /// Crates which are considered local for the purposes of error reporting.
     pub(crate) local_crates: Vec<CrateNum>,
 
-    /// Mapping extern static names to their base pointer.
+    /// Mapping extern static names to their pointer.
     extern_statics: FxHashMap<Symbol, Pointer<Provenance>>,
 
     /// The random number generator used for resolving non-determinism.
@@ -1042,14 +1042,14 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         ecx.generate_nan(inputs)
     }
 
-    fn thread_local_static_base_pointer(
+    fn thread_local_static_pointer(
         ecx: &mut MiriInterpCx<'mir, 'tcx>,
         def_id: DefId,
     ) -> InterpResult<'tcx, Pointer<Provenance>> {
         ecx.get_or_create_thread_local_alloc(def_id)
     }
 
-    fn extern_static_base_pointer(
+    fn extern_static_pointer(
         ecx: &MiriInterpCx<'mir, 'tcx>,
         def_id: DefId,
     ) -> InterpResult<'tcx, Pointer<Provenance>> {
@@ -1090,7 +1090,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         alloc: Cow<'b, Allocation>,
         kind: Option<MemoryKind>,
     ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
-        let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
+        let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
         if ecx.machine.tracked_alloc_ids.contains(&id) {
             ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
                 id,
@@ -1135,7 +1135,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
                 weak_memory: buffer_alloc,
                 backtrace,
             },
-            |ptr| ecx.global_base_pointer(ptr),
+            |ptr| ecx.global_root_pointer(ptr),
         )?;
 
         if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
@@ -1148,31 +1148,33 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         Ok(Cow::Owned(alloc))
     }
 
-    fn adjust_alloc_base_pointer(
+    fn adjust_alloc_root_pointer(
         ecx: &MiriInterpCx<'mir, 'tcx>,
         ptr: Pointer<CtfeProvenance>,
+        kind: Option<MemoryKind>,
     ) -> InterpResult<'tcx, Pointer<Provenance>> {
+        let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
         let alloc_id = ptr.provenance.alloc_id();
         if cfg!(debug_assertions) {
             // The machine promises to never call us on thread-local or extern statics.
             match ecx.tcx.try_get_global_alloc(alloc_id) {
                 Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_thread_local_static(def_id) => {
-                    panic!("adjust_alloc_base_pointer called on thread-local static")
+                    panic!("adjust_alloc_root_pointer called on thread-local static")
                 }
                 Some(GlobalAlloc::Static(def_id)) if ecx.tcx.is_foreign_item(def_id) => {
-                    panic!("adjust_alloc_base_pointer called on extern static")
+                    panic!("adjust_alloc_root_pointer called on extern static")
                 }
                 _ => {}
             }
         }
         // FIXME: can we somehow preserve the immutability of `ptr`?
         let tag = if let Some(borrow_tracker) = &ecx.machine.borrow_tracker {
-            borrow_tracker.borrow_mut().base_ptr_tag(alloc_id, &ecx.machine)
+            borrow_tracker.borrow_mut().root_ptr_tag(alloc_id, &ecx.machine)
         } else {
             // Value does not matter, SB is disabled
             BorTag::default()
         };
-        ecx.ptr_from_rel_ptr(ptr, tag)
+        ecx.adjust_alloc_root_pointer(ptr, tag, kind)
     }
 
     /// Called on `usize as ptr` casts.
diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr
index f6eeef33e9e..8426f56004b 100644
--- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.stack.stderr
@@ -6,7 +6,7 @@ LL |     unsafe { *x = 0 };
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: <TAG> was created here, as the base tag for ALLOC
+help: <TAG> was created here, as the root tag for ALLOC
   --> $DIR/invalidate_against_protector3.rs:LL:CC
    |
 LL |         let ptr = alloc(Layout::for_value(&0i32)) as *mut i32;
diff --git a/tests/run-make/issue-107495-archive-permissions/foo.rs b/tests/run-make/issue-107495-archive-permissions/foo.rs
new file mode 100644
index 00000000000..d15abba5976
--- /dev/null
+++ b/tests/run-make/issue-107495-archive-permissions/foo.rs
@@ -0,0 +1 @@
+// Empty
diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs
new file mode 100644
index 00000000000..40deabe15b7
--- /dev/null
+++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs
@@ -0,0 +1,31 @@
+#![feature(rustc_private)]
+
+#[cfg(unix)]
+extern crate libc;
+extern crate run_make_support;
+
+use run_make_support::{aux_build, tmp_dir};
+use std::fs;
+#[cfg(unix)]
+use std::os::unix::fs::PermissionsExt;
+use std::path::Path;
+
+fn main() {
+    #[cfg(unix)]
+    unsafe {
+        libc::umask(0o002);
+    }
+
+    aux_build().arg("foo.rs").run();
+    verify(&tmp_dir().join("libfoo.rlib"));
+}
+
+fn verify(path: &Path) {
+    let perm = fs::metadata(path).unwrap().permissions();
+
+    assert!(!perm.readonly());
+
+    // Check that the file is readable for everyone
+    #[cfg(unix)]
+    assert_eq!(perm.mode(), 0o100664);
+}
diff --git a/tests/ui/abi/anon-extern-mod.rs b/tests/ui/abi/anon-extern-mod.rs
index a424f93f637..bb3739bc4af 100644
--- a/tests/ui/abi/anon-extern-mod.rs
+++ b/tests/ui/abi/anon-extern-mod.rs
@@ -1,13 +1,9 @@
 //@ run-pass
 //@ pretty-expanded FIXME #23616
 
-#![feature(rustc_private)]
-
-extern crate libc;
-
 #[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
-    fn rust_get_test_int() -> libc::intptr_t;
+    fn rust_get_test_int() -> isize;
 }
 
 pub fn main() {
diff --git a/tests/ui/abi/c-stack-as-value.rs b/tests/ui/abi/c-stack-as-value.rs
index 6ea2051b05b..401bc132b6e 100644
--- a/tests/ui/abi/c-stack-as-value.rs
+++ b/tests/ui/abi/c-stack-as-value.rs
@@ -1,14 +1,10 @@
 //@ run-pass
 //@ pretty-expanded FIXME #23616
 
-#![feature(rustc_private)]
-
 mod rustrt {
-    extern crate libc;
-
     #[link(name = "rust_test_helpers", kind = "static")]
     extern "C" {
-        pub fn rust_get_test_int() -> libc::intptr_t;
+        pub fn rust_get_test_int() -> isize;
     }
 }
 
diff --git a/tests/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/tests/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
index 5cbf8093c5c..559c40546a8 100644
--- a/tests/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/tests/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
@@ -1,9 +1,6 @@
 #![crate_name = "anonexternmod"]
-#![feature(rustc_private)]
-
-extern crate libc;
 
 #[link(name = "rust_test_helpers", kind = "static")]
 extern "C" {
-    pub fn rust_get_test_int() -> libc::intptr_t;
+    pub fn rust_get_test_int() -> isize;
 }
diff --git a/tests/ui/abi/foreign/auxiliary/foreign_lib.rs b/tests/ui/abi/foreign/auxiliary/foreign_lib.rs
index 3c649b778bd..74a95b96e9f 100644
--- a/tests/ui/abi/foreign/auxiliary/foreign_lib.rs
+++ b/tests/ui/abi/foreign/auxiliary/foreign_lib.rs
@@ -1,28 +1,28 @@
 #![crate_name = "foreign_lib"]
-#![feature(rustc_private)]
 
 pub mod rustrt {
-    extern crate libc;
-
     #[link(name = "rust_test_helpers", kind = "static")]
     extern "C" {
-        pub fn rust_get_test_int() -> libc::intptr_t;
+        pub fn rust_get_test_int() -> isize;
     }
 }
 
 pub mod rustrt2 {
-    extern crate libc;
-
     extern "C" {
-        pub fn rust_get_test_int() -> libc::intptr_t;
+        pub fn rust_get_test_int() -> isize;
     }
 }
 
 pub mod rustrt3 {
-    // Different type, but same ABI (on all supported platforms).
-    // Ensures that we don't ICE or trigger LLVM asserts when
-    // importing the same symbol under different types.
-    // See https://github.com/rust-lang/rust/issues/32740.
+    // The point of this test is to ensure that we don't ICE or trigger LLVM asserts when importing
+    // the same symbol with different types. This is not really possible to test portably; there is
+    // no different signature we can come up with that is different to LLVM but which for sure has
+    // the same behavior on all platforms. The signed-ness of integers is ignored by LLVM as well
+    // as pointee types. So the only ways to make our signatures differ are to use
+    // differently-sized integers which is definitely an ABI mismatch, or to rely on pointers and
+    // isize/usize having the same ABI, which is wrong on CHERI and probably other niche platforms.
+    // If this test causes you trouble, please file an issue.
+    // See https://github.com/rust-lang/rust/issues/32740 for the bug that prompted this test.
     extern "C" {
         pub fn rust_get_test_int() -> *const u8;
     }
@@ -32,6 +32,6 @@ pub fn local_uses() {
     unsafe {
         let x = rustrt::rust_get_test_int();
         assert_eq!(x, rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, rustrt3::rust_get_test_int());
+        assert_eq!(x as *const u8, rustrt3::rust_get_test_int());
     }
 }
diff --git a/tests/ui/abi/foreign/foreign-dupe.rs b/tests/ui/abi/foreign/foreign-dupe.rs
index 1b6df0892c7..3473d436cb4 100644
--- a/tests/ui/abi/foreign/foreign-dupe.rs
+++ b/tests/ui/abi/foreign/foreign-dupe.rs
@@ -4,13 +4,12 @@
 // Check that we can still call duplicated extern (imported) functions
 // which were declared in another crate. See issues #32740 and #32783.
 
-
 extern crate foreign_lib;
 
 pub fn main() {
     unsafe {
         let x = foreign_lib::rustrt::rust_get_test_int();
         assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int());
-        assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int());
+        assert_eq!(x as *const u8, foreign_lib::rustrt3::rust_get_test_int());
     }
 }
diff --git a/tests/ui/abi/foreign/foreign-no-abi.rs b/tests/ui/abi/foreign/foreign-no-abi.rs
deleted file mode 100644
index 4ac47df29a7..00000000000
--- a/tests/ui/abi/foreign/foreign-no-abi.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ run-pass
-// ABI is cdecl by default
-
-//@ pretty-expanded FIXME #23616
-
-#![feature(rustc_private)]
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers", kind = "static")]
-    extern "C" {
-        pub fn rust_get_test_int() -> libc::intptr_t;
-    }
-}
-
-pub fn main() {
-    unsafe {
-        rustrt::rust_get_test_int();
-    }
-}
diff --git a/tests/ui/attributes/item-attributes.rs b/tests/ui/attributes/item-attributes.rs
index 7fe7fdd9758..daab1bccb2c 100644
--- a/tests/ui/attributes/item-attributes.rs
+++ b/tests/ui/attributes/item-attributes.rs
@@ -148,7 +148,7 @@ mod test_foreign_items {
             #![rustc_dummy]
 
             #[rustc_dummy]
-            fn rust_get_test_int() -> u32;
+            fn rust_get_test_int() -> isize;
         }
     }
 }
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
index 8426748fd52..fd54fe2b0e8 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
@@ -22,8 +22,7 @@ struct MyType {
 impl MyTrait<MyType> for MyType {
 //~^ ERROR E0119
     fn get(&self) -> usize { (*self).clone() }
-    //~^ ERROR incompatible type
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
 }
 
 fn main() { }
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
index 0653009409c..fc6250dfa02 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
@@ -7,23 +7,6 @@ LL | impl<T> MyTrait<T> for T {
 LL | impl MyTrait<MyType> for MyType {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
 
-error[E0053]: method `get` has an incompatible type for trait
-  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:22
-   |
-LL |     fn get(&self) -> usize { (*self).clone() }
-   |                      ^^^^^
-   |                      |
-   |                      expected `MyType`, found `usize`
-   |                      help: change the output type to match the trait: `MyType`
-   |
-note: type in trait
-  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:8:22
-   |
-LL |     fn get(&self) -> T;
-   |                      ^
-   = note: expected signature `fn(&MyType) -> MyType`
-              found signature `fn(&MyType) -> usize`
-
 error[E0308]: mismatched types
   --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:30
    |
@@ -32,7 +15,7 @@ LL |     fn get(&self) -> usize { (*self).clone() }
    |                      |
    |                      expected `usize` because of return type
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0053, E0119, E0308.
-For more information about an error, try `rustc --explain E0053`.
+Some errors have detailed explanations: E0119, E0308.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs
index 9c96958f21a..aee6647a788 100644
--- a/tests/ui/coherence/coherence-orphan.rs
+++ b/tests/ui/coherence/coherence-orphan.rs
@@ -9,13 +9,10 @@ struct TheType;
 
 impl TheTrait<usize> for isize {}
 //~^ ERROR E0117
-//~| ERROR not all trait items implemented
 
 impl TheTrait<TheType> for isize {}
-//~^ ERROR not all trait items implemented
 
 impl TheTrait<isize> for TheType {}
-//~^ ERROR not all trait items implemented
 
 impl !Send for Vec<isize> {} //~ ERROR E0117
 
diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr
index 48843f7cd18..f6ffae34290 100644
--- a/tests/ui/coherence/coherence-orphan.stderr
+++ b/tests/ui/coherence/coherence-orphan.stderr
@@ -10,32 +10,8 @@ LL | impl TheTrait<usize> for isize {}
    |
    = note: define and implement a trait or new type instead
 
-error[E0046]: not all trait items implemented, missing: `the_fn`
-  --> $DIR/coherence-orphan.rs:10:1
-   |
-LL | impl TheTrait<usize> for isize {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
-   |
-   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
-
-error[E0046]: not all trait items implemented, missing: `the_fn`
-  --> $DIR/coherence-orphan.rs:14:1
-   |
-LL | impl TheTrait<TheType> for isize {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
-   |
-   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
-
-error[E0046]: not all trait items implemented, missing: `the_fn`
-  --> $DIR/coherence-orphan.rs:17:1
-   |
-LL | impl TheTrait<isize> for TheType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
-   |
-   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
-
 error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
-  --> $DIR/coherence-orphan.rs:20:1
+  --> $DIR/coherence-orphan.rs:17:1
    |
 LL | impl !Send for Vec<isize> {}
    | ^^^^^^^^^^^^^^^----------
@@ -45,7 +21,6 @@ LL | impl !Send for Vec<isize> {}
    |
    = note: define and implement a trait or new type instead
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0046, E0117.
-For more information about an error, try `rustc --explain E0046`.
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/error-codes/E0117.rs b/tests/ui/error-codes/E0117.rs
index 32b9863806c..406d24e3666 100644
--- a/tests/ui/error-codes/E0117.rs
+++ b/tests/ui/error-codes/E0117.rs
@@ -1,5 +1,4 @@
 impl Drop for u32 {} //~ ERROR E0117
 //~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
-//~| ERROR not all trait items implemented
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0117.stderr b/tests/ui/error-codes/E0117.stderr
index 058a64b20d1..f144aa9f72c 100644
--- a/tests/ui/error-codes/E0117.stderr
+++ b/tests/ui/error-codes/E0117.stderr
@@ -15,15 +15,7 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums,
 LL | impl Drop for u32 {}
    |               ^^^ must be a struct, enum, or union in the current crate
 
-error[E0046]: not all trait items implemented, missing: `drop`
-  --> $DIR/E0117.rs:1:1
-   |
-LL | impl Drop for u32 {}
-   | ^^^^^^^^^^^^^^^^^ missing `drop` in implementation
-   |
-   = help: implement the missing item: `fn drop(&mut self) { todo!() }`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0046, E0117, E0120.
-For more information about an error, try `rustc --explain E0046`.
+Some errors have detailed explanations: E0117, E0120.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/extern/issue-1251.rs b/tests/ui/extern/issue-1251.rs
index da2b8be7bc1..5581bddaddc 100644
--- a/tests/ui/extern/issue-1251.rs
+++ b/tests/ui/extern/issue-1251.rs
@@ -2,13 +2,10 @@
 #![allow(unused_attributes)]
 #![allow(dead_code)]
 //@ pretty-expanded FIXME #23616
-#![feature(rustc_private)]
 
 mod rustrt {
-    extern crate libc;
-
     extern "C" {
-        pub fn rust_get_test_int() -> libc::intptr_t;
+        pub fn rust_get_test_int() -> isize;
     }
 }
 
diff --git a/tests/ui/inference/dont-collect-stmts-from-parent-body.rs b/tests/ui/inference/dont-collect-stmts-from-parent-body.rs
new file mode 100644
index 00000000000..635fe74b867
--- /dev/null
+++ b/tests/ui/inference/dont-collect-stmts-from-parent-body.rs
@@ -0,0 +1,15 @@
+// issue: rust-lang/rust#124022
+
+struct Type<T>;
+//~^ ERROR type parameter `T` is never used
+
+fn main() {
+    {
+        impl<T> Type<T> {
+            fn new() -> Type<T> {
+                Type
+                //~^ ERROR type annotations needed
+            }
+        }
+    };
+}
diff --git a/tests/ui/inference/dont-collect-stmts-from-parent-body.stderr b/tests/ui/inference/dont-collect-stmts-from-parent-body.stderr
new file mode 100644
index 00000000000..f82527273fb
--- /dev/null
+++ b/tests/ui/inference/dont-collect-stmts-from-parent-body.stderr
@@ -0,0 +1,24 @@
+error[E0392]: type parameter `T` is never used
+  --> $DIR/dont-collect-stmts-from-parent-body.rs:3:13
+   |
+LL | struct Type<T>;
+   |             ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0282]: type annotations needed
+  --> $DIR/dont-collect-stmts-from-parent-body.rs:10:17
+   |
+LL |                 Type
+   |                 ^^^^ cannot infer type of the type parameter `T` declared on the struct `Type`
+   |
+help: consider specifying the generic argument
+   |
+LL |                 Type::<T>
+   |                     +++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0392.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/issues/issue-67535.rs b/tests/ui/issues/issue-67535.rs
index 153b95a1674..24f50621310 100644
--- a/tests/ui/issues/issue-67535.rs
+++ b/tests/ui/issues/issue-67535.rs
@@ -2,21 +2,21 @@ fn main() {}
 
 impl std::ops::AddAssign for () {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: ()) -> () { //~ ERROR incompatible type
+    fn add_assign(&self, other: ()) -> () {
         ()
     }
 }
 
 impl std::ops::AddAssign for [(); 1] {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: [(); 1]) -> [(); 1] { //~ ERROR incompatible type
+    fn add_assign(&self, other: [(); 1]) -> [(); 1] {
         [()]
     }
 }
 
 impl std::ops::AddAssign for &[u8] {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: &[u8]) -> &[u8] { //~ ERROR incompatible type
+    fn add_assign(&self, other: &[u8]) -> &[u8] {
         self
     }
 }
diff --git a/tests/ui/issues/issue-67535.stderr b/tests/ui/issues/issue-67535.stderr
index c8bde2cb88c..4d7a02a5096 100644
--- a/tests/ui/issues/issue-67535.stderr
+++ b/tests/ui/issues/issue-67535.stderr
@@ -34,43 +34,6 @@ LL | impl std::ops::AddAssign for &[u8] {
    |
    = note: define and implement a trait or new type instead
 
-error[E0053]: method `add_assign` has an incompatible type for trait
-  --> $DIR/issue-67535.rs:5:19
-   |
-LL |     fn add_assign(&self, other: ()) -> () {
-   |                   ^^^^^
-   |                   |
-   |                   types differ in mutability
-   |                   help: change the self-receiver type to match the trait: `&mut self`
-   |
-   = note: expected signature `fn(&mut (), ())`
-              found signature `fn(&(), ())`
-
-error[E0053]: method `add_assign` has an incompatible type for trait
-  --> $DIR/issue-67535.rs:12:19
-   |
-LL |     fn add_assign(&self, other: [(); 1]) -> [(); 1] {
-   |                   ^^^^^
-   |                   |
-   |                   types differ in mutability
-   |                   help: change the self-receiver type to match the trait: `&mut self`
-   |
-   = note: expected signature `fn(&mut _, _)`
-              found signature `fn(&_, _) -> [(); 1]`
-
-error[E0053]: method `add_assign` has an incompatible type for trait
-  --> $DIR/issue-67535.rs:19:19
-   |
-LL |     fn add_assign(&self, other: &[u8]) -> &[u8] {
-   |                   ^^^^^
-   |                   |
-   |                   types differ in mutability
-   |                   help: change the self-receiver type to match the trait: `&mut self`
-   |
-   = note: expected signature `fn(&mut &_, &_)`
-              found signature `fn(&&_, &_) -> &[u8]`
-
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0053, E0117.
-For more information about an error, try `rustc --explain E0053`.
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs
index d856b06e260..0009ed0e34c 100644
--- a/tests/ui/weird-exprs.rs
+++ b/tests/ui/weird-exprs.rs
@@ -256,6 +256,20 @@ fn fake_macros() -> impl std::fmt::Debug {
     }
 }
 
+fn fish_fight() {
+    trait Rope {
+        fn _____________<U>(_: Self, _: U) where Self: Sized {}
+    }
+
+    struct T;
+
+    impl Rope for T {}
+
+    fn tug_o_war(_: impl Fn(T, T)) {}
+
+    tug_o_war(<T>::_____________::<T>);
+}
+
 pub fn main() {
     strange();
     funny();
@@ -284,4 +298,5 @@ pub fn main() {
     infcx();
     return_already();
     fake_macros();
+    fish_fight();
 }
diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs
new file mode 100644
index 00000000000..8054eb7c594
--- /dev/null
+++ b/tests/ui/wf/conflicting-impls.rs
@@ -0,0 +1,20 @@
+//@ edition: 2021
+
+struct Ty;
+
+impl TryFrom<Ty> for u8 {
+    type Error = Ty;
+    fn try_from(_: Ty) -> Result<Self, Self::Error> {
+        loop {}
+    }
+}
+
+impl TryFrom<Ty> for u8 {
+    //~^ ERROR conflicting implementations of trait
+    type Error = Ty;
+    fn try_from(_: Ty) -> Result<Self, Self::Error> {
+        loop {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr
new file mode 100644
index 00000000000..d31ae17aa8f
--- /dev/null
+++ b/tests/ui/wf/conflicting-impls.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `TryFrom<Ty>` for type `u8`
+  --> $DIR/conflicting-impls.rs:12:1
+   |
+LL | impl TryFrom<Ty> for u8 {
+   | ----------------------- first implementation here
+...
+LL | impl TryFrom<Ty> for u8 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/triagebot.toml b/triagebot.toml
index 731642ca74c..66b8f44d688 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -417,6 +417,54 @@ message_on_remove = "Issue #{number}'s prioritization request has been removed."
 message_on_close = "Issue #{number} has been closed while requested for prioritization."
 message_on_reopen = "Issue #{number} has been reopened."
 
+# FIXME: Patch triagebot to support `notify-zulip.<label>` getting mapped to an array of actions.
+#        At the moment, the beta-nominated+T-rustdoc action fully occupies the beta-nominated slot
+#        preventing others from adding more beta-nominated actions.
+[notify-zulip."beta-nominated"]
+required_labels = ["T-rustdoc"]
+zulip_stream = 266220 # #t-rustdoc
+topic = "beta-nominated: #{number}"
+# Zulip polls may not be preceded by any other text and pings & short links inside
+# the title of a poll don't get recognized. Therefore we need to send two messages.
+message_on_add = [
+    """\
+@*T-rustdoc* PR #{number} "{title}" has been nominated for beta backport.
+""",
+    """\
+/poll Approve beta backport of #{number}?
+approve
+decline
+don't know
+""",
+]
+message_on_remove = "PR #{number}'s beta-nomination has been removed."
+message_on_close = "PR #{number} has been closed. Thanks for participating!"
+message_on_reopen = "PR #{number} has been reopened. Pinging @*T-rustdoc*."
+
+# FIXME: Patch triagebot to support `notify-zulip.<label>` getting mapped to an array of actions.
+#        At the moment, the stable-nominated+T-rustdoc action fully occupies the stable-nominated slot
+#        preventing others from adding more stable-nominated actions.
+[notify-zulip."stable-nominated"]
+required_labels = ["T-rustdoc"]
+zulip_stream = 266220 # #t-rustdoc
+topic = "stable-nominated: #{number}"
+# Zulip polls may not be preceded by any other text and pings & short links inside
+# the title of a poll don't get recognized. Therefore we need to send two messages.
+message_on_add = [
+    """\
+@*T-rustdoc* PR #{number} "{title}" has been nominated for stable backport.
+""",
+    """\
+/poll Approve stable backport of #{number}?
+approve
+decline
+don't know
+""",
+]
+message_on_remove = "PR #{number}'s stable-nomination has been removed."
+message_on_close = "PR #{number} has been closed. Thanks for participating!"
+message_on_reopen = "PR #{number} has been reopened. Pinging @*T-rustdoc*."
+
 [notify-zulip."I-types-nominated"]
 zulip_stream = 326866 # #T-types/nominated
 topic = "#{number}: {title}"