design/place/handles/
local.rs1use 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}