]>
Commit | Line | Data |
---|---|---|
d9bb1a4e | 1 | use crate::cmp::Ordering; |
dc9dc135 | 2 | use crate::convert::From; |
dc9dc135 XL |
3 | use crate::fmt; |
4 | use crate::hash; | |
5 | use crate::marker::Unsize; | |
6 | use crate::mem; | |
d9bb1a4e | 7 | use crate::ops::{CoerceUnsized, DispatchFromDyn}; |
dc9dc135 | 8 | use crate::ptr::Unique; |
d9bb1a4e FG |
9 | |
10 | // ignore-tidy-undocumented-unsafe | |
dc9dc135 XL |
11 | |
12 | /// `*mut T` but non-zero and covariant. | |
13 | /// | |
14 | /// This is often the correct thing to use when building data structures using | |
15 | /// raw pointers, but is ultimately more dangerous to use because of its additional | |
16 | /// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`! | |
17 | /// | |
18 | /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer | |
19 | /// is never dereferenced. This is so that enums may use this forbidden value | |
20 | /// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`. | |
21 | /// However the pointer may still dangle if it isn't dereferenced. | |
22 | /// | |
23 | /// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect | |
24 | /// for your use case, you should include some [`PhantomData`] in your type to | |
25 | /// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. | |
26 | /// Usually this won't be necessary; covariance is correct for most safe abstractions, | |
27 | /// such as `Box`, `Rc`, `Arc`, `Vec`, and `LinkedList`. This is the case because they | |
28 | /// provide a public API that follows the normal shared XOR mutable rules of Rust. | |
29 | /// | |
30 | /// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does | |
31 | /// not change the fact that mutating through a (pointer derived from a) shared | |
32 | /// reference is undefined behavior unless the mutation happens inside an | |
33 | /// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared | |
34 | /// reference. When using this `From` instance without an `UnsafeCell<T>`, | |
35 | /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr` | |
36 | /// is never used for mutation. | |
37 | /// | |
38 | /// [`PhantomData`]: ../marker/struct.PhantomData.html | |
39 | /// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html | |
40 | #[stable(feature = "nonnull", since = "1.25.0")] | |
41 | #[repr(transparent)] | |
42 | #[rustc_layout_scalar_valid_range_start(1)] | |
416331ca | 43 | #[rustc_nonnull_optimization_guaranteed] |
dc9dc135 XL |
44 | pub struct NonNull<T: ?Sized> { |
45 | pointer: *const T, | |
46 | } | |
47 | ||
48 | /// `NonNull` pointers are not `Send` because the data they reference may be aliased. | |
49 | // N.B., this impl is unnecessary, but should provide better error messages. | |
50 | #[stable(feature = "nonnull", since = "1.25.0")] | |
d9bb1a4e | 51 | impl<T: ?Sized> !Send for NonNull<T> {} |
dc9dc135 XL |
52 | |
53 | /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. | |
54 | // N.B., this impl is unnecessary, but should provide better error messages. | |
55 | #[stable(feature = "nonnull", since = "1.25.0")] | |
d9bb1a4e | 56 | impl<T: ?Sized> !Sync for NonNull<T> {} |
dc9dc135 XL |
57 | |
58 | impl<T: Sized> NonNull<T> { | |
59 | /// Creates a new `NonNull` that is dangling, but well-aligned. | |
60 | /// | |
61 | /// This is useful for initializing types which lazily allocate, like | |
62 | /// `Vec::new` does. | |
63 | /// | |
64 | /// Note that the pointer value may potentially represent a valid pointer to | |
65 | /// a `T`, which means this must not be used as a "not yet initialized" | |
66 | /// sentinel value. Types that lazily allocate must track initialization by | |
67 | /// some other means. | |
68 | #[stable(feature = "nonnull", since = "1.25.0")] | |
46de9a89 | 69 | #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")] |
dc9dc135 XL |
70 | #[inline] |
71 | pub const fn dangling() -> Self { | |
72 | unsafe { | |
73 | let ptr = mem::align_of::<T>() as *mut T; | |
74 | NonNull::new_unchecked(ptr) | |
75 | } | |
76 | } | |
77 | } | |
78 | ||
79 | impl<T: ?Sized> NonNull<T> { | |
80 | /// Creates a new `NonNull`. | |
81 | /// | |
82 | /// # Safety | |
83 | /// | |
84 | /// `ptr` must be non-null. | |
85 | #[stable(feature = "nonnull", since = "1.25.0")] | |
46de9a89 | 86 | #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.32.0")] |
dc9dc135 XL |
87 | #[inline] |
88 | pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { | |
89 | NonNull { pointer: ptr as _ } | |
90 | } | |
91 | ||
92 | /// Creates a new `NonNull` if `ptr` is non-null. | |
93 | #[stable(feature = "nonnull", since = "1.25.0")] | |
94 | #[inline] | |
95 | pub fn new(ptr: *mut T) -> Option<Self> { | |
d9bb1a4e | 96 | if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None } |
dc9dc135 XL |
97 | } |
98 | ||
99 | /// Acquires the underlying `*mut` pointer. | |
100 | #[stable(feature = "nonnull", since = "1.25.0")] | |
46de9a89 | 101 | #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")] |
dc9dc135 XL |
102 | #[inline] |
103 | pub const fn as_ptr(self) -> *mut T { | |
104 | self.pointer as *mut T | |
105 | } | |
106 | ||
107 | /// Dereferences the content. | |
108 | /// | |
109 | /// The resulting lifetime is bound to self so this behaves "as if" | |
110 | /// it were actually an instance of T that is getting borrowed. If a longer | |
111 | /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. | |
112 | #[stable(feature = "nonnull", since = "1.25.0")] | |
113 | #[inline] | |
114 | pub unsafe fn as_ref(&self) -> &T { | |
115 | &*self.as_ptr() | |
116 | } | |
117 | ||
118 | /// Mutably dereferences the content. | |
119 | /// | |
120 | /// The resulting lifetime is bound to self so this behaves "as if" | |
121 | /// it were actually an instance of T that is getting borrowed. If a longer | |
122 | /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. | |
123 | #[stable(feature = "nonnull", since = "1.25.0")] | |
124 | #[inline] | |
125 | pub unsafe fn as_mut(&mut self) -> &mut T { | |
126 | &mut *self.as_ptr() | |
127 | } | |
128 | ||
e1599b0c | 129 | /// Casts to a pointer of another type. |
dc9dc135 | 130 | #[stable(feature = "nonnull_cast", since = "1.27.0")] |
46de9a89 | 131 | #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")] |
dc9dc135 XL |
132 | #[inline] |
133 | pub const fn cast<U>(self) -> NonNull<U> { | |
d9bb1a4e | 134 | unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) } |
dc9dc135 XL |
135 | } |
136 | } | |
137 | ||
138 | #[stable(feature = "nonnull", since = "1.25.0")] | |
139 | impl<T: ?Sized> Clone for NonNull<T> { | |
140 | #[inline] | |
141 | fn clone(&self) -> Self { | |
142 | *self | |
143 | } | |
144 | } | |
145 | ||
146 | #[stable(feature = "nonnull", since = "1.25.0")] | |
d9bb1a4e | 147 | impl<T: ?Sized> Copy for NonNull<T> {} |
dc9dc135 XL |
148 | |
149 | #[unstable(feature = "coerce_unsized", issue = "27732")] | |
d9bb1a4e | 150 | impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} |
dc9dc135 | 151 | |
46de9a89 | 152 | #[unstable(feature = "dispatch_from_dyn", issue = "none")] |
d9bb1a4e | 153 | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} |
dc9dc135 XL |
154 | |
155 | #[stable(feature = "nonnull", since = "1.25.0")] | |
156 | impl<T: ?Sized> fmt::Debug for NonNull<T> { | |
157 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
158 | fmt::Pointer::fmt(&self.as_ptr(), f) | |
159 | } | |
160 | } | |
161 | ||
162 | #[stable(feature = "nonnull", since = "1.25.0")] | |
163 | impl<T: ?Sized> fmt::Pointer for NonNull<T> { | |
164 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
165 | fmt::Pointer::fmt(&self.as_ptr(), f) | |
166 | } | |
167 | } | |
168 | ||
169 | #[stable(feature = "nonnull", since = "1.25.0")] | |
170 | impl<T: ?Sized> Eq for NonNull<T> {} | |
171 | ||
172 | #[stable(feature = "nonnull", since = "1.25.0")] | |
173 | impl<T: ?Sized> PartialEq for NonNull<T> { | |
174 | #[inline] | |
175 | fn eq(&self, other: &Self) -> bool { | |
176 | self.as_ptr() == other.as_ptr() | |
177 | } | |
178 | } | |
179 | ||
180 | #[stable(feature = "nonnull", since = "1.25.0")] | |
181 | impl<T: ?Sized> Ord for NonNull<T> { | |
182 | #[inline] | |
183 | fn cmp(&self, other: &Self) -> Ordering { | |
184 | self.as_ptr().cmp(&other.as_ptr()) | |
185 | } | |
186 | } | |
187 | ||
188 | #[stable(feature = "nonnull", since = "1.25.0")] | |
189 | impl<T: ?Sized> PartialOrd for NonNull<T> { | |
190 | #[inline] | |
191 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | |
192 | self.as_ptr().partial_cmp(&other.as_ptr()) | |
193 | } | |
194 | } | |
195 | ||
196 | #[stable(feature = "nonnull", since = "1.25.0")] | |
197 | impl<T: ?Sized> hash::Hash for NonNull<T> { | |
198 | #[inline] | |
199 | fn hash<H: hash::Hasher>(&self, state: &mut H) { | |
200 | self.as_ptr().hash(state) | |
201 | } | |
202 | } | |
203 | ||
46de9a89 | 204 | #[unstable(feature = "ptr_internals", issue = "none")] |
dc9dc135 XL |
205 | impl<T: ?Sized> From<Unique<T>> for NonNull<T> { |
206 | #[inline] | |
207 | fn from(unique: Unique<T>) -> Self { | |
208 | unsafe { NonNull::new_unchecked(unique.as_ptr()) } | |
209 | } | |
210 | } | |
211 | ||
212 | #[stable(feature = "nonnull", since = "1.25.0")] | |
213 | impl<T: ?Sized> From<&mut T> for NonNull<T> { | |
214 | #[inline] | |
215 | fn from(reference: &mut T) -> Self { | |
216 | unsafe { NonNull { pointer: reference as *mut T } } | |
217 | } | |
218 | } | |
219 | ||
220 | #[stable(feature = "nonnull", since = "1.25.0")] | |
221 | impl<T: ?Sized> From<&T> for NonNull<T> { | |
222 | #[inline] | |
223 | fn from(reference: &T) -> Self { | |
224 | unsafe { NonNull { pointer: reference as *const T } } | |
225 | } | |
226 | } |