Skip to main content

_01_places/
basic_impls.rs

1use crate::*;
2
3// Aliases to make macros and copy/paste easier.
4type RawConst<T> = *const T;
5type RawMut<T> = *mut T;
6type SharedRef<'a, T> = &'a T;
7type MutRef<'a, T> = &'a mut T;
8
9macro_rules! impl_has_place {
10    ($ptr:ident) => {
11        impl<T: ?Sized> HasPlace for $ptr<T> {
12            type Target = T;
13        }
14    };
15}
16macro_rules! impl_has_place_with_lt {
17    ($ptr:ident) => {
18        impl<'a, T: ?Sized> HasPlace for $ptr<'a, T> {
19            type Target = T;
20        }
21    };
22}
23
24impl<T: ?Sized> HasPlace for RawConst<T> {
    type Target = T;
}impl_has_place!(RawConst);
25impl<T: ?Sized> HasPlace for RawMut<T> {
    type Target = T;
}impl_has_place!(RawMut);
26impl<T: ?Sized> HasPlace for NonNull<T> {
    type Target = T;
}impl_has_place!(NonNull);
27impl<'a, T: ?Sized> HasPlace for SharedRef<'a, T> {
    type Target = T;
}impl_has_place_with_lt!(SharedRef);
28impl<'a, T: ?Sized> HasPlace for MutRef<'a, T> {
    type Target = T;
}impl_has_place_with_lt!(MutRef);
29
30// The two basic impls everything else is derived from.
31unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawConst<P::Target>>
32    for RawConst<P::Source>
33{
34    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
35    unsafe fn borrow(ptr: *const Self, p: &P) -> RawConst<P::Target> {
36        unsafe {
37            let (ptr, meta) = (*ptr).to_raw_parts();
38            let ptr = ptr.byte_offset(p.offset(meta) as isize);
39            let meta = p.project_metadata(meta);
40            std::ptr::from_raw_parts(ptr, meta)
41        }
42    }
43}
44unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawMut<P::Target>>
45    for RawMut<P::Source>
46{
47    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
48    unsafe fn borrow(ptr: *const Self, p: &P) -> RawMut<P::Target> {
49        unsafe {
50            let (ptr, meta) = (*ptr).to_raw_parts();
51            let ptr = ptr.byte_offset(p.offset(meta) as isize);
52            let meta = p.project_metadata(meta);
53            std::ptr::from_raw_parts_mut(ptr, meta)
54        }
55    }
56}
57
58unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, NonNull<P::Target>>
59    for NonNull<P::Source>
60{
61    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
62    unsafe fn borrow(ptr: *const Self, p: &P) -> NonNull<P::Target> {
63        unsafe {
64            let ptr: *mut _ = (*ptr).as_ptr();
65            NonNull::new_unchecked(p.borrow::<*mut _, *mut _>(&raw const ptr))
66        }
67    }
68}
69unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawConst<P::Target>>
70    for NonNull<P::Source>
71{
72    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
73    unsafe fn borrow(ptr: *const Self, p: &P) -> RawConst<P::Target> {
74        unsafe { p.borrow::<NonNull<_>, NonNull<_>>(ptr).as_ptr() }
75    }
76}
77unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawConst<P::Target>>
78    for RawMut<P::Source>
79{
80    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
81    unsafe fn borrow(ptr: *const Self, p: &P) -> RawConst<P::Target> {
82        unsafe { p.borrow::<RawMut<_>, RawMut<_>>(ptr) }
83    }
84}
85unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawConst<P::Target>>
86    for SharedRef<'_, P::Source>
87{
88    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
89    unsafe fn borrow(ptr: *const Self, p: &P) -> RawConst<P::Target> {
90        unsafe {
91            let r: *const *const Self::Target = ptr.cast();
92            p.borrow::<RawConst<_>, RawConst<_>>(r)
93        }
94    }
95}
96unsafe impl<'a, P: Projection + ?Sized> PlaceBorrow<'a, P, RawConst<P::Target>>
97    for MutRef<'_, P::Source>
98{
99    const BORROW_KIND: BorrowKind = BorrowKind::Untracked;
100    unsafe fn borrow(ptr: *const Self, p: &P) -> RawConst<P::Target> {
101        unsafe {
102            let r: *const *mut Self::Target = ptr.cast();
103            p.borrow::<RawMut<_>, RawMut<_>>(r)
104        }
105    }
106}
107
108unsafe impl<P: Projection + ?Sized> PlaceDeref<P> for NonNull<P::Source>
109where
110    P::Target: HasPlace,
111{
112    unsafe fn double_deref(
113        ptr: *mut Self,
114        p: &P,
115    ) -> *const <P as Projection>::Target {
116        unsafe { p.borrow(ptr) }
117    }
118}
119unsafe impl<P: Projection + ?Sized> PlaceDeref<P> for RawConst<P::Source>
120where
121    P::Target: HasPlace,
122{
123    unsafe fn double_deref(
124        ptr: *mut Self,
125        p: &P,
126    ) -> *const <P as Projection>::Target {
127        unsafe { p.borrow(ptr) }
128    }
129}
130unsafe impl<P: Projection + ?Sized> PlaceDeref<P> for RawMut<P::Source>
131where
132    P::Target: HasPlace,
133{
134    unsafe fn double_deref(
135        ptr: *mut Self,
136        p: &P,
137    ) -> *const <P as Projection>::Target {
138        unsafe { p.borrow(ptr) }
139    }
140}
141unsafe impl<P: Projection + ?Sized> PlaceDeref<P> for SharedRef<'_, P::Source>
142where
143    P::Target: HasPlace,
144{
145    unsafe fn double_deref(
146        ptr: *mut Self,
147        p: &P,
148    ) -> *const <P as Projection>::Target {
149        unsafe { p.borrow(ptr) }
150    }
151}
152unsafe impl<P: Projection + ?Sized> PlaceDeref<P> for MutRef<'_, P::Source>
153where
154    P::Target: HasPlace,
155{
156    unsafe fn double_deref(
157        ptr: *mut Self,
158        p: &P,
159    ) -> *const <P as Projection>::Target {
160        unsafe { p.borrow(ptr) }
161    }
162}
163
164unsafe impl<P: Projection + ?Sized> PlaceRead<P> for RawConst<P::Source> {
165    unsafe fn read(ptr: *const Self, p: &P) -> P::Target
166    where
167        P::Target: Sized,
168    {
169        unsafe { p.borrow::<RawConst<_>, RawConst<_>>(ptr).read() }
170    }
171}
172unsafe impl<P: Projection + ?Sized> PlaceRead<P> for RawMut<P::Source> {
173    unsafe fn read(ptr: *const Self, p: &P) -> P::Target
174    where
175        P::Target: Sized,
176    {
177        // Use read on `*const`.
178        unsafe { p.read(ptr.cast::<*const _>()) }
179    }
180}
181unsafe impl<P: Projection + ?Sized> PlaceRead<P> for SharedRef<'_, P::Source> {
182    unsafe fn read(ptr: *const Self, p: &P) -> P::Target
183    where
184        P::Target: Sized,
185    {
186        // Use read on `*const`.
187        unsafe { p.read(ptr.cast::<*const _>()) }
188    }
189}
190
191unsafe impl<P: Projection + ?Sized> PlaceWrite<P> for RawMut<P::Source> {
192    unsafe fn write(ptr: *mut Self, p: &P, x: P::Target)
193    where
194        P::Target: Sized,
195    {
196        unsafe { p.borrow::<RawMut<_>, RawMut<_>>(ptr).write(x) }
197    }
198}
199
200unsafe impl<'a, 'b, T: ?Sized> PlaceCoerce<&'a &'b T> for &'b T {
201    type Output = &'b T;
202}
203unsafe impl<'a, 'b, T: ?Sized> PlaceCoerce<&'a mut &'b T> for &'b T {
204    type Output = &'b T;
205}
206unsafe impl<'a, 'b, T: ?Sized> PlaceCoerce<&'a &'b mut T> for &'b mut T {
207    type Output = &'a T;
208}
209unsafe impl<'a, 'b, T: ?Sized> PlaceCoerce<&'a mut &'b mut T> for &'b mut T {
210    type Output = &'a mut T;
211}