Skip to main content

design/place/handles/
local.rs

1use std::ptr::NonNull;
2
3use crate::{
4    ops::place::{
5        BorrowPlace,
6        CreateHandle,
7        DerefPlace,
8        PlaceHandle,
9        ProjectPlace,
10        ReadPlace,
11        ReadVariant,
12        VariantPlace,
13        WritePlace,
14        borrowck::{
15            AccessKind,
16            Instant,
17            Lifetime,
18            Timing,
19        },
20    },
21    place::subplace::{
22        HasVariant,
23        Matchable,
24        Subplace,
25        VariantType,
26    },
27};
28
29pub struct LocalHandle<T: ?Sized> {
30    ptr: *const T,
31}
32
33impl<T: ?Sized> Clone for LocalHandle<T> {
34    fn clone(&self) -> Self {
35        *self
36    }
37}
38impl<T: ?Sized> Copy for LocalHandle<T> {}
39
40impl<T: ?Sized> LocalHandle<T> {
41    pub unsafe fn new(ptr: *const T) -> Self {
42        Self { ptr }
43    }
44
45    pub fn as_ptr(&self) -> *mut T {
46        self.ptr.cast_mut()
47    }
48}
49
50impl<T: ?Sized> PlaceHandle for LocalHandle<T> {
51    type Target = T;
52}
53
54unsafe impl<P, ProxyTiming> DerefPlace<ProxyTiming, Instant> for LocalHandle<P>
55where
56    P: CreateHandle<ProxyTiming>,
57    ProxyTiming: Timing,
58{
59    const POINTEE_ACCESS: AccessKind = P::ACCESS;
60    const POINTER_ACCESS: AccessKind = P::ACCESS;
61
62    const SAFE: bool = true;
63
64    unsafe fn deref_place(
65        self,
66    ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle {
67        unsafe { P::handle_from_raw(self.as_ptr()) }
68    }
69}
70
71unsafe impl<T: ?Sized + Matchable> ReadVariant for LocalHandle<T> {
72    unsafe fn read_variant(self) -> &'static str {
73        unsafe { T::variant_at(self.ptr) }
74    }
75}
76
77unsafe impl<T, const VARIANT: &'static str> VariantPlace<VARIANT>
78    for LocalHandle<T>
79where
80    T: ?Sized + HasVariant<VARIANT>,
81{
82    type ToVariant = LocalHandle<VariantType<T, VARIANT>>;
83
84    unsafe fn cast(self) -> Self::ToVariant {
85        LocalHandle { ptr: self.ptr.cast() }
86    }
87}
88
89unsafe impl<S> ProjectPlace<S> for LocalHandle<S::Source>
90where
91    S: Subplace,
92{
93    type Projected = LocalHandle<S::Target>;
94
95    unsafe fn project_place(self, subplace: S) -> Self::Projected {
96        LocalHandle {
97            ptr: unsafe { self.ptr.project_place(subplace) },
98        }
99    }
100}
101
102unsafe impl<T> ReadPlace for LocalHandle<T> {
103    const ACCESS: AccessKind = AccessKind::Shared;
104    const SAFE: bool = true;
105
106    unsafe fn read_place(self) -> Self::Target {
107        unsafe { self.ptr.read() }
108    }
109}
110
111unsafe impl<T> WritePlace for LocalHandle<T> {
112    const ACCESS: AccessKind = AccessKind::Exclusive;
113    const SAFE: bool = true;
114
115    unsafe fn write_place(self, value: Self::Target) {
116        unsafe { self.ptr.cast_mut().write(value) }
117    }
118}
119
120unsafe impl<'a, T> BorrowPlace<&'a T> for LocalHandle<T> {
121    const ACCESS: AccessKind = AccessKind::Shared;
122    type Timing = Lifetime<'a>;
123    const SAFE: bool = true;
124
125    unsafe fn borrow(self) -> &'a T {
126        unsafe { self.ptr.as_ref_unchecked() }
127    }
128}
129
130unsafe impl<'a, T> BorrowPlace<&'a mut T> for LocalHandle<T> {
131    const ACCESS: AccessKind = AccessKind::Exclusive;
132    type Timing = Lifetime<'a>;
133    const SAFE: bool = true;
134
135    unsafe fn borrow(self) -> &'a mut T {
136        unsafe { self.ptr.cast_mut().as_mut_unchecked() }
137    }
138}
139
140unsafe impl<T> BorrowPlace<NonNull<T>> for LocalHandle<T> {
141    const ACCESS: AccessKind = AccessKind::Untracked;
142    type Timing = Instant;
143    const SAFE: bool = true;
144
145    unsafe fn borrow(self) -> NonNull<T> {
146        unsafe { NonNull::new_unchecked(self.ptr.cast_mut()) }
147    }
148}
149
150unsafe impl<T> BorrowPlace<*const T> for LocalHandle<T> {
151    const ACCESS: AccessKind = AccessKind::Untracked;
152    type Timing = Instant;
153    const SAFE: bool = true;
154
155    unsafe fn borrow(self) -> *const T {
156        self.ptr
157    }
158}
159
160unsafe impl<T> BorrowPlace<*mut T> for LocalHandle<T> {
161    const ACCESS: AccessKind = AccessKind::Untracked;
162    type Timing = Instant;
163    const SAFE: bool = true;
164
165    unsafe fn borrow(self) -> *mut T {
166        self.ptr.cast_mut()
167    }
168}