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