diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index f855b2ad4833..b1b63e6dcbc5 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2855,3 +2855,28 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { write_bytes(dst, val, count) } } + +/// Inform Miri that a given pointer definitely has a certain alignment. +#[cfg(miri)] +pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) { + extern "Rust" { + /// Miri-provided extern function to promise that a given pointer is properly aligned for + /// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is + /// not a power of two. Has no effect when alignment checks are concrete (which is the default). + fn miri_promise_symbolic_alignment(ptr: *const (), align: usize); + } + + fn runtime(ptr: *const (), align: usize) { + // SAFETY: this call is always safe. + unsafe { + miri_promise_symbolic_alignment(ptr, align); + } + } + + const fn compiletime(_ptr: *const (), _align: usize) {} + + // SAFETY: the extra behavior at runtime is for UB checks only. + unsafe { + const_eval_select((ptr, align), compiletime, runtime); + } +} diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 5744ae2366e7..c9489f095644 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1373,27 +1373,7 @@ impl *const T { // Inform Miri that we want to consider the resulting pointer to be suitably aligned. #[cfg(miri)] if ret != usize::MAX { - fn runtime(ptr: *const (), align: usize) { - extern "Rust" { - pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize); - } - - // SAFETY: this call is always safe. - unsafe { - miri_promise_symbolic_alignment(ptr, align); - } - } - - const fn compiletime(_ptr: *const (), _align: usize) {} - - // SAFETY: the extra behavior at runtime is for UB checks only. - unsafe { - intrinsics::const_eval_select( - (self.wrapping_add(ret).cast(), align), - compiletime, - runtime, - ); - } + intrinsics::miri_promise_symbolic_alignment(self.wrapping_add(ret).cast(), align); } ret diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 7805ff8bef56..ab3145ad2dec 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1640,27 +1640,10 @@ impl *mut T { // Inform Miri that we want to consider the resulting pointer to be suitably aligned. #[cfg(miri)] if ret != usize::MAX { - fn runtime(ptr: *const (), align: usize) { - extern "Rust" { - pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize); - } - - // SAFETY: this call is always safe. - unsafe { - miri_promise_symbolic_alignment(ptr, align); - } - } - - const fn compiletime(_ptr: *const (), _align: usize) {} - - // SAFETY: the extra behavior at runtime is for UB checks only. - unsafe { - intrinsics::const_eval_select( - (self.wrapping_add(ret).cast_const().cast(), align), - compiletime, - runtime, - ); - } + intrinsics::miri_promise_symbolic_alignment( + self.wrapping_add(ret).cast_const().cast(), + align, + ); } ret diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 915912d101a0..2c66be6c8cf5 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3878,16 +3878,10 @@ impl [T] { let (us_len, ts_len) = rest.align_to_offsets::(); // Inform Miri that we want to consider the "middle" pointer to be suitably aligned. #[cfg(miri)] - { - extern "Rust" { - pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize); - } - - // SAFETY: this call is always safe. - unsafe { - miri_promise_symbolic_alignment(rest.as_ptr().cast(), mem::align_of::()); - } - } + crate::intrinsics::miri_promise_symbolic_alignment( + rest.as_ptr().cast(), + mem::align_of::(), + ); // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay, // since the caller guarantees that we can transmute `T` to `U` safely. unsafe { @@ -3960,19 +3954,10 @@ impl [T] { let mut_ptr = rest.as_mut_ptr(); // Inform Miri that we want to consider the "middle" pointer to be suitably aligned. #[cfg(miri)] - { - extern "Rust" { - pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize); - } - - // SAFETY: this call is always safe. - unsafe { - miri_promise_symbolic_alignment( - mut_ptr.cast() as *const (), - mem::align_of::(), - ); - } - } + crate::intrinsics::miri_promise_symbolic_alignment( + mut_ptr.cast() as *const (), + mem::align_of::(), + ); // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`! // SAFETY: see comments for `align_to`. unsafe {