Skip to main content

design/ptr/
non_null.rs

1use std::ptr::NonNull;
2
3use crate::{
4    ops::place::{
5        BorrowPlace,
6        CreateHandle,
7        PlaceHandle,
8        PlaceProxy,
9        ProjectPlace,
10        ReadPlace,
11        WritePlace,
12        borrowck::{
13            AccessKind,
14            Instant,
15            Lifetime,
16        },
17    },
18    place::Subplace,
19};
20
21impl<T: ?Sized> PlaceProxy for NonNull<T> {
22    type Target = T;
23}
24
25unsafe impl<T: ?Sized> CreateHandle<Instant> for NonNull<T> {
26    type Handle = Self;
27
28    const ACCESS: AccessKind = AccessKind::Untracked;
29
30    unsafe fn handle_from_raw(this: *const Self) -> Self::Handle {
31        unsafe { *this }
32    }
33}
34
35impl<T: ?Sized> PlaceHandle for NonNull<T> {
36    type Target = T;
37}
38
39unsafe impl<S: Subplace> ProjectPlace<S> for NonNull<S::Source> {
40    type Projected = NonNull<S::Target>;
41
42    unsafe fn project_place(self, subplace: S) -> Self::Projected {
43        let ptr: *mut S::Source = self.as_ptr();
44        let ptr: *mut S::Target = unsafe { ptr.project_place(subplace) };
45        unsafe { NonNull::new_unchecked(ptr) }
46    }
47}
48
49unsafe impl<'a, T: ?Sized> BorrowPlace<&'a T> for NonNull<T> {
50    const ACCESS: AccessKind = AccessKind::Shared;
51    type Timing = Lifetime<'a>;
52    const SAFE: bool = false;
53
54    unsafe fn borrow(self) -> &'a T {
55        unsafe { self.as_ref() }
56    }
57}
58
59unsafe impl<'a, T: ?Sized> BorrowPlace<&'a mut T> for NonNull<T> {
60    const ACCESS: AccessKind = AccessKind::Exclusive;
61    type Timing = Lifetime<'a>;
62    const SAFE: bool = false;
63
64    unsafe fn borrow(mut self) -> &'a mut T {
65        unsafe { self.as_mut() }
66    }
67}
68
69unsafe impl<T: ?Sized> BorrowPlace<*const T> for NonNull<T> {
70    const ACCESS: AccessKind = AccessKind::Untracked;
71    type Timing = Instant;
72    const SAFE: bool = true;
73
74    unsafe fn borrow(self) -> *const T {
75        self.as_ptr()
76    }
77}
78
79unsafe impl<T: ?Sized> BorrowPlace<*mut T> for NonNull<T> {
80    const ACCESS: AccessKind = AccessKind::Untracked;
81    type Timing = Instant;
82    const SAFE: bool = true;
83
84    unsafe fn borrow(self) -> *mut T {
85        self.as_ptr()
86    }
87}
88
89unsafe impl<T: ?Sized> BorrowPlace<NonNull<T>> for NonNull<T> {
90    const ACCESS: AccessKind = AccessKind::Untracked;
91    type Timing = Instant;
92    const SAFE: bool = true;
93
94    unsafe fn borrow(self) -> NonNull<T> {
95        self
96    }
97}
98
99unsafe impl<T> WritePlace for NonNull<T> {
100    const ACCESS: AccessKind = AccessKind::Exclusive;
101    const SAFE: bool = false;
102
103    unsafe fn write_place(self, value: Self::Target) {
104        unsafe { self.write(value) }
105    }
106}
107
108unsafe impl<T> ReadPlace for NonNull<T> {
109    const ACCESS: AccessKind = AccessKind::Exclusive;
110    const SAFE: bool = false;
111
112    unsafe fn read_place(self) -> Self::Target {
113        unsafe { self.read() }
114    }
115}