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}