rune_alloc/
ptr.rs

1//! This module contains (hopefully sound) re-implementations of unstable
2//! `core::ptr` APIs.
3
4pub(crate) use self::unique::Unique;
5mod unique;
6
7use core::mem;
8pub(crate) use core::ptr::NonNull;
9
10// Stable re-exports.
11pub(crate) use core::ptr::{
12    addr_of, addr_of_mut, copy, copy_nonoverlapping, drop_in_place, read, slice_from_raw_parts_mut,
13    write,
14};
15
16pub(crate) const unsafe fn nonnull_add<T>(this: NonNull<T>, delta: usize) -> NonNull<T>
17where
18    T: Sized,
19{
20    // SAFETY: We require that the delta stays in-bounds of the object, and
21    // thus it cannot become null, as that would require wrapping the
22    // address space, which no legal objects are allowed to do.
23    // And the caller promised the `delta` is sound to add.
24    let pointer = this.as_ptr();
25    unsafe { NonNull::new_unchecked(pointer.add(delta)) }
26}
27
28pub(crate) const unsafe fn nonnull_sub<T>(this: NonNull<T>, delta: usize) -> NonNull<T>
29where
30    T: Sized,
31{
32    // SAFETY: We require that the delta stays in-bounds of the object, and
33    // thus it cannot become null, as that would require wrapping the
34    // address space, which no legal objects are allowed to do.
35    // And the caller promised the `delta` is sound to add.
36    let pointer = this.as_ptr();
37    unsafe { NonNull::new_unchecked(pointer.sub(delta)) }
38}
39
40#[inline(always)]
41#[allow(clippy::useless_transmute)]
42pub const fn invalid<T>(addr: usize) -> *const T {
43    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
44    // We use transmute rather than a cast so tools like Miri can tell that this
45    // is *not* the same as from_exposed_addr.
46    // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
47    // pointer).
48    unsafe { mem::transmute(addr) }
49}
50
51#[inline(always)]
52#[allow(clippy::useless_transmute)]
53pub const fn invalid_mut<T>(addr: usize) -> *mut T {
54    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
55    // We use transmute rather than a cast so tools like Miri can tell that this
56    // is *not* the same as from_exposed_addr.
57    // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
58    // pointer).
59    unsafe { mem::transmute(addr) }
60}