Skip to main content

design/place/handles/
ref_const.rs

1use std::{
2    marker::PhantomData,
3    ptr::NonNull,
4};
5
6use crate::{
7    ops::place::{
8        BorrowPlace,
9        CreateHandle,
10        DerefPlace,
11        PlaceHandle,
12        PlaceProxy,
13        ProjectPlace,
14        ReadPlace,
15        borrowck::{
16            AccessKind,
17            Instant,
18            Lifetime,
19            Timing,
20        },
21    },
22    place::subplace::Subplace,
23};
24
25pub struct RefHandle<'a, T: ?Sized> {
26    ptr: NonNull<T>,
27    _lt: PhantomData<&'a mut T>,
28}
29
30impl<'a, T: ?Sized> PlaceProxy for &'a T {
31    type Target = T;
32}
33
34unsafe impl<'a, T: ?Sized> CreateHandle<Instant> for &'a T {
35    type Handle = RefHandle<'a, T>;
36
37    const ACCESS: AccessKind = AccessKind::Shared;
38
39    unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
40        let ptr: *const *const T = this.cast::<*const T>();
41        let handle = unsafe { *ptr };
42        let handle = handle.cast_mut();
43        RefHandle {
44            ptr: unsafe { NonNull::new_unchecked(handle) },
45            _lt: PhantomData,
46        }
47    }
48}
49
50impl<'a, T: ?Sized> PlaceHandle for RefHandle<'a, T> {
51    type Target = T;
52}
53
54unsafe impl<'a, S: Subplace<Target: 'a>> ProjectPlace<S>
55    for RefHandle<'a, S::Source>
56{
57    type Projected = RefHandle<'a, S::Target>;
58
59    unsafe fn project_place(self, subplace: S) -> Self::Projected {
60        RefHandle {
61            ptr: unsafe { self.ptr.project_place(subplace) },
62            _lt: PhantomData,
63        }
64    }
65}
66
67unsafe impl<'a, ProxyTiming, P: ?Sized> DerefPlace<ProxyTiming, Instant>
68    for RefHandle<'a, P>
69where
70    P: CreateHandle<ProxyTiming>,
71    ProxyTiming: Timing,
72{
73    const POINTEE_ACCESS: AccessKind = P::ACCESS;
74    const POINTER_ACCESS: AccessKind = AccessKind::Shared;
75    const SAFE: bool = true;
76
77    unsafe fn deref_place(
78        self,
79    ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle {
80        unsafe { P::handle_from_raw(self.ptr.as_ptr()) }
81    }
82}
83
84unsafe impl<'a, 'b, T> BorrowPlace<&'b T> for RefHandle<'a, T>
85where
86    'a: 'b,
87{
88    const ACCESS: AccessKind = AccessKind::Shared;
89    type Timing = Lifetime<'b>;
90    const SAFE: bool = true;
91
92    unsafe fn borrow(self) -> &'b T {
93        unsafe { &*self.ptr.as_ptr() }
94    }
95}
96
97unsafe impl<'a, T> ReadPlace for RefHandle<'a, T> {
98    const ACCESS: AccessKind = AccessKind::Shared;
99    const SAFE: bool = true;
100
101    unsafe fn read_place(self) -> Self::Target {
102        unsafe { self.ptr.read() }
103    }
104}