Skip to main content

design/ptr/
raw_const.rs

1use std::ptr;
2
3use crate::{
4    ops::place::{
5        CreateHandle,
6        DerefPlace,
7        MovePlace,
8        PlaceHandle,
9        PlaceProxy,
10        ProjectPlace,
11        ReadMetadata,
12        ReadPlace,
13        borrowck::{
14            AccessKind,
15            Instant,
16            Timing,
17        },
18    },
19    place::Subplace,
20    ptr::Metadata,
21};
22
23impl<T: ?Sized> PlaceProxy for *const T {
24    type Target = T;
25}
26
27unsafe impl<T: ?Sized> CreateHandle<Instant> for *const T {
28    type Handle = Self;
29
30    const ACCESS: AccessKind = AccessKind::Untracked;
31
32    unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
33        unsafe { *this }
34    }
35}
36
37impl<T: ?Sized> PlaceHandle for *const T {
38    type Target = T;
39}
40
41unsafe impl<T> ReadPlace for *const T {
42    const ACCESS: AccessKind = AccessKind::Untracked;
43    const SAFE: bool = false;
44
45    unsafe fn read_place(self) -> Self::Target {
46        unsafe { self.read() }
47    }
48}
49
50unsafe impl<T: ?Sized> ReadMetadata for *const T {
51    fn metadata(self) -> Metadata<Self::Target> {
52        ptr::metadata(self)
53    }
54}
55
56unsafe impl<T> MovePlace for *const T {}
57
58unsafe impl<S: Subplace> ProjectPlace<S> for *const S::Source {
59    type Projected = *const S::Target;
60
61    unsafe fn project_place(self, subplace: S) -> Self::Projected {
62        let meta: Metadata<S::Source> = self.metadata();
63        let thin: *const () = self.cast();
64        let (offset, meta) = subplace.offset(meta);
65        let thin = unsafe { thin.byte_add(offset) };
66        ptr::from_raw_parts(thin, meta)
67    }
68}
69
70unsafe impl<P, ProxyTiming> DerefPlace<ProxyTiming, Instant> for *const P
71where
72    P: ?Sized + CreateHandle<ProxyTiming>,
73    ProxyTiming: Timing,
74{
75    const POINTEE_ACCESS: AccessKind = P::ACCESS;
76    const POINTER_ACCESS: AccessKind = AccessKind::Untracked;
77
78    const SAFE: bool = false;
79
80    unsafe fn deref_place(
81        self,
82    ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle {
83        unsafe { P::handle_from_raw(self) }
84    }
85}