design/place/handles/
ref_mut.rs1use std::{
2 marker::PhantomData,
3 ptr::NonNull,
4};
5
6use crate::{
7 ops::place::{
8 BorrowPlace,
9 CreateHandle,
10 DerefPlace,
11 DropPlace,
12 PlaceHandle,
13 PlaceProxy,
14 ProjectPlace,
15 ReadPlace,
16 WritePlace,
17 borrowck::{
18 AccessKind,
19 Instant,
20 Lifetime,
21 Timing,
22 },
23 },
24 place::subplace::Subplace,
25};
26
27pub struct MutHandle<'a, T: ?Sized> {
28 ptr: NonNull<T>,
29 _lt: PhantomData<&'a mut T>,
30}
31
32impl<T: ?Sized> Clone for MutHandle<'_, T> {
33 fn clone(&self) -> Self {
34 *self
35 }
36}
37impl<T: ?Sized> Copy for MutHandle<'_, T> {}
38
39impl<'a, T: ?Sized> MutHandle<'a, T> {
40 pub unsafe fn from_raw(ptr: *mut T) -> Self {
41 Self {
42 ptr: unsafe { NonNull::new_unchecked(ptr) },
43 _lt: PhantomData,
44 }
45 }
46}
47
48impl<'a, T: ?Sized> PlaceProxy for &'a mut T {
49 type Target = T;
50}
51
52unsafe impl<'a, T: ?Sized> CreateHandle<Instant> for &'a mut T {
53 type Handle = MutHandle<'a, T>;
54
55 const ACCESS: AccessKind = AccessKind::Shared;
56
57 unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
58 let ptr: *const *mut T = this.cast::<*mut T>();
59 let handle = unsafe { *ptr };
60 MutHandle {
61 ptr: unsafe { NonNull::new_unchecked(handle) },
62 _lt: PhantomData,
63 }
64 }
65}
66
67impl<'a, T: ?Sized> PlaceHandle for MutHandle<'a, T> {
68 type Target = T;
69}
70
71unsafe impl<T> WritePlace for MutHandle<'_, T> {
72 const ACCESS: AccessKind = AccessKind::Exclusive;
73 const SAFE: bool = true;
74
75 unsafe fn write_place(self, value: Self::Target) {
76 unsafe { self.ptr.write(value) };
77 }
78}
79
80unsafe impl<T> DropPlace for MutHandle<'_, T> {
81 unsafe fn drop_place(self) {
82 unsafe { self.ptr.drop_in_place() };
83 }
84}
85
86unsafe impl<T> ReadPlace for MutHandle<'_, T> {
87 const ACCESS: AccessKind = AccessKind::Exclusive;
88 const SAFE: bool = true;
89
90 unsafe fn read_place(self) -> Self::Target {
91 unsafe { self.ptr.read() }
92 }
93}
94
95unsafe impl<'a, S: Subplace<Target: 'a>> ProjectPlace<S>
96 for MutHandle<'a, S::Source>
97{
98 type Projected = MutHandle<'a, S::Target>;
99
100 unsafe fn project_place(self, subplace: S) -> Self::Projected {
101 MutHandle {
102 ptr: unsafe { self.ptr.project_place(subplace) },
103 _lt: PhantomData,
104 }
105 }
106}
107
108unsafe impl<'a, ProxyTiming, P> DerefPlace<ProxyTiming, Instant>
109 for MutHandle<'a, P>
110where
111 P: CreateHandle<ProxyTiming>,
112 ProxyTiming: Timing,
113 P: ?Sized,
114{
115 const POINTEE_ACCESS: AccessKind = P::ACCESS;
116 const POINTER_ACCESS: AccessKind = AccessKind::Shared;
117 const SAFE: bool = true;
118
119 unsafe fn deref_place(
120 self,
121 ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle {
122 unsafe { P::handle_from_raw(self.ptr.as_ptr()) }
123 }
124}
125
126unsafe impl<'a, 'b, T> BorrowPlace<&'b mut T> for MutHandle<'a, T>
127where
128 'a: 'b,
129{
130 const ACCESS: AccessKind = AccessKind::Exclusive;
131 type Timing = Lifetime<'b>;
132 const SAFE: bool = true;
133
134 unsafe fn borrow(self) -> &'b mut T {
135 unsafe { &mut *self.ptr.as_ptr() }
136 }
137}