Skip to main content

design/place/handles/
ref_mut.rs

1use 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}