about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-11 10:22:10 +0000
committerbors <bors@rust-lang.org>2024-03-11 10:22:10 +0000
commite919669d42dfb8950866d4cb268c5359eb3f7c54 (patch)
tree08ac6de3309dc8a896699d04b1b1739bd6e413d4
parent66396725541ac7920439876fc79cbc7b604b82e0 (diff)
parent5a3d6c91b1892806b0cdda8b03e5ceef64a1989f (diff)
downloadrust-e919669d42dfb8950866d4cb268c5359eb3f7c54.tar.gz
rust-e919669d42dfb8950866d4cb268c5359eb3f7c54.zip
Auto merge of #122331 - jhpratt:rollup-cbl8xsy, r=jhpratt
Rollup of 9 pull requests

Successful merges:

 - #121148 (Add slice::try_range)
 - #121633 (Win10: Use `GetSystemTimePreciseAsFileTime` directly)
 - #121840 (Expose the Freeze trait again (unstably) and forbid implementing it manually)
 - #121907 (skip sanity check for non-host targets in `check` builds)
 - #122002 (std::threads: revisit stack address calculation on netbsd.)
 - #122108 (Add `target.*.runner` configuration for targets)
 - #122298 (RawVec::into_box: avoid unnecessary intermediate reference)
 - #122315 (Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function.)
 - #122326 (Optimize `process_heap_alloc`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs1
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs14
-rw-r--r--compiler/rustc_lint/src/internal.rs17
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--config.example.toml11
-rw-r--r--library/alloc/src/raw_vec.rs3
-rw-r--r--library/alloc/src/slice.rs4
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/marker.rs10
-rw-r--r--library/core/src/slice/index.rs59
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs5
-rw-r--r--library/std/src/sys/pal/windows/alloc.rs55
-rw-r--r--library/std/src/sys/pal/windows/c.rs1
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt1
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs4
-rw-r--r--src/bootstrap/src/core/config/config.rs3
-rw-r--r--src/bootstrap/src/core/sanity.rs17
-rw-r--r--src/bootstrap/src/lib.rs11
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/tools/compiletest/src/common.rs6
-rw-r--r--src/tools/compiletest/src/lib.rs6
-rw-r--r--src/tools/compiletest/src/runtest.rs4
-rw-r--r--src/tools/miri/src/shims/time.rs5
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs4
-rw-r--r--src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs18
-rw-r--r--tests/run-make/min-global-align/min_global_align.rs2
-rw-r--r--tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs9
-rw-r--r--tests/rustdoc/empty-section.rs4
-rw-r--r--tests/rustdoc/synthetic_auto/basic.rs2
-rw-r--r--tests/rustdoc/synthetic_auto/manual.rs2
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.rs10
-rw-r--r--tests/ui/associated-consts/freeze.rs12
-rw-r--r--tests/ui/feature-gates/feature-gate-freeze-impls.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-freeze-impls.stderr23
-rw-r--r--tests/ui/hygiene/panic-location.rs1
-rw-r--r--tests/ui/hygiene/panic-location.run.stderr2
40 files changed, 277 insertions, 81 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 67a0d0dabea..39988cf64e5 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -8,6 +8,7 @@
     rustc_attrs,
     transparent_unions,
     auto_traits,
+    freeze_impls,
     thread_local
 )]
 #![no_core]
diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs
index cc3d647c8c8..a868471ed1d 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core.rs
@@ -1,6 +1,6 @@
 #![feature(
     no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
-    decl_macro, rustc_attrs, transparent_unions, auto_traits,
+    decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
     thread_local
 )]
 #![no_core]
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index a10f4b934ea..52421fce867 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -471,6 +471,8 @@ declare_features! (
     (unstable, fn_align, "1.53.0", Some(82232)),
     /// Support delegating implementation of functions to other already implemented functions.
     (incomplete, fn_delegation, "1.76.0", Some(118212)),
+    /// Allows impls for the Freeze trait.
+    (internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)),
     /// Allows defining gen blocks and `gen fn`.
     (unstable, gen_blocks, "1.75.0", Some(117078)),
     /// Infer generic args for both consts and types.
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index fc7a73e12be..054a3af212a 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
+use rustc_session::parse::feature_err;
 use rustc_span::{sym, ErrorGuaranteed};
 use rustc_trait_selection::traits;
 
