Skip to main content

logic_eval_util/
reference.rs

1use std::{marker::PhantomData, ptr::NonNull};
2
3/// A lightweight wrapper around a non-null pointer for a shared reference.
4///
5/// The wrappers are useful when you need a pointer instead of a reference while not degrading usage
6/// and keeping its provenance. For instance, if you make the [`Ref`] from a mutable reference, the
7/// fact the type is made from "mutable" won't be lost, which is an information which some tools,
8/// such as [miri], used for finding pointer safety violations.
9///
10/// [miri]: https://github.com/rust-lang/miri
11#[derive(Debug)]
12pub struct Ref<'a, T: 'a + ?Sized> {
13    ptr: NonNull<T>,
14    _marker: PhantomData<&'a T>,
15}
16
17impl<'a, T: 'a + ?Sized> Ref<'a, T> {
18    pub const fn from_ref(r: &'a T) -> Self {
19        Self {
20            ptr: NonNull::from_ref(r),
21            _marker: PhantomData,
22        }
23    }
24
25    pub const fn from_mut(r: &'a mut T) -> Self {
26        Self {
27            ptr: NonNull::from_mut(r),
28            _marker: PhantomData,
29        }
30    }
31
32    pub const fn as_ref(&self) -> &'a T {
33        // Safety: The type actually has the `&'a T`.
34        unsafe { self.ptr.as_ref() }
35    }
36
37    pub const fn as_nonnull(self) -> NonNull<T> {
38        self.ptr
39    }
40
41    pub const fn as_ptr(self) -> *mut T {
42        self.ptr.as_ptr()
43    }
44}
45
46impl<'a, T: 'a + ?Sized> Clone for Ref<'a, T> {
47    fn clone(&self) -> Self {
48        *self
49    }
50}
51
52impl<'a, T: 'a + ?Sized> Copy for Ref<'a, T> {}