@@ -49,6 +50,19 @@ fn enforce_trait_manually_implementable(
 ) -> Result<(), ErrorGuaranteed> {
     let impl_header_span = tcx.def_span(impl_def_id);
 
+    if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
+        if !tcx.features().freeze_impls {
+            feature_err(
+                &tcx.sess,
+                sym::freeze_impls,
+                impl_header_span,
+                "explicit impls for the `Freeze` trait are not permitted",
+            )
+            .with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
+            .emit();
+        }
+    }
+
     // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
     if trait_def.deny_explicit_impl {
         let trait_name = tcx.item_name(trait_def_id);
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 0872a8a2095..153d91ce28c 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -409,9 +409,8 @@ impl LateLintPass<'_> for Diagnostics {
             }
         };
 
-        // Does the callee have a `impl Into<{D,Subd}iagMessage>` parameter? (There should be at
-        // most one.)
-        let mut impl_into_diagnostic_message_param = None;
+        // Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
+        let mut impl_into_diagnostic_message_params = vec![];
         let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
         let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
         for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
@@ -425,20 +424,14 @@ impl LateLintPass<'_> for Diagnostics {
                         && let ty1 = trait_ref.args.type_at(1)
                         && is_diag_message(ty1)
                     {
-                        if impl_into_diagnostic_message_param.is_some() {
-                            cx.tcx.dcx().span_bug(
-                                span,
-                                "can't handle multiple `impl Into<{D,Sub}iagMessage>` params",
-                            );
-                        }
-                        impl_into_diagnostic_message_param = Some((i, p.name));
+                        impl_into_diagnostic_message_params.push((i, p.name));
                     }
                 }
             }
         }
 
         // Is the callee interesting?
-        if !has_attr && impl_into_diagnostic_message_param.is_none() {
+        if !has_attr && impl_into_diagnostic_message_params.is_empty() {
             return;
         }
 
@@ -481,7 +474,7 @@ impl LateLintPass<'_> for Diagnostics {
         // Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
         // with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
         // `UNTRANSLATABLE_DIAGNOSTIC` lint.
-        if let Some((param_i, param_i_p_name)) = impl_into_diagnostic_message_param {
+        for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
             // Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
             let arg_ty = call_tys[param_i];
             let is_translatable = is_diag_message(arg_ty)
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a8426d78cac..f592c1d3dd3 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -864,6 +864,7 @@ symbols! {
         format_placeholder,
         format_unsafe_arg,
         freeze,
+        freeze_impls,
         freg,
         frem_algebraic,
         frem_fast,
diff --git a/config.example.toml b/config.example.toml
index c1939933850..4fbdccba911 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -842,6 +842,17 @@
 # See that option for more info.
 #codegen-backends = rust.codegen-backends (array)
 
+# This is a "runner" to pass to `compiletest` when executing tests. Tests will
+# execute this tool where the binary-to-test is passed as an argument. Can
+# be useful for situations such as when WebAssembly is being tested and a
+# runtime needs to be configured. This value is similar to
+# Cargo's `CARGO_$target_RUNNER` configuration.
+#
+# This configuration is a space-separated list of arguments so `foo bar` would
+# execute the program `foo` with the first argument as `bar` and the second
+# argument as the test binary.
+#runner = <none> (string)
+
 # =============================================================================
 # Distribution options
 #
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index ace73c0fdaa..0ee293db73a 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -5,7 +5,6 @@ use core::cmp;
 use core::hint;
 use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
 use core::ptr::{self, NonNull, Unique};
-use core::slice;
 
 #[cfg(not(no_global_oom_handling))]
 use crate::alloc::handle_alloc_error;
@@ -192,7 +191,7 @@ impl<T, A: Allocator> RawVec<T, A> {
 
         let me = ManuallyDrop::new(self);
         unsafe {
-            let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
+            let slice = ptr::slice_from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
             Box::from_raw_in(slice, ptr::read(&me.alloc))
         }
     }
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index f4e392760c8..21d5dce04a0 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -33,8 +33,6 @@ use crate::vec::Vec;
 #[cfg(test)]
 mod tests;
 
-#[unstable(feature = "slice_range", issue = "76393")]
-pub use core::slice::range;
 #[unstable(feature = "array_chunks", issue = "74985")]
 pub use core::slice::ArrayChunks;
 #[unstable(feature = "array_chunks", issue = "74985")]
@@ -51,6 +49,8 @@ pub use core::slice::{from_mut, from_ref};
 pub use core::slice::{from_mut_ptr_range, from_ptr_range};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
+#[unstable(feature = "slice_range", issue = "76393")]
+pub use core::slice::{range, try_range};
 #[stable(feature = "slice_group_by", since = "1.77.0")]
 pub use core::slice::{ChunkBy, ChunkByMut};
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 0f7885769c2..6bcf7c13e64 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -204,6 +204,7 @@
 // tidy-alphabetical-start
 #![cfg_attr(bootstrap, feature(diagnostic_namespace))]
 #![cfg_attr(bootstrap, feature(platform_intrinsics))]
+#![cfg_attr(not(bootstrap), feature(freeze_impls))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 2e22129d7b6..a56a2578c22 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -810,15 +810,21 @@ pub trait DiscriminantKind {
     type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
 }
 
-/// Compiler-internal trait used to determine whether a type contains
+/// Used to determine whether a type contains
 /// any `UnsafeCell` internally, but not through an indirection.
 /// This affects, for example, whether a `static` of that type is
 /// placed in read-only static memory or writable static memory.
+/// This can be used to declare that a constant with a generic type
+/// will not contain interior mutability, and subsequently allow
+/// placing the constant behind references.
 #[lang = "freeze"]
-pub(crate) unsafe auto trait Freeze {}
+#[unstable(feature = "freeze", issue = "121675")]
+pub unsafe auto trait Freeze {}
 
+#[unstable(feature = "freeze", issue = "121675")]
 impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
 marker_impls! {
+    #[unstable(feature = "freeze", issue = "121675")]
     unsafe Freeze for
         {T: ?Sized} PhantomData<T>,
         {T: ?Sized} *const T,
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 33c2769591d..64f1f360821 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -704,8 +704,7 @@ where
 {
     let len = bounds.end;
 
-    let start: ops::Bound<&usize> = range.start_bound();
-    let start = match start {
+    let start = match range.start_bound() {
         ops::Bound::Included(&start) => start,
         ops::Bound::Excluded(start) => {
             start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
@@ -713,8 +712,7 @@ where
         ops::Bound::Unbounded => 0,
     };
 
-    let end: ops::Bound<&usize> = range.end_bound();
-    let end = match end {
+    let end = match range.end_bound() {
         ops::Bound::Included(end) => {
             end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
         }
@@ -732,6 +730,59 @@ where
     ops::Range { start, end }
 }
 
+/// Performs bounds-checking of a range without panicking.
+///
+/// This is a version of [`range`] that returns [`None`] instead of panicking.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(slice_range)]
+///
+/// use std::slice;
+///
+/// let v = [10, 40, 30];
+/// assert_eq!(Some(1..2), slice::try_range(1..2, ..v.len()));
+/// assert_eq!(Some(0..2), slice::try_range(..2, ..v.len()));
+/// assert_eq!(Some(1..3), slice::try_range(1.., ..v.len()));
+/// ```
+///
+/// Returns [`None`] when [`Index::index`] would panic:
+///
+/// ```
+/// #![feature(slice_range)]
+///
+/// use std::slice;
+///
+/// assert_eq!(None, slice::try_range(2..1, ..3));
+/// assert_eq!(None, slice::try_range(1..4, ..3));
+/// assert_eq!(None, slice::try_range(1..=usize::MAX, ..3));
+/// ```
+///
+/// [`Index::index`]: ops::Index::index
+#[unstable(feature = "slice_range", issue = "76393")]
+#[must_use]
+pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
+where
+    R: ops::RangeBounds<usize>,
+{
+    let len = bounds.end;
+
+    let start = match range.start_bound() {
+        ops::Bound::Included(&start) => start,
+        ops::Bound::Excluded(start) => start.checked_add(1)?,
+        ops::Bound::Unbounded => 0,
+    };
+
+    let end = match range.end_bound() {
+        ops::Bound::Included(end) => end.checked_add(1)?,
+        ops::Bound::Excluded(&end) => end,
+        ops::Bound::Unbounded => len,
+    };
+
+    if start > end || end > len { None } else { Some(ops::Range { start, end }) }
+}
+
 /// Convert pair of `ops::Bound`s into `ops::Range` without performing any bounds checking and (in debug) overflow checking
 pub(crate) fn into_range_unchecked(
     len: usize,
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 2dd01ba33af..4a574bf0347 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -91,7 +91,7 @@ pub use sort::heapsort;
 pub use index::SliceIndex;
 
 #[unstable(feature = "slice_range", issue = "76393")]
-pub use index::range;
+pub use index::{range, try_range};
 
 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
 pub use ascii::EscapeAscii;
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 2af6382f3da..6520ca9fc48 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -806,9 +806,9 @@ pub mod guard {
     #[cfg(any(
         target_os = "android",
         target_os = "freebsd",
+        target_os = "netbsd",
         target_os = "hurd",
         target_os = "linux",
-        target_os = "netbsd",
         target_os = "l4re"
     ))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
@@ -911,9 +911,10 @@ pub mod guard {
                         }
                     }) * page_size;
             Some(guard)
-        } else if cfg!(target_os = "openbsd") {
+        } else if cfg!(any(target_os = "openbsd", target_os = "netbsd")) {
             // OpenBSD stack already includes a guard page, and stack is
             // immutable.
+            // NetBSD stack includes the guard page.
             //
             // We'll just note where we expect rlimit to start
             // faulting, so our handler can report "stack overflow", and
diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs
index 270eca37b14..681d1a5efe9 100644
--- a/library/std/src/sys/pal/windows/alloc.rs
+++ b/library/std/src/sys/pal/windows/alloc.rs
@@ -6,6 +6,7 @@ use crate::ptr;
 use crate::sync::atomic::{AtomicPtr, Ordering};
 use crate::sys::c;
 use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
+use core::mem::MaybeUninit;
 
 #[cfg(test)]
 mod tests;
@@ -94,29 +95,30 @@ static HEAP: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
 // a non-null handle returned by `GetProcessHeap`.
 #[inline]
 fn init_or_get_process_heap() -> c::HANDLE {
-    let heap = HEAP.load(Ordering::Relaxed);
-    if core::intrinsics::unlikely(heap.is_null()) {
-        // `HEAP` has not yet been successfully initialized
-        let heap = unsafe { GetProcessHeap() };
-        if !heap.is_null() {
-            // SAFETY: No locking is needed because within the same process,
-            // successful calls to `GetProcessHeap` will always return the same value, even on different threads.
-            HEAP.store(heap, Ordering::Release);
-
-            // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
-            heap
-        } else {
-            // Could not get the current process heap.
-            ptr::null_mut()
-        }
-    } else {
+    // `HEAP` has not yet been successfully initialized
+    let heap = unsafe { GetProcessHeap() };
+    if !heap.is_null() {
+        // SAFETY: No locking is needed because within the same process,
+        // successful calls to `GetProcessHeap` will always return the same value, even on different threads.
+        HEAP.store(heap, Ordering::Release);
+
         // SAFETY: `HEAP` contains a non-null handle returned by `GetProcessHeap`
         heap
+    } else {
+        // Could not get the current process heap.
+        ptr::null_mut()
     }
 }
 
+/// This is outlined from `process_heap_alloc` so that `process_heap_alloc`
+/// does not need any stack allocations.
 #[inline(never)]
-fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
+#[cold]
+extern "C" fn process_heap_init_and_alloc(
+    _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`
+    flags: c::DWORD,
+    dwBytes: c::SIZE_T,
+) -> c::LPVOID {
     let heap = init_or_get_process_heap();
     if core::intrinsics::unlikely(heap.is_null()) {
         return ptr::null_mut();
@@ -125,6 +127,21 @@ fn process_heap_alloc(flags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID {
     unsafe { HeapAlloc(heap, flags, dwBytes) }
 }
 
+#[inline(never)]
+fn process_heap_alloc(
+    _heap: MaybeUninit<c::HANDLE>, // We pass this argument to match the ABI of `HeapAlloc`,
+    flags: c::DWORD,
+    dwBytes: c::SIZE_T,
+) -> c::LPVOID {
+    let heap = HEAP.load(Ordering::Relaxed);
+    if core::intrinsics::likely(!heap.is_null()) {
+        // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`.
+        unsafe { HeapAlloc(heap, flags, dwBytes) }
+    } else {
+        process_heap_init_and_alloc(MaybeUninit::uninit(), flags, dwBytes)
+    }
+}
+
 // Get a non-null handle to the default heap of the current process.
 // SAFETY: `HEAP` must have been successfully initialized.
 #[inline]
@@ -148,12 +165,12 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 {
 
     if layout.align() <= MIN_ALIGN {
         // The returned pointer points to the start of an allocated block.
-        process_heap_alloc(flags, layout.size()) as *mut u8
+        process_heap_alloc(MaybeUninit::uninit(), flags, layout.size()) as *mut u8
     } else {
         // Allocate extra padding in order to be able to satisfy the alignment.
         let total = layout.align() + layout.size();
 
-        let ptr = process_heap_alloc(flags, total) as *mut u8;
+        let ptr = process_heap_alloc(MaybeUninit::uninit(), flags, total) as *mut u8;
         if ptr.is_null() {
             // Allocation has failed.
             return ptr::null_mut();
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 2fc6598d876..1c828bac4b6 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -344,6 +344,7 @@ compat_fn_with_fallback! {
 
     // >= Win8 / Server 2012
     // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
+    #[cfg(target_vendor = "win7")]
     pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
         GetSystemTimeAsFileTime(lpsystemtimeasfiletime)
     }
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 7667f761106..849e64ac591 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2476,6 +2476,7 @@ Windows.Win32.System.Pipes.PIPE_WAIT
 Windows.Win32.System.SystemInformation.GetSystemDirectoryW
 Windows.Win32.System.SystemInformation.GetSystemInfo
 Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
+Windows.Win32.System.SystemInformation.GetSystemTimePreciseAsFileTime
 Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
 Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
 Windows.Win32.System.SystemInformation.SYSTEM_INFO
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 7b751079afb..baaa8257d84 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -346,6 +346,10 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
+    pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
+}
+#[link(name = "kernel32")]
+extern "system" {
     pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
 }
 #[link(name = "kernel32")]
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 58bc3791369..248d831b6e3 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1971,6 +1971,8 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
 
         if builder.remote_tested(target) {
             cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
+        } else if let Some(tool) = builder.runner(target) {
+            cmd.arg("--runner").arg(tool);
         }
 
         if suite != "mir-opt" {
@@ -2523,6 +2525,8 @@ fn prepare_cargo_test(
             format!("CARGO_TARGET_{}_RUNNER", envify(&target.triple)),
             format!("{} run 0", builder.tool_exe(Tool::RemoteTestClient).display()),
         );
+    } else if let Some(tool) = builder.runner(target) {
+        cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target.triple)), tool);
     }
 
     cargo
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 4766f9d426c..683e0a4302f 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -581,6 +581,7 @@ pub struct Target {
     pub musl_libdir: Option<PathBuf>,
     pub wasi_root: Option<PathBuf>,
     pub qemu_rootfs: Option<PathBuf>,
+    pub runner: Option<String>,
     pub no_std: bool,
     pub codegen_backends: Option<Vec<String>>,
 }
@@ -1144,6 +1145,7 @@ define_config! {
         qemu_rootfs: Option<String> = "qemu-rootfs",
         no_std: Option<bool> = "no-std",
         codegen_backends: Option<Vec<String>> = "codegen-backends",
+        runner: Option<String> = "runner",
     }
 }
 
@@ -1864,6 +1866,7 @@ impl Config {
                 target.musl_libdir = cfg.musl_libdir.map(PathBuf::from);
                 target.wasi_root = cfg.wasi_root.map(PathBuf::from);
                 target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from);
+                target.runner = cfg.runner;
                 target.sanitizers = cfg.sanitizers;
                 target.profiler = cfg.profiler;
                 target.rpath = cfg.rpath;
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 1dce8d8ac71..e03b1e17908 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -15,6 +15,7 @@ use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
 
+use crate::builder::Kind;
 use crate::core::config::Target;
 use crate::utils::helpers::output;
 use crate::Build;
@@ -64,6 +65,8 @@ pub fn check(build: &mut Build) {
     let mut skip_target_sanity =
         env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some_and(|s| s == "1" || s == "true");
 
+    skip_target_sanity |= build.config.cmd.kind() == Kind::Check;
+
     // Skip target sanity checks when we are doing anything with mir-opt tests or Miri
     let skipped_paths = [OsStr::new("mir-opt"), OsStr::new("miri")];
     skip_target_sanity |= build.config.paths.iter().any(|path| {
@@ -169,11 +172,8 @@ than building it.
             continue;
         }
 
-        // Some environments don't want or need these tools, such as when testing Miri.
-        // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
-        // checks, and have a regular flag for skipping the latter. Also see
-        // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
-        if skip_target_sanity {
+        // skip check for cross-targets
+        if skip_target_sanity && target != &build.build {
             continue;
         }
 
@@ -215,11 +215,8 @@ than building it.
             panic!("All the *-none-* and nvptx* targets are no-std targets")
         }
 
-        // Some environments don't want or need these tools, such as when testing Miri.
-        // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
-        // checks, and have a regular flag for skipping the latter. Also see
-        // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
-        if skip_target_sanity {
+        // skip check for cross-targets
+        if skip_target_sanity && target != &build.build {
             continue;
         }
 
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 10c13fecbf3..938b95cc60e 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -1354,6 +1354,17 @@ impl Build {
             || env::var_os("TEST_DEVICE_ADDR").is_some()
     }
 
+    /// Returns an optional "runner" to pass to `compiletest` when executing
+    /// test binaries.
+    ///
+    /// An example of this would be a WebAssembly runtime when testing the wasm
+    /// targets.
+    fn runner(&self, target: TargetSelection) -> Option<String> {
+        let target = self.config.target_config.get(&target)?;
+        let runner = target.runner.as_ref()?;
+        Some(runner.to_owned())
+    }
+
     /// Returns the root of the "rootfs" image that this target will be using,
     /// if one was configured.
     ///
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index d166b84e51f..a348fa35841 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -141,4 +141,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "A new `boostrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.",
     },
+    ChangeInfo {
+        change_id: 122108,
+        severity: ChangeSeverity::Info,
+        summary: "a new `target.*.runner` option is available to specify a wrapper executable required to run tests for a target",
+    },
 ];
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 06d8f099c33..78246136f2a 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -266,8 +266,10 @@ pub struct Config {
     pub logfile: Option<PathBuf>,
 
     /// A command line to prefix program execution with,
-    /// for running under valgrind
-    pub runtool: Option<String>,
+    /// for running under valgrind for example.
+    ///
+    /// Similar to `CARGO_*_RUNNER` configuration.
+    pub runner: Option<String>,
 
     /// Flags to pass to the compiler when building for the host
     pub host_rustcflags: Vec<String>,
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index b32a5a4bf1a..ef02e7fcb4a 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -86,7 +86,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .optflag("", "exact", "filters match exactly")
         .optopt(
             "",
-            "runtool",
+            "runner",
             "supervisor program to run tests under \
              (eg. emulator, valgrind)",
             "PROGRAM",
@@ -256,7 +256,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
             _ => panic!("unknown `--run` option `{}` given", mode),
         }),
         logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
-        runtool: matches.opt_str("runtool"),
+        runner: matches.opt_str("runner"),
         host_rustcflags: matches.opt_strs("host-rustcflags"),
         target_rustcflags: matches.opt_strs("target-rustcflags"),
         optimize_tests: matches.opt_present("optimize-tests"),
@@ -341,7 +341,7 @@ pub fn log_config(config: &Config) {
         c,
         format!("force_pass_mode: {}", opt_str(&config.force_pass_mode.map(|m| format!("{}", m))),),
     );
-    logv(c, format!("runtool: {}", opt_str(&config.runtool)));
+    logv(c, format!("runner: {}", opt_str(&config.runner)));
     logv(c, format!("host-rustcflags: {:?}", config.host_rustcflags));
     logv(c, format!("target-rustcflags: {:?}", config.target_rustcflags));
     logv(c, format!("target: {}", config.target));
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index ae0db88d873..9fd83c507ed 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -461,7 +461,7 @@ impl<'test> TestCx<'test> {
         }
 
         let mut new_config = self.config.clone();
-        new_config.runtool = new_config.valgrind_path.clone();
+        new_config.runner = new_config.valgrind_path.clone();
         let new_cx = TestCx { config: &new_config, ..*self };
         proc_res = new_cx.exec_compiled_test();
 
@@ -2647,7 +2647,7 @@ impl<'test> TestCx<'test> {
     fn make_run_args(&self) -> ProcArgs {
         // If we've got another tool to run under (valgrind),
         // then split apart its command
-        let mut args = self.split_maybe_args(&self.config.runtool);
+        let mut args = self.split_maybe_args(&self.config.runner);
 
         // If this is emscripten, then run tests under nodejs
         if self.config.target.contains("emscripten") {
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index 13ce9d119bc..4535bcf6dfe 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -110,12 +110,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     #[allow(non_snake_case, clippy::arithmetic_side_effects)]
     fn GetSystemTimeAsFileTime(
         &mut self,
+        shim_name: &str,
         LPFILETIME_op: &OpTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
-        this.assert_target_os("windows", "GetSystemTimeAsFileTime");
-        this.check_no_isolation("`GetSystemTimeAsFileTime`")?;
+        this.assert_target_os("windows", shim_name);
+        this.check_no_isolation(shim_name)?;
 
         let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
 
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 9e0baf86cbc..bb4c325b746 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -257,11 +257,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             }
 
             // Time related shims
-            "GetSystemTimeAsFileTime" => {
+            "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => {
                 #[allow(non_snake_case)]
                 let [LPFILETIME] =
                     this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
-                this.GetSystemTimeAsFileTime(LPFILETIME)?;
+                this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?;
             }
             "QueryPerformanceCounter" => {
                 #[allow(non_snake_case)]
diff --git a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
index 541e5f244db..ada9cf45375 100644
--- a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
+++ b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
@@ -92,6 +92,8 @@ unsafe impl Allocator for MyAllocator {
     }
 
     unsafe fn deallocate(&self, ptr: NonNull<u8>, _layout: Layout) {
+        // Make sure accesses via `self` don't disturb anything.
+        let _val = self.bins[0].top.get();
         // Since manually finding the corresponding bin of `ptr` is very expensive,
         // doing pointer arithmetics is preferred.
         // But this means we access `top` via `ptr` rather than `self`!
@@ -101,22 +103,30 @@ unsafe impl Allocator for MyAllocator {
         if self.thread_id == thread_id {
             unsafe { (*their_bin).push(ptr) };
         } else {
-            todo!("Deallocating from another thread")
+            todo!("Deallocating from another thread");
         }
+        // Make sure we can also still access this via `self` after the rest is done.
+        let _val = self.bins[0].top.get();
     }
 }
 
 // Make sure to involve `Box` in allocating these,
 // as that's where `noalias` may come from.
-fn v<T, A: Allocator>(t: T, a: A) -> Vec<T, A> {
+fn v1<T, A: Allocator>(t: T, a: A) -> Vec<T, A> {
     (Box::new_in([t], a) as Box<[T], A>).into_vec()
 }
+fn v2<T, A: Allocator>(t: T, a: A) -> Vec<T, A> {
+    let v = v1(t, a);
+    // There was a bug in `into_boxed_slice` that caused aliasing issues,
+    // so round-trip through that as well.
+    v.into_boxed_slice().into_vec()
+}
 
 fn main() {
     assert!(mem::size_of::<MyBin>() <= 128); // if it grows bigger, the trick to access the "header" no longer works
     let my_alloc = MyAllocator::new();
-    let a = v(1usize, &my_alloc);
-    let b = v(2usize, &my_alloc);
+    let a = v1(1usize, &my_alloc);
+    let b = v2(2usize, &my_alloc);
     assert_eq!(a[0] + 1, b[0]);
     assert_eq!(addr_of!(a[0]).wrapping_add(1), addr_of!(b[0]));
     drop((a, b));
diff --git a/tests/run-make/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs
index 135792e9372..cd1ef8cb351 100644
--- a/tests/run-make/min-global-align/min_global_align.rs
+++ b/tests/run-make/min-global-align/min_global_align.rs
@@ -1,4 +1,4 @@
-#![feature(no_core, lang_items)]
+#![feature(no_core, lang_items, freeze_impls)]
 #![crate_type = "rlib"]
 #![no_core]
 
diff --git a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs
index 0663ed5fc81..7d9133b85a6 100644
--- a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs
+++ b/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs
@@ -1,5 +1,5 @@
 // https://github.com/rust-lang/rust/issues/50159
-#![crate_name="foo"]
+#![crate_name = "foo"]
 
 pub trait Signal {
     type Item;
@@ -9,7 +9,10 @@ pub trait Signal2 {
     type Item2;
 }
 
-impl<B, C> Signal2 for B where B: Signal<Item = C> {
+impl<B, C> Signal2 for B
+where
+    B: Signal<Item = C>,
+{
     type Item2 = C;
 }
 
@@ -17,7 +20,7 @@ impl<B, C> Signal2 for B where B: Signal<Item = C> {
 // @has - '//h3[@class="code-header"]' 'impl<B> Send for Switch<B>where <B as Signal>::Item: Send'
 // @has - '//h3[@class="code-header"]' 'impl<B> Sync for Switch<B>where <B as Signal>::Item: Sync'
 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
 pub struct Switch<B: Signal> {
     pub inner: <B as Signal2>::Item2,
 }
diff --git a/tests/rustdoc/empty-section.rs b/tests/rustdoc/empty-section.rs
index d8241ab96f6..0d6afb0e444 100644
--- a/tests/rustdoc/empty-section.rs
+++ b/tests/rustdoc/empty-section.rs
@@ -1,6 +1,5 @@
 #![crate_name = "foo"]
-
-#![feature(negative_impls)]
+#![feature(negative_impls, freeze_impls, freeze)]
 
 pub struct Foo;
 
@@ -8,6 +7,7 @@ pub struct Foo;
 // @!hasraw - 'Auto Trait Implementations'
 impl !Send for Foo {}
 impl !Sync for Foo {}
+impl !std::marker::Freeze for Foo {}
 impl !std::marker::Unpin for Foo {}
 impl !std::panic::RefUnwindSafe for Foo {}
 impl !std::panic::UnwindSafe for Foo {}
diff --git a/tests/rustdoc/synthetic_auto/basic.rs b/tests/rustdoc/synthetic_auto/basic.rs
index 043ac241488..16b8cce490c 100644
--- a/tests/rustdoc/synthetic_auto/basic.rs
+++ b/tests/rustdoc/synthetic_auto/basic.rs
@@ -2,7 +2,7 @@
 // @has - '//h3[@class="code-header"]' 'impl<T> Send for Foo<T>where T: Send'
 // @has - '//h3[@class="code-header"]' 'impl<T> Sync for Foo<T>where T: Sync'
 // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6
 pub struct Foo<T> {
     field: T,
 }
diff --git a/tests/rustdoc/synthetic_auto/manual.rs b/tests/rustdoc/synthetic_auto/manual.rs
index 7fc8447df3e..692d68294a7 100644
--- a/tests/rustdoc/synthetic_auto/manual.rs
+++ b/tests/rustdoc/synthetic_auto/manual.rs
@@ -6,7 +6,7 @@
 // 'impl<T> Send for Foo<T>'
 //
 // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1
-// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4
+// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5
 pub struct Foo<T> {
     field: T,
 }
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs
index d443681d5db..1d7417be58c 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs
@@ -15,7 +15,7 @@ extern crate rustc_span;
 
 use rustc_errors::{
     Diag, DiagCtxt, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level, LintDiagnostic,
-    SubdiagMessageOp, Subdiagnostic,
+    SubdiagMessageOp, SubdiagMessage, Subdiagnostic,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::Span;
@@ -114,9 +114,15 @@ pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {
 
 // Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted for
 // `diagnostic_outside_of_impl`.
-
 #[rustc_lint_diagnostics]
 pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) {
     #[allow(rustc::untranslatable_diagnostic)]
     let _diag = dcx.struct_err("untranslatable diagnostic"); // okay!
 }
+
+// Check that multiple translatable params are allowed in a single function (at one point they
+// weren't).
+fn f(_x: impl Into<DiagMessage>, _y: impl Into<SubdiagMessage>) {}
+fn g() {
+    f(crate::fluent_generated::no_crate_example, crate::fluent_generated::no_crate_example);
+}
diff --git a/tests/ui/associated-consts/freeze.rs b/tests/ui/associated-consts/freeze.rs
new file mode 100644
index 00000000000..2364ee1f495
--- /dev/null
+++ b/tests/ui/associated-consts/freeze.rs
@@ -0,0 +1,12 @@
+#![feature(freeze)]
+
+//@ check-pass
+
+use std::marker::Freeze;
+
+trait Trait<T: Freeze + 'static> {
+    const VALUE: T;
+    const VALUE_REF: &'static T = &Self::VALUE;
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-freeze-impls.rs b/tests/ui/feature-gates/feature-gate-freeze-impls.rs
new file mode 100644
index 00000000000..c14c9494874
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-freeze-impls.rs
@@ -0,0 +1,15 @@
+#![feature(freeze, negative_impls)]
+
+use std::marker::Freeze;
+
+struct Foo;
+
+unsafe impl Freeze for Foo {}
+//~^ explicit impls for the `Freeze` trait are not permitted
+
+struct Bar;
+
+impl !Freeze for Bar {}
+//~^ explicit impls for the `Freeze` trait are not permitted
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-freeze-impls.stderr b/tests/ui/feature-gates/feature-gate-freeze-impls.stderr
new file mode 100644
index 00000000000..eef524fe78e
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-freeze-impls.stderr
@@ -0,0 +1,23 @@
+error[E0658]: explicit impls for the `Freeze` trait are not permitted
+  --> $DIR/feature-gate-freeze-impls.rs:7:1
+   |
+LL | unsafe impl Freeze for Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
+   |
+   = note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
+   = help: add `#![feature(freeze_impls)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: explicit impls for the `Freeze` trait are not permitted
+  --> $DIR/feature-gate-freeze-impls.rs:12:1
+   |
+LL | impl !Freeze for Bar {}
+   | ^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed
+   |
+   = note: see issue #121675 <https://github.com/rust-lang/rust/issues/121675> for more information
+   = help: add `#![feature(freeze_impls)]` 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 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/hygiene/panic-location.rs b/tests/ui/hygiene/panic-location.rs
index a98960d74b0..b2f9bfe4f9a 100644
--- a/tests/ui/hygiene/panic-location.rs
+++ b/tests/ui/hygiene/panic-location.rs
@@ -1,6 +1,7 @@
 //@ run-fail
 //@ check-run-results
 //@ exec-env:RUST_BACKTRACE=0
+//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
 //
 // Regression test for issue #70963
 // The captured stderr from this test reports a location
diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr
index ec0ce18c3df..5c1778bc485 100644
--- a/tests/ui/hygiene/panic-location.run.stderr
+++ b/tests/ui/hygiene/panic-location.run.stderr
@@ -1,3 +1,3 @@
-thread 'main' panicked at library/alloc/src/raw_vec.rs:26:5:
+thread 'main' panicked at library/alloc/src/raw_vec.rs:LL:CC:
 capacity overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace