1 | use crate::cmp::Ordering; |
2 | use crate::fmt; |
3 | use crate::hash; |
4 | use crate::intrinsics; |
5 | use crate::intrinsics::assert_unsafe_precondition; |
6 | use crate::marker::Unsize; |
7 | use crate::mem::SizedTypeProperties; |
8 | use crate::mem::{self, MaybeUninit}; |
9 | use crate::num::NonZeroUsize; |
10 | use crate::ops::{CoerceUnsized, DispatchFromDyn}; |
11 | use crate::ptr; |
12 | use crate::ptr::Unique; |
13 | use crate::slice::{self, SliceIndex}; |
14 | |
15 | /// `*mut T` but non-zero and [covariant]. |
16 | /// |
17 | /// This is often the correct thing to use when building data structures using |
18 | /// raw pointers, but is ultimately more dangerous to use because of its additional |
19 | /// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`! |
20 | /// |
21 | /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer |
22 | /// is never dereferenced. This is so that enums may use this forbidden value |
23 | /// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`. |
24 | /// However the pointer may still dangle if it isn't dereferenced. |
25 | /// |
26 | /// Unlike `*mut T`, `NonNull<T>` was chosen to be covariant over `T`. This makes it |
27 | /// possible to use `NonNull<T>` when building covariant types, but introduces the |
28 | /// risk of unsoundness if used in a type that shouldn't actually be covariant. |
29 | /// (The opposite choice was made for `*mut T` even though technically the unsoundness |
30 | /// could only be caused by calling unsafe functions.) |
31 | /// |
32 | /// Covariance is correct for most safe abstractions, such as `Box`, `Rc`, `Arc`, `Vec`, |
33 | /// and `LinkedList`. This is the case because they provide a public API that follows the |
34 | /// normal shared XOR mutable rules of Rust. |
35 | /// |
36 | /// If your type cannot safely be covariant, you must ensure it contains some |
37 | /// additional field to provide invariance. Often this field will be a [`PhantomData`] |
38 | /// type like `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. |
39 | /// |
40 | /// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does |
41 | /// not change the fact that mutating through a (pointer derived from a) shared |
42 | /// reference is undefined behavior unless the mutation happens inside an |
43 | /// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared |
44 | /// reference. When using this `From` instance without an `UnsafeCell<T>`, |
45 | /// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr` |
46 | /// is never used for mutation. |
47 | /// |
48 | /// # Representation |
49 | /// |
50 | /// Thanks to the [null pointer optimization], |
51 | /// `NonNull<T>` and `Option<NonNull<T>>` |
52 | /// are guaranteed to have the same size and alignment: |
53 | /// |
54 | /// ``` |
55 | /// # use std::mem::{size_of, align_of}; |
56 | /// use std::ptr::NonNull; |
57 | /// |
58 | /// assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>()); |
59 | /// assert_eq!(align_of::<NonNull<i16>>(), align_of::<Option<NonNull<i16>>>()); |
60 | /// |
61 | /// assert_eq!(size_of::<NonNull<str>>(), size_of::<Option<NonNull<str>>>()); |
62 | /// assert_eq!(align_of::<NonNull<str>>(), align_of::<Option<NonNull<str>>>()); |
63 | /// ``` |
64 | /// |
65 | /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html |
66 | /// [`PhantomData`]: crate::marker::PhantomData |
67 | /// [`UnsafeCell<T>`]: crate::cell::UnsafeCell |
68 | /// [null pointer optimization]: crate::option#representation |
69 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
70 | #[repr (transparent)] |
71 | #[rustc_layout_scalar_valid_range_start (1)] |
72 | #[rustc_nonnull_optimization_guaranteed ] |
73 | #[rustc_diagnostic_item = "NonNull" ] |
74 | pub struct NonNull<T: ?Sized> { |
75 | pointer: *const T, |
76 | } |
77 | |
78 | /// `NonNull` pointers are not `Send` because the data they reference may be aliased. |
79 | // N.B., this impl is unnecessary, but should provide better error messages. |
80 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
81 | impl<T: ?Sized> !Send for NonNull<T> {} |
82 | |
83 | /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. |
84 | // N.B., this impl is unnecessary, but should provide better error messages. |
85 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
86 | impl<T: ?Sized> !Sync for NonNull<T> {} |
87 | |
88 | impl<T: Sized> NonNull<T> { |
89 | /// Creates a new `NonNull` that is dangling, but well-aligned. |
90 | /// |
91 | /// This is useful for initializing types which lazily allocate, like |
92 | /// `Vec::new` does. |
93 | /// |
94 | /// Note that the pointer value may potentially represent a valid pointer to |
95 | /// a `T`, which means this must not be used as a "not yet initialized" |
96 | /// sentinel value. Types that lazily allocate must track initialization by |
97 | /// some other means. |
98 | /// |
99 | /// # Examples |
100 | /// |
101 | /// ``` |
102 | /// use std::ptr::NonNull; |
103 | /// |
104 | /// let ptr = NonNull::<u32>::dangling(); |
105 | /// // Important: don't try to access the value of `ptr` without |
106 | /// // initializing it first! The pointer is not null but isn't valid either! |
107 | /// ``` |
108 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
109 | #[rustc_const_stable (feature = "const_nonnull_dangling" , since = "1.36.0" )] |
110 | #[must_use ] |
111 | #[inline ] |
112 | pub const fn dangling() -> Self { |
113 | // SAFETY: mem::align_of() returns a non-zero usize which is then casted |
114 | // to a *mut T. Therefore, `ptr` is not null and the conditions for |
115 | // calling new_unchecked() are respected. |
116 | unsafe { |
117 | let ptr = crate::ptr::invalid_mut::<T>(mem::align_of::<T>()); |
118 | NonNull::new_unchecked(ptr) |
119 | } |
120 | } |
121 | |
122 | /// Returns a shared references to the value. In contrast to [`as_ref`], this does not require |
123 | /// that the value has to be initialized. |
124 | /// |
125 | /// For the mutable counterpart see [`as_uninit_mut`]. |
126 | /// |
127 | /// [`as_ref`]: NonNull::as_ref |
128 | /// [`as_uninit_mut`]: NonNull::as_uninit_mut |
129 | /// |
130 | /// # Safety |
131 | /// |
132 | /// When calling this method, you have to ensure that all of the following is true: |
133 | /// |
134 | /// * The pointer must be properly aligned. |
135 | /// |
136 | /// * It must be "dereferenceable" in the sense defined in [the module documentation]. |
137 | /// |
138 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
139 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
140 | /// In particular, while this reference exists, the memory the pointer points to must |
141 | /// not get mutated (except inside `UnsafeCell`). |
142 | /// |
143 | /// This applies even if the result of this method is unused! |
144 | /// |
145 | /// [the module documentation]: crate::ptr#safety |
146 | #[inline ] |
147 | #[must_use ] |
148 | #[unstable (feature = "ptr_as_uninit" , issue = "75402" )] |
149 | #[rustc_const_unstable (feature = "const_ptr_as_ref" , issue = "91822" )] |
150 | pub const unsafe fn as_uninit_ref<'a>(self) -> &'a MaybeUninit<T> { |
151 | // SAFETY: the caller must guarantee that `self` meets all the |
152 | // requirements for a reference. |
153 | unsafe { &*self.cast().as_ptr() } |
154 | } |
155 | |
156 | /// Returns a unique references to the value. In contrast to [`as_mut`], this does not require |
157 | /// that the value has to be initialized. |
158 | /// |
159 | /// For the shared counterpart see [`as_uninit_ref`]. |
160 | /// |
161 | /// [`as_mut`]: NonNull::as_mut |
162 | /// [`as_uninit_ref`]: NonNull::as_uninit_ref |
163 | /// |
164 | /// # Safety |
165 | /// |
166 | /// When calling this method, you have to ensure that all of the following is true: |
167 | /// |
168 | /// * The pointer must be properly aligned. |
169 | /// |
170 | /// * It must be "dereferenceable" in the sense defined in [the module documentation]. |
171 | /// |
172 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
173 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
174 | /// In particular, while this reference exists, the memory the pointer points to must |
175 | /// not get accessed (read or written) through any other pointer. |
176 | /// |
177 | /// This applies even if the result of this method is unused! |
178 | /// |
179 | /// [the module documentation]: crate::ptr#safety |
180 | #[inline ] |
181 | #[must_use ] |
182 | #[unstable (feature = "ptr_as_uninit" , issue = "75402" )] |
183 | #[rustc_const_unstable (feature = "const_ptr_as_ref" , issue = "91822" )] |
184 | pub const unsafe fn as_uninit_mut<'a>(self) -> &'a mut MaybeUninit<T> { |
185 | // SAFETY: the caller must guarantee that `self` meets all the |
186 | // requirements for a reference. |
187 | unsafe { &mut *self.cast().as_ptr() } |
188 | } |
189 | } |
190 | |
191 | impl<T: ?Sized> NonNull<T> { |
192 | /// Creates a new `NonNull`. |
193 | /// |
194 | /// # Safety |
195 | /// |
196 | /// `ptr` must be non-null. |
197 | /// |
198 | /// # Examples |
199 | /// |
200 | /// ``` |
201 | /// use std::ptr::NonNull; |
202 | /// |
203 | /// let mut x = 0u32; |
204 | /// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) }; |
205 | /// ``` |
206 | /// |
207 | /// *Incorrect* usage of this function: |
208 | /// |
209 | /// ```rust,no_run |
210 | /// use std::ptr::NonNull; |
211 | /// |
212 | /// // NEVER DO THAT!!! This is undefined behavior. ⚠️ |
213 | /// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) }; |
214 | /// ``` |
215 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
216 | #[rustc_const_stable (feature = "const_nonnull_new_unchecked" , since = "1.25.0" )] |
217 | #[inline ] |
218 | pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { |
219 | // SAFETY: the caller must guarantee that `ptr` is non-null. |
220 | unsafe { |
221 | assert_unsafe_precondition!("NonNull::new_unchecked requires that the pointer is non-null" , [T: ?Sized](ptr: *mut T) => !ptr.is_null()); |
222 | NonNull { pointer: ptr as _ } |
223 | } |
224 | } |
225 | |
226 | /// Creates a new `NonNull` if `ptr` is non-null. |
227 | /// |
228 | /// # Examples |
229 | /// |
230 | /// ``` |
231 | /// use std::ptr::NonNull; |
232 | /// |
233 | /// let mut x = 0u32; |
234 | /// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!" ); |
235 | /// |
236 | /// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) { |
237 | /// unreachable!(); |
238 | /// } |
239 | /// ``` |
240 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
241 | #[rustc_const_unstable (feature = "const_nonnull_new" , issue = "93235" )] |
242 | #[inline ] |
243 | pub const fn new(ptr: *mut T) -> Option<Self> { |
244 | if !ptr.is_null() { |
245 | // SAFETY: The pointer is already checked and is not null |
246 | Some(unsafe { Self::new_unchecked(ptr) }) |
247 | } else { |
248 | None |
249 | } |
250 | } |
251 | |
252 | /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a |
253 | /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer. |
254 | /// |
255 | /// See the documentation of [`std::ptr::from_raw_parts`] for more details. |
256 | /// |
257 | /// [`std::ptr::from_raw_parts`]: crate::ptr::from_raw_parts |
258 | #[unstable (feature = "ptr_metadata" , issue = "81513" )] |
259 | #[rustc_const_unstable (feature = "ptr_metadata" , issue = "81513" )] |
260 | #[inline ] |
261 | pub const fn from_raw_parts( |
262 | data_pointer: NonNull<()>, |
263 | metadata: <T as super::Pointee>::Metadata, |
264 | ) -> NonNull<T> { |
265 | // SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_pointer` is. |
266 | unsafe { |
267 | NonNull::new_unchecked(super::from_raw_parts_mut(data_pointer.as_ptr(), metadata)) |
268 | } |
269 | } |
270 | |
271 | /// Decompose a (possibly wide) pointer into its data pointer and metadata components. |
272 | /// |
273 | /// The pointer can be later reconstructed with [`NonNull::from_raw_parts`]. |
274 | #[unstable (feature = "ptr_metadata" , issue = "81513" )] |
275 | #[rustc_const_unstable (feature = "ptr_metadata" , issue = "81513" )] |
276 | #[must_use = "this returns the result of the operation, \ |
277 | without modifying the original" ] |
278 | #[inline ] |
279 | pub const fn to_raw_parts(self) -> (NonNull<()>, <T as super::Pointee>::Metadata) { |
280 | (self.cast(), super::metadata(self.as_ptr())) |
281 | } |
282 | |
283 | /// Gets the "address" portion of the pointer. |
284 | /// |
285 | /// For more details see the equivalent method on a raw pointer, [`pointer::addr`]. |
286 | /// |
287 | /// This API and its claimed semantics are part of the Strict Provenance experiment, |
288 | /// see the [`ptr` module documentation][crate::ptr]. |
289 | #[must_use ] |
290 | #[inline ] |
291 | #[unstable (feature = "strict_provenance" , issue = "95228" )] |
292 | pub fn addr(self) -> NonZeroUsize { |
293 | // SAFETY: The pointer is guaranteed by the type to be non-null, |
294 | // meaning that the address will be non-zero. |
295 | unsafe { NonZeroUsize::new_unchecked(self.pointer.addr()) } |
296 | } |
297 | |
298 | /// Creates a new pointer with the given address. |
299 | /// |
300 | /// For more details see the equivalent method on a raw pointer, [`pointer::with_addr`]. |
301 | /// |
302 | /// This API and its claimed semantics are part of the Strict Provenance experiment, |
303 | /// see the [`ptr` module documentation][crate::ptr]. |
304 | #[must_use ] |
305 | #[inline ] |
306 | #[unstable (feature = "strict_provenance" , issue = "95228" )] |
307 | pub fn with_addr(self, addr: NonZeroUsize) -> Self { |
308 | // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero. |
309 | unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) } |
310 | } |
311 | |
312 | /// Creates a new pointer by mapping `self`'s address to a new one. |
313 | /// |
314 | /// For more details see the equivalent method on a raw pointer, [`pointer::map_addr`]. |
315 | /// |
316 | /// This API and its claimed semantics are part of the Strict Provenance experiment, |
317 | /// see the [`ptr` module documentation][crate::ptr]. |
318 | #[must_use ] |
319 | #[inline ] |
320 | #[unstable (feature = "strict_provenance" , issue = "95228" )] |
321 | pub fn map_addr(self, f: impl FnOnce(NonZeroUsize) -> NonZeroUsize) -> Self { |
322 | self.with_addr(f(self.addr())) |
323 | } |
324 | |
325 | /// Acquires the underlying `*mut` pointer. |
326 | /// |
327 | /// # Examples |
328 | /// |
329 | /// ``` |
330 | /// use std::ptr::NonNull; |
331 | /// |
332 | /// let mut x = 0u32; |
333 | /// let ptr = NonNull::new(&mut x).expect("ptr is null!" ); |
334 | /// |
335 | /// let x_value = unsafe { *ptr.as_ptr() }; |
336 | /// assert_eq!(x_value, 0); |
337 | /// |
338 | /// unsafe { *ptr.as_ptr() += 2; } |
339 | /// let x_value = unsafe { *ptr.as_ptr() }; |
340 | /// assert_eq!(x_value, 2); |
341 | /// ``` |
342 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
343 | #[rustc_const_stable (feature = "const_nonnull_as_ptr" , since = "1.32.0" )] |
344 | #[rustc_never_returns_null_ptr ] |
345 | #[must_use ] |
346 | #[inline (always)] |
347 | pub const fn as_ptr(self) -> *mut T { |
348 | self.pointer as *mut T |
349 | } |
350 | |
351 | /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`] |
352 | /// must be used instead. |
353 | /// |
354 | /// For the mutable counterpart see [`as_mut`]. |
355 | /// |
356 | /// [`as_uninit_ref`]: NonNull::as_uninit_ref |
357 | /// [`as_mut`]: NonNull::as_mut |
358 | /// |
359 | /// # Safety |
360 | /// |
361 | /// When calling this method, you have to ensure that all of the following is true: |
362 | /// |
363 | /// * The pointer must be properly aligned. |
364 | /// |
365 | /// * It must be "dereferenceable" in the sense defined in [the module documentation]. |
366 | /// |
367 | /// * The pointer must point to an initialized instance of `T`. |
368 | /// |
369 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
370 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
371 | /// In particular, while this reference exists, the memory the pointer points to must |
372 | /// not get mutated (except inside `UnsafeCell`). |
373 | /// |
374 | /// This applies even if the result of this method is unused! |
375 | /// (The part about being initialized is not yet fully decided, but until |
376 | /// it is, the only safe approach is to ensure that they are indeed initialized.) |
377 | /// |
378 | /// # Examples |
379 | /// |
380 | /// ``` |
381 | /// use std::ptr::NonNull; |
382 | /// |
383 | /// let mut x = 0u32; |
384 | /// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!" ); |
385 | /// |
386 | /// let ref_x = unsafe { ptr.as_ref() }; |
387 | /// println!("{ref_x}" ); |
388 | /// ``` |
389 | /// |
390 | /// [the module documentation]: crate::ptr#safety |
391 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
392 | #[rustc_const_stable (feature = "const_nonnull_as_ref" , since = "1.73.0" )] |
393 | #[must_use ] |
394 | #[inline (always)] |
395 | pub const unsafe fn as_ref<'a>(&self) -> &'a T { |
396 | // SAFETY: the caller must guarantee that `self` meets all the |
397 | // requirements for a reference. |
398 | // `cast_const` avoids a mutable raw pointer deref. |
399 | unsafe { &*self.as_ptr().cast_const() } |
400 | } |
401 | |
402 | /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`] |
403 | /// must be used instead. |
404 | /// |
405 | /// For the shared counterpart see [`as_ref`]. |
406 | /// |
407 | /// [`as_uninit_mut`]: NonNull::as_uninit_mut |
408 | /// [`as_ref`]: NonNull::as_ref |
409 | /// |
410 | /// # Safety |
411 | /// |
412 | /// When calling this method, you have to ensure that all of the following is true: |
413 | /// |
414 | /// * The pointer must be properly aligned. |
415 | /// |
416 | /// * It must be "dereferenceable" in the sense defined in [the module documentation]. |
417 | /// |
418 | /// * The pointer must point to an initialized instance of `T`. |
419 | /// |
420 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
421 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
422 | /// In particular, while this reference exists, the memory the pointer points to must |
423 | /// not get accessed (read or written) through any other pointer. |
424 | /// |
425 | /// This applies even if the result of this method is unused! |
426 | /// (The part about being initialized is not yet fully decided, but until |
427 | /// it is, the only safe approach is to ensure that they are indeed initialized.) |
428 | /// # Examples |
429 | /// |
430 | /// ``` |
431 | /// use std::ptr::NonNull; |
432 | /// |
433 | /// let mut x = 0u32; |
434 | /// let mut ptr = NonNull::new(&mut x).expect("null pointer" ); |
435 | /// |
436 | /// let x_ref = unsafe { ptr.as_mut() }; |
437 | /// assert_eq!(*x_ref, 0); |
438 | /// *x_ref += 2; |
439 | /// assert_eq!(*x_ref, 2); |
440 | /// ``` |
441 | /// |
442 | /// [the module documentation]: crate::ptr#safety |
443 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
444 | #[rustc_const_unstable (feature = "const_ptr_as_ref" , issue = "91822" )] |
445 | #[must_use ] |
446 | #[inline (always)] |
447 | pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T { |
448 | // SAFETY: the caller must guarantee that `self` meets all the |
449 | // requirements for a mutable reference. |
450 | unsafe { &mut *self.as_ptr() } |
451 | } |
452 | |
453 | /// Casts to a pointer of another type. |
454 | /// |
455 | /// # Examples |
456 | /// |
457 | /// ``` |
458 | /// use std::ptr::NonNull; |
459 | /// |
460 | /// let mut x = 0u32; |
461 | /// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer" ); |
462 | /// |
463 | /// let casted_ptr = ptr.cast::<i8>(); |
464 | /// let raw_ptr: *mut i8 = casted_ptr.as_ptr(); |
465 | /// ``` |
466 | #[stable (feature = "nonnull_cast" , since = "1.27.0" )] |
467 | #[rustc_const_stable (feature = "const_nonnull_cast" , since = "1.36.0" )] |
468 | #[must_use = "this returns the result of the operation, \ |
469 | without modifying the original" ] |
470 | #[inline ] |
471 | pub const fn cast<U>(self) -> NonNull<U> { |
472 | // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null |
473 | unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) } |
474 | } |
475 | |
476 | /// Calculates the offset from a pointer. |
477 | /// |
478 | /// `count` is in units of T; e.g., a `count` of 3 represents a pointer |
479 | /// offset of `3 * size_of::<T>()` bytes. |
480 | /// |
481 | /// # Safety |
482 | /// |
483 | /// If any of the following conditions are violated, the result is Undefined |
484 | /// Behavior: |
485 | /// |
486 | /// * Both the starting and resulting pointer must be either in bounds or one |
487 | /// byte past the end of the same [allocated object]. |
488 | /// |
489 | /// * The computed offset, **in bytes**, cannot overflow an `isize`. |
490 | /// |
491 | /// * The offset being in bounds cannot rely on "wrapping around" the address |
492 | /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. |
493 | /// |
494 | /// The compiler and standard library generally tries to ensure allocations |
495 | /// never reach a size where an offset is a concern. For instance, `Vec` |
496 | /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so |
497 | /// `vec.as_ptr().add(vec.len())` is always safe. |
498 | /// |
499 | /// Most platforms fundamentally can't even construct such an allocation. |
500 | /// For instance, no known 64-bit platform can ever serve a request |
501 | /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space. |
502 | /// However, some 32-bit and 16-bit platforms may successfully serve a request for |
503 | /// more than `isize::MAX` bytes with things like Physical Address |
504 | /// Extension. As such, memory acquired directly from allocators or memory |
505 | /// mapped files *may* be too large to handle with this function. |
506 | /// |
507 | /// [allocated object]: crate::ptr#allocated-object |
508 | /// |
509 | /// # Examples |
510 | /// |
511 | /// ``` |
512 | /// #![feature(non_null_convenience)] |
513 | /// use std::ptr::NonNull; |
514 | /// |
515 | /// let mut s = [1, 2, 3]; |
516 | /// let ptr: NonNull<u32> = NonNull::new(s.as_mut_ptr()).unwrap(); |
517 | /// |
518 | /// unsafe { |
519 | /// println!("{}" , ptr.offset(1).read()); |
520 | /// println!("{}" , ptr.offset(2).read()); |
521 | /// } |
522 | /// ``` |
523 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
524 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
525 | #[must_use = "returns a new pointer rather than modifying its argument" ] |
526 | #[inline (always)] |
527 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
528 | pub const unsafe fn offset(self, count: isize) -> NonNull<T> |
529 | where |
530 | T: Sized, |
531 | { |
532 | // SAFETY: the caller must uphold the safety contract for `offset`. |
533 | // Additionally safety contract of `offset` guarantees that the resulting pointer is |
534 | // pointing to an allocation, there can't be an allocation at null, thus it's safe to |
535 | // construct `NonNull`. |
536 | unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } |
537 | } |
538 | |
539 | /// Calculates the offset from a pointer in bytes. |
540 | /// |
541 | /// `count` is in units of **bytes**. |
542 | /// |
543 | /// This is purely a convenience for casting to a `u8` pointer and |
544 | /// using [offset][pointer::offset] on it. See that method for documentation |
545 | /// and safety requirements. |
546 | /// |
547 | /// For non-`Sized` pointees this operation changes only the data pointer, |
548 | /// leaving the metadata untouched. |
549 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
550 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
551 | #[must_use ] |
552 | #[inline (always)] |
553 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
554 | pub const unsafe fn byte_offset(self, count: isize) -> Self { |
555 | // SAFETY: the caller must uphold the safety contract for `offset` and `byte_offset` has |
556 | // the same safety contract. |
557 | // Additionally safety contract of `offset` guarantees that the resulting pointer is |
558 | // pointing to an allocation, there can't be an allocation at null, thus it's safe to |
559 | // construct `NonNull`. |
560 | unsafe { NonNull { pointer: self.pointer.byte_offset(count) } } |
561 | } |
562 | |
563 | /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). |
564 | /// |
565 | /// `count` is in units of T; e.g., a `count` of 3 represents a pointer |
566 | /// offset of `3 * size_of::<T>()` bytes. |
567 | /// |
568 | /// # Safety |
569 | /// |
570 | /// If any of the following conditions are violated, the result is Undefined |
571 | /// Behavior: |
572 | /// |
573 | /// * Both the starting and resulting pointer must be either in bounds or one |
574 | /// byte past the end of the same [allocated object]. |
575 | /// |
576 | /// * The computed offset, **in bytes**, cannot overflow an `isize`. |
577 | /// |
578 | /// * The offset being in bounds cannot rely on "wrapping around" the address |
579 | /// space. That is, the infinite-precision sum must fit in a `usize`. |
580 | /// |
581 | /// The compiler and standard library generally tries to ensure allocations |
582 | /// never reach a size where an offset is a concern. For instance, `Vec` |
583 | /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so |
584 | /// `vec.as_ptr().add(vec.len())` is always safe. |
585 | /// |
586 | /// Most platforms fundamentally can't even construct such an allocation. |
587 | /// For instance, no known 64-bit platform can ever serve a request |
588 | /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space. |
589 | /// However, some 32-bit and 16-bit platforms may successfully serve a request for |
590 | /// more than `isize::MAX` bytes with things like Physical Address |
591 | /// Extension. As such, memory acquired directly from allocators or memory |
592 | /// mapped files *may* be too large to handle with this function. |
593 | /// |
594 | /// [allocated object]: crate::ptr#allocated-object |
595 | /// |
596 | /// # Examples |
597 | /// |
598 | /// ``` |
599 | /// #![feature(non_null_convenience)] |
600 | /// use std::ptr::NonNull; |
601 | /// |
602 | /// let s: &str = "123" ; |
603 | /// let ptr: NonNull<u8> = NonNull::new(s.as_ptr().cast_mut()).unwrap(); |
604 | /// |
605 | /// unsafe { |
606 | /// println!("{}" , ptr.add(1).read() as char); |
607 | /// println!("{}" , ptr.add(2).read() as char); |
608 | /// } |
609 | /// ``` |
610 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
611 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
612 | #[must_use = "returns a new pointer rather than modifying its argument" ] |
613 | #[inline (always)] |
614 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
615 | pub const unsafe fn add(self, count: usize) -> Self |
616 | where |
617 | T: Sized, |
618 | { |
619 | // SAFETY: the caller must uphold the safety contract for `offset`. |
620 | // Additionally safety contract of `offset` guarantees that the resulting pointer is |
621 | // pointing to an allocation, there can't be an allocation at null, thus it's safe to |
622 | // construct `NonNull`. |
623 | unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } } |
624 | } |
625 | |
626 | /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). |
627 | /// |
628 | /// `count` is in units of bytes. |
629 | /// |
630 | /// This is purely a convenience for casting to a `u8` pointer and |
631 | /// using [`add`][NonNull::add] on it. See that method for documentation |
632 | /// and safety requirements. |
633 | /// |
634 | /// For non-`Sized` pointees this operation changes only the data pointer, |
635 | /// leaving the metadata untouched. |
636 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
637 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
638 | #[must_use ] |
639 | #[inline (always)] |
640 | #[rustc_allow_const_fn_unstable (set_ptr_value)] |
641 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
642 | pub const unsafe fn byte_add(self, count: usize) -> Self { |
643 | // SAFETY: the caller must uphold the safety contract for `add` and `byte_add` has the same |
644 | // safety contract. |
645 | // Additionally safety contract of `add` guarantees that the resulting pointer is pointing |
646 | // to an allocation, there can't be an allocation at null, thus it's safe to construct |
647 | // `NonNull`. |
648 | unsafe { NonNull { pointer: self.pointer.byte_add(count) } } |
649 | } |
650 | |
651 | /// Calculates the offset from a pointer (convenience for |
652 | /// `.offset((count as isize).wrapping_neg())`). |
653 | /// |
654 | /// `count` is in units of T; e.g., a `count` of 3 represents a pointer |
655 | /// offset of `3 * size_of::<T>()` bytes. |
656 | /// |
657 | /// # Safety |
658 | /// |
659 | /// If any of the following conditions are violated, the result is Undefined |
660 | /// Behavior: |
661 | /// |
662 | /// * Both the starting and resulting pointer must be either in bounds or one |
663 | /// byte past the end of the same [allocated object]. |
664 | /// |
665 | /// * The computed offset cannot exceed `isize::MAX` **bytes**. |
666 | /// |
667 | /// * The offset being in bounds cannot rely on "wrapping around" the address |
668 | /// space. That is, the infinite-precision sum must fit in a usize. |
669 | /// |
670 | /// The compiler and standard library generally tries to ensure allocations |
671 | /// never reach a size where an offset is a concern. For instance, `Vec` |
672 | /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so |
673 | /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. |
674 | /// |
675 | /// Most platforms fundamentally can't even construct such an allocation. |
676 | /// For instance, no known 64-bit platform can ever serve a request |
677 | /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space. |
678 | /// However, some 32-bit and 16-bit platforms may successfully serve a request for |
679 | /// more than `isize::MAX` bytes with things like Physical Address |
680 | /// Extension. As such, memory acquired directly from allocators or memory |
681 | /// mapped files *may* be too large to handle with this function. |
682 | /// |
683 | /// [allocated object]: crate::ptr#allocated-object |
684 | /// |
685 | /// # Examples |
686 | /// |
687 | /// ``` |
688 | /// #![feature(non_null_convenience)] |
689 | /// use std::ptr::NonNull; |
690 | /// |
691 | /// let s: &str = "123" ; |
692 | /// |
693 | /// unsafe { |
694 | /// let end: NonNull<u8> = NonNull::new(s.as_ptr().cast_mut()).unwrap().add(3); |
695 | /// println!("{}" , end.sub(1).read() as char); |
696 | /// println!("{}" , end.sub(2).read() as char); |
697 | /// } |
698 | /// ``` |
699 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
700 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
701 | #[must_use = "returns a new pointer rather than modifying its argument" ] |
702 | // We could always go back to wrapping if unchecked becomes unacceptable |
703 | #[rustc_allow_const_fn_unstable (const_int_unchecked_arith)] |
704 | #[inline (always)] |
705 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
706 | pub const unsafe fn sub(self, count: usize) -> Self |
707 | where |
708 | T: Sized, |
709 | { |
710 | if T::IS_ZST { |
711 | // Pointer arithmetic does nothing when the pointee is a ZST. |
712 | self |
713 | } else { |
714 | // SAFETY: the caller must uphold the safety contract for `offset`. |
715 | // Because the pointee is *not* a ZST, that means that `count` is |
716 | // at most `isize::MAX`, and thus the negation cannot overflow. |
717 | unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } |
718 | } |
719 | } |
720 | |
721 | /// Calculates the offset from a pointer in bytes (convenience for |
722 | /// `.byte_offset((count as isize).wrapping_neg())`). |
723 | /// |
724 | /// `count` is in units of bytes. |
725 | /// |
726 | /// This is purely a convenience for casting to a `u8` pointer and |
727 | /// using [`sub`][NonNull::sub] on it. See that method for documentation |
728 | /// and safety requirements. |
729 | /// |
730 | /// For non-`Sized` pointees this operation changes only the data pointer, |
731 | /// leaving the metadata untouched. |
732 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
733 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
734 | #[must_use ] |
735 | #[inline (always)] |
736 | #[rustc_allow_const_fn_unstable (set_ptr_value)] |
737 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
738 | pub const unsafe fn byte_sub(self, count: usize) -> Self { |
739 | // SAFETY: the caller must uphold the safety contract for `sub` and `byte_sub` has the same |
740 | // safety contract. |
741 | // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing |
742 | // to an allocation, there can't be an allocation at null, thus it's safe to construct |
743 | // `NonNull`. |
744 | unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } |
745 | } |
746 | |
747 | /// Calculates the distance between two pointers. The returned value is in |
748 | /// units of T: the distance in bytes divided by `mem::size_of::<T>()`. |
749 | /// |
750 | /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`, |
751 | /// except that it has a lot more opportunities for UB, in exchange for the compiler |
752 | /// better understanding what you are doing. |
753 | /// |
754 | /// The primary motivation of this method is for computing the `len` of an array/slice |
755 | /// of `T` that you are currently representing as a "start" and "end" pointer |
756 | /// (and "end" is "one past the end" of the array). |
757 | /// In that case, `end.offset_from(start)` gets you the length of the array. |
758 | /// |
759 | /// All of the following safety requirements are trivially satisfied for this usecase. |
760 | /// |
761 | /// [`offset`]: #method.offset |
762 | /// |
763 | /// # Safety |
764 | /// |
765 | /// If any of the following conditions are violated, the result is Undefined |
766 | /// Behavior: |
767 | /// |
768 | /// * Both `self` and `origin` must be either in bounds or one |
769 | /// byte past the end of the same [allocated object]. |
770 | /// |
771 | /// * Both pointers must be *derived from* a pointer to the same object. |
772 | /// (See below for an example.) |
773 | /// |
774 | /// * The distance between the pointers, in bytes, must be an exact multiple |
775 | /// of the size of `T`. |
776 | /// |
777 | /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. |
778 | /// |
779 | /// * The distance being in bounds cannot rely on "wrapping around" the address space. |
780 | /// |
781 | /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the |
782 | /// address space, so two pointers within some value of any Rust type `T` will always satisfy |
783 | /// the last two conditions. The standard library also generally ensures that allocations |
784 | /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they |
785 | /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())` |
786 | /// always satisfies the last two conditions. |
787 | /// |
788 | /// Most platforms fundamentally can't even construct such a large allocation. |
789 | /// For instance, no known 64-bit platform can ever serve a request |
790 | /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space. |
791 | /// However, some 32-bit and 16-bit platforms may successfully serve a request for |
792 | /// more than `isize::MAX` bytes with things like Physical Address |
793 | /// Extension. As such, memory acquired directly from allocators or memory |
794 | /// mapped files *may* be too large to handle with this function. |
795 | /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on |
796 | /// such large allocations either.) |
797 | /// |
798 | /// The requirement for pointers to be derived from the same allocated object is primarily |
799 | /// needed for `const`-compatibility: the distance between pointers into *different* allocated |
800 | /// objects is not known at compile-time. However, the requirement also exists at |
801 | /// runtime and may be exploited by optimizations. If you wish to compute the difference between |
802 | /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - |
803 | /// origin as isize) / mem::size_of::<T>()`. |
804 | // FIXME: recommend `addr()` instead of `as usize` once that is stable. |
805 | /// |
806 | /// [`add`]: #method.add |
807 | /// [allocated object]: crate::ptr#allocated-object |
808 | /// |
809 | /// # Panics |
810 | /// |
811 | /// This function panics if `T` is a Zero-Sized Type ("ZST"). |
812 | /// |
813 | /// # Examples |
814 | /// |
815 | /// Basic usage: |
816 | /// |
817 | /// ``` |
818 | /// #![feature(non_null_convenience)] |
819 | /// use std::ptr::NonNull; |
820 | /// |
821 | /// let a = [0; 5]; |
822 | /// let ptr1: NonNull<u32> = NonNull::from(&a[1]); |
823 | /// let ptr2: NonNull<u32> = NonNull::from(&a[3]); |
824 | /// unsafe { |
825 | /// assert_eq!(ptr2.offset_from(ptr1), 2); |
826 | /// assert_eq!(ptr1.offset_from(ptr2), -2); |
827 | /// assert_eq!(ptr1.offset(2), ptr2); |
828 | /// assert_eq!(ptr2.offset(-2), ptr1); |
829 | /// } |
830 | /// ``` |
831 | /// |
832 | /// *Incorrect* usage: |
833 | /// |
834 | /// ```rust,no_run |
835 | /// #![feature(non_null_convenience, strict_provenance)] |
836 | /// use std::ptr::NonNull; |
837 | /// |
838 | /// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap(); |
839 | /// let ptr2 = NonNull::new(Box::into_raw(Box::new(1u8))).unwrap(); |
840 | /// let diff = (ptr2.addr().get() as isize).wrapping_sub(ptr1.addr().get() as isize); |
841 | /// // Make ptr2_other an "alias" of ptr2, but derived from ptr1. |
842 | /// let ptr2_other = NonNull::new(ptr1.as_ptr().wrapping_byte_offset(diff)).unwrap(); |
843 | /// assert_eq!(ptr2.addr(), ptr2_other.addr()); |
844 | /// // Since ptr2_other and ptr2 are derived from pointers to different objects, |
845 | /// // computing their offset is undefined behavior, even though |
846 | /// // they point to the same address! |
847 | /// unsafe { |
848 | /// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior |
849 | /// } |
850 | /// ``` |
851 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
852 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
853 | #[inline ] |
854 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
855 | pub const unsafe fn offset_from(self, origin: NonNull<T>) -> isize |
856 | where |
857 | T: Sized, |
858 | { |
859 | // SAFETY: the caller must uphold the safety contract for `offset_from`. |
860 | unsafe { self.pointer.offset_from(origin.pointer) } |
861 | } |
862 | |
863 | /// Calculates the distance between two pointers. The returned value is in |
864 | /// units of **bytes**. |
865 | /// |
866 | /// This is purely a convenience for casting to a `u8` pointer and |
867 | /// using [`offset_from`][NonNull::offset_from] on it. See that method for |
868 | /// documentation and safety requirements. |
869 | /// |
870 | /// For non-`Sized` pointees this operation considers only the data pointers, |
871 | /// ignoring the metadata. |
872 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
873 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
874 | #[inline (always)] |
875 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
876 | pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize { |
877 | // SAFETY: the caller must uphold the safety contract for `byte_offset_from`. |
878 | unsafe { self.pointer.byte_offset_from(origin.pointer) } |
879 | } |
880 | |
881 | // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null |
882 | |
883 | /// Calculates the distance between two pointers, *where it's known that |
884 | /// `self` is equal to or greater than `origin`*. The returned value is in |
885 | /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`. |
886 | /// |
887 | /// This computes the same value that [`offset_from`](#method.offset_from) |
888 | /// would compute, but with the added precondition that the offset is |
889 | /// guaranteed to be non-negative. This method is equivalent to |
890 | /// `usize::try_from(self.offset_from(origin)).unwrap_unchecked()`, |
891 | /// but it provides slightly more information to the optimizer, which can |
892 | /// sometimes allow it to optimize slightly better with some backends. |
893 | /// |
894 | /// This method can be though of as recovering the `count` that was passed |
895 | /// to [`add`](#method.add) (or, with the parameters in the other order, |
896 | /// to [`sub`](#method.sub)). The following are all equivalent, assuming |
897 | /// that their safety preconditions are met: |
898 | /// ```rust |
899 | /// # #![feature (non_null_convenience)] |
900 | /// # unsafe fn blah(ptr: std::ptr::NonNull<u32>, origin: std::ptr::NonNull<u32>, count: usize) -> bool { |
901 | /// ptr.sub_ptr(origin) == count |
902 | /// # && |
903 | /// origin.add(count) == ptr |
904 | /// # && |
905 | /// ptr.sub(count) == origin |
906 | /// # } |
907 | /// ``` |
908 | /// |
909 | /// # Safety |
910 | /// |
911 | /// - The distance between the pointers must be non-negative (`self >= origin`) |
912 | /// |
913 | /// - *All* the safety conditions of [`offset_from`](#method.offset_from) |
914 | /// apply to this method as well; see it for the full details. |
915 | /// |
916 | /// Importantly, despite the return type of this method being able to represent |
917 | /// a larger offset, it's still *not permitted* to pass pointers which differ |
918 | /// by more than `isize::MAX` *bytes*. As such, the result of this method will |
919 | /// always be less than or equal to `isize::MAX as usize`. |
920 | /// |
921 | /// # Panics |
922 | /// |
923 | /// This function panics if `T` is a Zero-Sized Type ("ZST"). |
924 | /// |
925 | /// # Examples |
926 | /// |
927 | /// ``` |
928 | /// #![feature(non_null_convenience)] |
929 | /// use std::ptr::NonNull; |
930 | /// |
931 | /// let a = [0; 5]; |
932 | /// let ptr1: NonNull<u32> = NonNull::from(&a[1]); |
933 | /// let ptr2: NonNull<u32> = NonNull::from(&a[3]); |
934 | /// unsafe { |
935 | /// assert_eq!(ptr2.sub_ptr(ptr1), 2); |
936 | /// assert_eq!(ptr1.add(2), ptr2); |
937 | /// assert_eq!(ptr2.sub(2), ptr1); |
938 | /// assert_eq!(ptr2.sub_ptr(ptr2), 0); |
939 | /// } |
940 | /// |
941 | /// // This would be incorrect, as the pointers are not correctly ordered: |
942 | /// // ptr1.sub_ptr(ptr2) |
943 | /// ``` |
944 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
945 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
946 | // #[unstable(feature = "ptr_sub_ptr", issue = "95892")] |
947 | // #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] |
948 | #[inline ] |
949 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
950 | pub const unsafe fn sub_ptr(self, subtracted: NonNull<T>) -> usize |
951 | where |
952 | T: Sized, |
953 | { |
954 | // SAFETY: the caller must uphold the safety contract for `sub_ptr`. |
955 | unsafe { self.pointer.sub_ptr(subtracted.pointer) } |
956 | } |
957 | |
958 | /// Reads the value from `self` without moving it. This leaves the |
959 | /// memory in `self` unchanged. |
960 | /// |
961 | /// See [`ptr::read`] for safety concerns and examples. |
962 | /// |
963 | /// [`ptr::read`]: crate::ptr::read() |
964 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
965 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
966 | #[inline ] |
967 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
968 | pub const unsafe fn read(self) -> T |
969 | where |
970 | T: Sized, |
971 | { |
972 | // SAFETY: the caller must uphold the safety contract for `read`. |
973 | unsafe { ptr::read(self.pointer) } |
974 | } |
975 | |
976 | /// Performs a volatile read of the value from `self` without moving it. This |
977 | /// leaves the memory in `self` unchanged. |
978 | /// |
979 | /// Volatile operations are intended to act on I/O memory, and are guaranteed |
980 | /// to not be elided or reordered by the compiler across other volatile |
981 | /// operations. |
982 | /// |
983 | /// See [`ptr::read_volatile`] for safety concerns and examples. |
984 | /// |
985 | /// [`ptr::read_volatile`]: crate::ptr::read_volatile() |
986 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
987 | #[inline ] |
988 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
989 | pub unsafe fn read_volatile(self) -> T |
990 | where |
991 | T: Sized, |
992 | { |
993 | // SAFETY: the caller must uphold the safety contract for `read_volatile`. |
994 | unsafe { ptr::read_volatile(self.pointer) } |
995 | } |
996 | |
997 | /// Reads the value from `self` without moving it. This leaves the |
998 | /// memory in `self` unchanged. |
999 | /// |
1000 | /// Unlike `read`, the pointer may be unaligned. |
1001 | /// |
1002 | /// See [`ptr::read_unaligned`] for safety concerns and examples. |
1003 | /// |
1004 | /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() |
1005 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1006 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1007 | #[inline ] |
1008 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1009 | pub const unsafe fn read_unaligned(self) -> T |
1010 | where |
1011 | T: Sized, |
1012 | { |
1013 | // SAFETY: the caller must uphold the safety contract for `read_unaligned`. |
1014 | unsafe { ptr::read_unaligned(self.pointer) } |
1015 | } |
1016 | |
1017 | /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source |
1018 | /// and destination may overlap. |
1019 | /// |
1020 | /// NOTE: this has the *same* argument order as [`ptr::copy`]. |
1021 | /// |
1022 | /// See [`ptr::copy`] for safety concerns and examples. |
1023 | /// |
1024 | /// [`ptr::copy`]: crate::ptr::copy() |
1025 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1026 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1027 | #[inline (always)] |
1028 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1029 | pub const unsafe fn copy_to(self, dest: NonNull<T>, count: usize) |
1030 | where |
1031 | T: Sized, |
1032 | { |
1033 | // SAFETY: the caller must uphold the safety contract for `copy`. |
1034 | unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) } |
1035 | } |
1036 | |
1037 | /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source |
1038 | /// and destination may *not* overlap. |
1039 | /// |
1040 | /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. |
1041 | /// |
1042 | /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. |
1043 | /// |
1044 | /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() |
1045 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1046 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1047 | #[inline (always)] |
1048 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1049 | pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull<T>, count: usize) |
1050 | where |
1051 | T: Sized, |
1052 | { |
1053 | // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. |
1054 | unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) } |
1055 | } |
1056 | |
1057 | /// Copies `count * size_of<T>` bytes from `src` to `self`. The source |
1058 | /// and destination may overlap. |
1059 | /// |
1060 | /// NOTE: this has the *opposite* argument order of [`ptr::copy`]. |
1061 | /// |
1062 | /// See [`ptr::copy`] for safety concerns and examples. |
1063 | /// |
1064 | /// [`ptr::copy`]: crate::ptr::copy() |
1065 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1066 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1067 | #[inline (always)] |
1068 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1069 | pub const unsafe fn copy_from(self, src: NonNull<T>, count: usize) |
1070 | where |
1071 | T: Sized, |
1072 | { |
1073 | // SAFETY: the caller must uphold the safety contract for `copy`. |
1074 | unsafe { ptr::copy(src.pointer, self.as_ptr(), count) } |
1075 | } |
1076 | |
1077 | /// Copies `count * size_of<T>` bytes from `src` to `self`. The source |
1078 | /// and destination may *not* overlap. |
1079 | /// |
1080 | /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`]. |
1081 | /// |
1082 | /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. |
1083 | /// |
1084 | /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() |
1085 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1086 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1087 | #[inline (always)] |
1088 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1089 | pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull<T>, count: usize) |
1090 | where |
1091 | T: Sized, |
1092 | { |
1093 | // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`. |
1094 | unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) } |
1095 | } |
1096 | |
1097 | /// Executes the destructor (if any) of the pointed-to value. |
1098 | /// |
1099 | /// See [`ptr::drop_in_place`] for safety concerns and examples. |
1100 | /// |
1101 | /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place() |
1102 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1103 | #[inline (always)] |
1104 | pub unsafe fn drop_in_place(self) { |
1105 | // SAFETY: the caller must uphold the safety contract for `drop_in_place`. |
1106 | unsafe { ptr::drop_in_place(self.as_ptr()) } |
1107 | } |
1108 | |
1109 | /// Overwrites a memory location with the given value without reading or |
1110 | /// dropping the old value. |
1111 | /// |
1112 | /// See [`ptr::write`] for safety concerns and examples. |
1113 | /// |
1114 | /// [`ptr::write`]: crate::ptr::write() |
1115 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1116 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1117 | //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] |
1118 | #[inline (always)] |
1119 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1120 | pub const unsafe fn write(self, val: T) |
1121 | where |
1122 | T: Sized, |
1123 | { |
1124 | // SAFETY: the caller must uphold the safety contract for `write`. |
1125 | unsafe { ptr::write(self.as_ptr(), val) } |
1126 | } |
1127 | |
1128 | /// Invokes memset on the specified pointer, setting `count * size_of::<T>()` |
1129 | /// bytes of memory starting at `self` to `val`. |
1130 | /// |
1131 | /// See [`ptr::write_bytes`] for safety concerns and examples. |
1132 | /// |
1133 | /// [`ptr::write_bytes`]: crate::ptr::write_bytes() |
1134 | #[doc (alias = "memset" )] |
1135 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1136 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1137 | //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] |
1138 | #[inline (always)] |
1139 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1140 | pub const unsafe fn write_bytes(self, val: u8, count: usize) |
1141 | where |
1142 | T: Sized, |
1143 | { |
1144 | // SAFETY: the caller must uphold the safety contract for `write_bytes`. |
1145 | unsafe { ptr::write_bytes(self.as_ptr(), val, count) } |
1146 | } |
1147 | |
1148 | /// Performs a volatile write of a memory location with the given value without |
1149 | /// reading or dropping the old value. |
1150 | /// |
1151 | /// Volatile operations are intended to act on I/O memory, and are guaranteed |
1152 | /// to not be elided or reordered by the compiler across other volatile |
1153 | /// operations. |
1154 | /// |
1155 | /// See [`ptr::write_volatile`] for safety concerns and examples. |
1156 | /// |
1157 | /// [`ptr::write_volatile`]: crate::ptr::write_volatile() |
1158 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1159 | #[inline (always)] |
1160 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1161 | pub unsafe fn write_volatile(self, val: T) |
1162 | where |
1163 | T: Sized, |
1164 | { |
1165 | // SAFETY: the caller must uphold the safety contract for `write_volatile`. |
1166 | unsafe { ptr::write_volatile(self.as_ptr(), val) } |
1167 | } |
1168 | |
1169 | /// Overwrites a memory location with the given value without reading or |
1170 | /// dropping the old value. |
1171 | /// |
1172 | /// Unlike `write`, the pointer may be unaligned. |
1173 | /// |
1174 | /// See [`ptr::write_unaligned`] for safety concerns and examples. |
1175 | /// |
1176 | /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned() |
1177 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1178 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1179 | //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] |
1180 | #[inline (always)] |
1181 | #[cfg_attr (miri, track_caller)] // even without panics, this helps for Miri backtraces |
1182 | pub const unsafe fn write_unaligned(self, val: T) |
1183 | where |
1184 | T: Sized, |
1185 | { |
1186 | // SAFETY: the caller must uphold the safety contract for `write_unaligned`. |
1187 | unsafe { ptr::write_unaligned(self.as_ptr(), val) } |
1188 | } |
1189 | |
1190 | /// Replaces the value at `self` with `src`, returning the old |
1191 | /// value, without dropping either. |
1192 | /// |
1193 | /// See [`ptr::replace`] for safety concerns and examples. |
1194 | /// |
1195 | /// [`ptr::replace`]: crate::ptr::replace() |
1196 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1197 | #[inline (always)] |
1198 | pub unsafe fn replace(self, src: T) -> T |
1199 | where |
1200 | T: Sized, |
1201 | { |
1202 | // SAFETY: the caller must uphold the safety contract for `replace`. |
1203 | unsafe { ptr::replace(self.as_ptr(), src) } |
1204 | } |
1205 | |
1206 | /// Swaps the values at two mutable locations of the same type, without |
1207 | /// deinitializing either. They may overlap, unlike `mem::swap` which is |
1208 | /// otherwise equivalent. |
1209 | /// |
1210 | /// See [`ptr::swap`] for safety concerns and examples. |
1211 | /// |
1212 | /// [`ptr::swap`]: crate::ptr::swap() |
1213 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1214 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1215 | //#[rustc_const_unstable(feature = "const_swap", issue = "83163")] |
1216 | #[inline (always)] |
1217 | pub const unsafe fn swap(self, with: NonNull<T>) |
1218 | where |
1219 | T: Sized, |
1220 | { |
1221 | // SAFETY: the caller must uphold the safety contract for `swap`. |
1222 | unsafe { ptr::swap(self.as_ptr(), with.as_ptr()) } |
1223 | } |
1224 | |
1225 | /// Computes the offset that needs to be applied to the pointer in order to make it aligned to |
1226 | /// `align`. |
1227 | /// |
1228 | /// If it is not possible to align the pointer, the implementation returns |
1229 | /// `usize::MAX`. It is permissible for the implementation to *always* |
1230 | /// return `usize::MAX`. Only your algorithm's performance can depend |
1231 | /// on getting a usable offset here, not its correctness. |
1232 | /// |
1233 | /// The offset is expressed in number of `T` elements, and not bytes. |
1234 | /// |
1235 | /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go |
1236 | /// beyond the allocation that the pointer points into. It is up to the caller to ensure that |
1237 | /// the returned offset is correct in all terms other than alignment. |
1238 | /// |
1239 | /// # Panics |
1240 | /// |
1241 | /// The function panics if `align` is not a power-of-two. |
1242 | /// |
1243 | /// # Examples |
1244 | /// |
1245 | /// Accessing adjacent `u8` as `u16` |
1246 | /// |
1247 | /// ``` |
1248 | /// #![feature(non_null_convenience)] |
1249 | /// use std::mem::align_of; |
1250 | /// use std::ptr::NonNull; |
1251 | /// |
1252 | /// # unsafe { |
1253 | /// let x = [5_u8, 6, 7, 8, 9]; |
1254 | /// let ptr = NonNull::new(x.as_ptr() as *mut u8).unwrap(); |
1255 | /// let offset = ptr.align_offset(align_of::<u16>()); |
1256 | /// |
1257 | /// if offset < x.len() - 1 { |
1258 | /// let u16_ptr = ptr.add(offset).cast::<u16>(); |
1259 | /// assert!(u16_ptr.read() == u16::from_ne_bytes([5, 6]) || u16_ptr.read() == u16::from_ne_bytes([6, 7])); |
1260 | /// } else { |
1261 | /// // while the pointer can be aligned via `offset`, it would point |
1262 | /// // outside the allocation |
1263 | /// } |
1264 | /// # } |
1265 | /// ``` |
1266 | #[unstable (feature = "non_null_convenience" , issue = "117691" )] |
1267 | #[rustc_const_unstable (feature = "non_null_convenience" , issue = "117691" )] |
1268 | //#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] |
1269 | #[must_use ] |
1270 | #[inline ] |
1271 | pub const fn align_offset(self, align: usize) -> usize |
1272 | where |
1273 | T: Sized, |
1274 | { |
1275 | if !align.is_power_of_two() { |
1276 | panic!("align_offset: align is not a power-of-two" ); |
1277 | } |
1278 | |
1279 | { |
1280 | // SAFETY: `align` has been checked to be a power of 2 above. |
1281 | unsafe { ptr::align_offset(self.pointer, align) } |
1282 | } |
1283 | } |
1284 | |
1285 | /// Returns whether the pointer is properly aligned for `T`. |
1286 | /// |
1287 | /// # Examples |
1288 | /// |
1289 | /// ``` |
1290 | /// #![feature(pointer_is_aligned)] |
1291 | /// use std::ptr::NonNull; |
1292 | /// |
1293 | /// // On some platforms, the alignment of i32 is less than 4. |
1294 | /// #[repr(align(4))] |
1295 | /// struct AlignedI32(i32); |
1296 | /// |
1297 | /// let data = AlignedI32(42); |
1298 | /// let ptr = NonNull::<AlignedI32>::from(&data); |
1299 | /// |
1300 | /// assert!(ptr.is_aligned()); |
1301 | /// assert!(!NonNull::new(ptr.as_ptr().wrapping_byte_add(1)).unwrap().is_aligned()); |
1302 | /// ``` |
1303 | /// |
1304 | /// # At compiletime |
1305 | /// **Note: Alignment at compiletime is experimental and subject to change. See the |
1306 | /// [tracking issue] for details.** |
1307 | /// |
1308 | /// At compiletime, the compiler may not know where a value will end up in memory. |
1309 | /// Calling this function on a pointer created from a reference at compiletime will only |
1310 | /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer |
1311 | /// is never aligned if cast to a type with a stricter alignment than the reference's |
1312 | /// underlying allocation. |
1313 | /// |
1314 | /// ``` |
1315 | /// #![feature(pointer_is_aligned)] |
1316 | /// #![feature(const_pointer_is_aligned)] |
1317 | /// #![feature(non_null_convenience)] |
1318 | /// #![feature(const_option)] |
1319 | /// #![feature(const_nonnull_new)] |
1320 | /// use std::ptr::NonNull; |
1321 | /// |
1322 | /// // On some platforms, the alignment of primitives is less than their size. |
1323 | /// #[repr(align(4))] |
1324 | /// struct AlignedI32(i32); |
1325 | /// #[repr(align(8))] |
1326 | /// struct AlignedI64(i64); |
1327 | /// |
1328 | /// const _: () = { |
1329 | /// let data = [AlignedI32(42), AlignedI32(42)]; |
1330 | /// let ptr = NonNull::<AlignedI32>::new(&data[0] as *const _ as *mut _).unwrap(); |
1331 | /// assert!(ptr.is_aligned()); |
1332 | /// |
1333 | /// // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned. |
1334 | /// let ptr1 = ptr.cast::<AlignedI64>(); |
1335 | /// let ptr2 = unsafe { ptr.add(1).cast::<AlignedI64>() }; |
1336 | /// assert!(!ptr1.is_aligned()); |
1337 | /// assert!(!ptr2.is_aligned()); |
1338 | /// }; |
1339 | /// ``` |
1340 | /// |
1341 | /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime |
1342 | /// pointer is aligned, even if the compiletime pointer wasn't aligned. |
1343 | /// |
1344 | /// ``` |
1345 | /// #![feature(pointer_is_aligned)] |
1346 | /// #![feature(const_pointer_is_aligned)] |
1347 | /// |
1348 | /// // On some platforms, the alignment of primitives is less than their size. |
1349 | /// #[repr(align(4))] |
1350 | /// struct AlignedI32(i32); |
1351 | /// #[repr(align(8))] |
1352 | /// struct AlignedI64(i64); |
1353 | /// |
1354 | /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned. |
1355 | /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42); |
1356 | /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned()); |
1357 | /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned()); |
1358 | /// |
1359 | /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned. |
1360 | /// let runtime_ptr = COMPTIME_PTR; |
1361 | /// assert_ne!( |
1362 | /// runtime_ptr.cast::<AlignedI64>().is_aligned(), |
1363 | /// runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(), |
1364 | /// ); |
1365 | /// ``` |
1366 | /// |
1367 | /// If a pointer is created from a fixed address, this function behaves the same during |
1368 | /// runtime and compiletime. |
1369 | /// |
1370 | /// ``` |
1371 | /// #![feature(pointer_is_aligned)] |
1372 | /// #![feature(const_pointer_is_aligned)] |
1373 | /// #![feature(const_option)] |
1374 | /// #![feature(const_nonnull_new)] |
1375 | /// use std::ptr::NonNull; |
1376 | /// |
1377 | /// // On some platforms, the alignment of primitives is less than their size. |
1378 | /// #[repr(align(4))] |
1379 | /// struct AlignedI32(i32); |
1380 | /// #[repr(align(8))] |
1381 | /// struct AlignedI64(i64); |
1382 | /// |
1383 | /// const _: () = { |
1384 | /// let ptr = NonNull::new(40 as *mut AlignedI32).unwrap(); |
1385 | /// assert!(ptr.is_aligned()); |
1386 | /// |
1387 | /// // For pointers with a known address, runtime and compiletime behavior are identical. |
1388 | /// let ptr1 = ptr.cast::<AlignedI64>(); |
1389 | /// let ptr2 = NonNull::new(ptr.as_ptr().wrapping_add(1)).unwrap().cast::<AlignedI64>(); |
1390 | /// assert!(ptr1.is_aligned()); |
1391 | /// assert!(!ptr2.is_aligned()); |
1392 | /// }; |
1393 | /// ``` |
1394 | /// |
1395 | /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 |
1396 | #[unstable (feature = "pointer_is_aligned" , issue = "96284" )] |
1397 | #[rustc_const_unstable (feature = "const_pointer_is_aligned" , issue = "104203" )] |
1398 | #[must_use ] |
1399 | #[inline ] |
1400 | pub const fn is_aligned(self) -> bool |
1401 | where |
1402 | T: Sized, |
1403 | { |
1404 | self.pointer.is_aligned() |
1405 | } |
1406 | |
1407 | /// Returns whether the pointer is aligned to `align`. |
1408 | /// |
1409 | /// For non-`Sized` pointees this operation considers only the data pointer, |
1410 | /// ignoring the metadata. |
1411 | /// |
1412 | /// # Panics |
1413 | /// |
1414 | /// The function panics if `align` is not a power-of-two (this includes 0). |
1415 | /// |
1416 | /// # Examples |
1417 | /// |
1418 | /// ``` |
1419 | /// #![feature(pointer_is_aligned)] |
1420 | /// |
1421 | /// // On some platforms, the alignment of i32 is less than 4. |
1422 | /// #[repr(align(4))] |
1423 | /// struct AlignedI32(i32); |
1424 | /// |
1425 | /// let data = AlignedI32(42); |
1426 | /// let ptr = &data as *const AlignedI32; |
1427 | /// |
1428 | /// assert!(ptr.is_aligned_to(1)); |
1429 | /// assert!(ptr.is_aligned_to(2)); |
1430 | /// assert!(ptr.is_aligned_to(4)); |
1431 | /// |
1432 | /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2)); |
1433 | /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4)); |
1434 | /// |
1435 | /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8)); |
1436 | /// ``` |
1437 | /// |
1438 | /// # At compiletime |
1439 | /// **Note: Alignment at compiletime is experimental and subject to change. See the |
1440 | /// [tracking issue] for details.** |
1441 | /// |
1442 | /// At compiletime, the compiler may not know where a value will end up in memory. |
1443 | /// Calling this function on a pointer created from a reference at compiletime will only |
1444 | /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer |
1445 | /// cannot be stricter aligned than the reference's underlying allocation. |
1446 | /// |
1447 | /// ``` |
1448 | /// #![feature(pointer_is_aligned)] |
1449 | /// #![feature(const_pointer_is_aligned)] |
1450 | /// |
1451 | /// // On some platforms, the alignment of i32 is less than 4. |
1452 | /// #[repr(align(4))] |
1453 | /// struct AlignedI32(i32); |
1454 | /// |
1455 | /// const _: () = { |
1456 | /// let data = AlignedI32(42); |
1457 | /// let ptr = &data as *const AlignedI32; |
1458 | /// |
1459 | /// assert!(ptr.is_aligned_to(1)); |
1460 | /// assert!(ptr.is_aligned_to(2)); |
1461 | /// assert!(ptr.is_aligned_to(4)); |
1462 | /// |
1463 | /// // At compiletime, we know for sure that the pointer isn't aligned to 8. |
1464 | /// assert!(!ptr.is_aligned_to(8)); |
1465 | /// assert!(!ptr.wrapping_add(1).is_aligned_to(8)); |
1466 | /// }; |
1467 | /// ``` |
1468 | /// |
1469 | /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime |
1470 | /// pointer is aligned, even if the compiletime pointer wasn't aligned. |
1471 | /// |
1472 | /// ``` |
1473 | /// #![feature(pointer_is_aligned)] |
1474 | /// #![feature(const_pointer_is_aligned)] |
1475 | /// |
1476 | /// // On some platforms, the alignment of i32 is less than 4. |
1477 | /// #[repr(align(4))] |
1478 | /// struct AlignedI32(i32); |
1479 | /// |
1480 | /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned. |
1481 | /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42); |
1482 | /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8)); |
1483 | /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8)); |
1484 | /// |
1485 | /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned. |
1486 | /// let runtime_ptr = COMPTIME_PTR; |
1487 | /// assert_ne!( |
1488 | /// runtime_ptr.is_aligned_to(8), |
1489 | /// runtime_ptr.wrapping_add(1).is_aligned_to(8), |
1490 | /// ); |
1491 | /// ``` |
1492 | /// |
1493 | /// If a pointer is created from a fixed address, this function behaves the same during |
1494 | /// runtime and compiletime. |
1495 | /// |
1496 | /// ``` |
1497 | /// #![feature(pointer_is_aligned)] |
1498 | /// #![feature(const_pointer_is_aligned)] |
1499 | /// |
1500 | /// const _: () = { |
1501 | /// let ptr = 40 as *const u8; |
1502 | /// assert!(ptr.is_aligned_to(1)); |
1503 | /// assert!(ptr.is_aligned_to(2)); |
1504 | /// assert!(ptr.is_aligned_to(4)); |
1505 | /// assert!(ptr.is_aligned_to(8)); |
1506 | /// assert!(!ptr.is_aligned_to(16)); |
1507 | /// }; |
1508 | /// ``` |
1509 | /// |
1510 | /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203 |
1511 | #[unstable (feature = "pointer_is_aligned" , issue = "96284" )] |
1512 | #[rustc_const_unstable (feature = "const_pointer_is_aligned" , issue = "104203" )] |
1513 | #[must_use ] |
1514 | #[inline ] |
1515 | pub const fn is_aligned_to(self, align: usize) -> bool { |
1516 | self.pointer.is_aligned_to(align) |
1517 | } |
1518 | } |
1519 | |
1520 | impl<T> NonNull<[T]> { |
1521 | /// Creates a non-null raw slice from a thin pointer and a length. |
1522 | /// |
1523 | /// The `len` argument is the number of **elements**, not the number of bytes. |
1524 | /// |
1525 | /// This function is safe, but dereferencing the return value is unsafe. |
1526 | /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements. |
1527 | /// |
1528 | /// # Examples |
1529 | /// |
1530 | /// ```rust |
1531 | /// use std::ptr::NonNull; |
1532 | /// |
1533 | /// // create a slice pointer when starting out with a pointer to the first element |
1534 | /// let mut x = [5, 6, 7]; |
1535 | /// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap(); |
1536 | /// let slice = NonNull::slice_from_raw_parts(nonnull_pointer, 3); |
1537 | /// assert_eq!(unsafe { slice.as_ref()[2] }, 7); |
1538 | /// ``` |
1539 | /// |
1540 | /// (Note that this example artificially demonstrates a use of this method, |
1541 | /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) |
1542 | #[stable (feature = "nonnull_slice_from_raw_parts" , since = "1.70.0" )] |
1543 | #[rustc_const_unstable (feature = "const_slice_from_raw_parts_mut" , issue = "67456" )] |
1544 | #[must_use ] |
1545 | #[inline ] |
1546 | pub const fn slice_from_raw_parts(data: NonNull<T>, len: usize) -> Self { |
1547 | // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null |
1548 | unsafe { Self::new_unchecked(super::slice_from_raw_parts_mut(data.as_ptr(), len)) } |
1549 | } |
1550 | |
1551 | /// Returns the length of a non-null raw slice. |
1552 | /// |
1553 | /// The returned value is the number of **elements**, not the number of bytes. |
1554 | /// |
1555 | /// This function is safe, even when the non-null raw slice cannot be dereferenced to a slice |
1556 | /// because the pointer does not have a valid address. |
1557 | /// |
1558 | /// # Examples |
1559 | /// |
1560 | /// ```rust |
1561 | /// use std::ptr::NonNull; |
1562 | /// |
1563 | /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); |
1564 | /// assert_eq!(slice.len(), 3); |
1565 | /// ``` |
1566 | #[stable (feature = "slice_ptr_len_nonnull" , since = "1.63.0" )] |
1567 | #[rustc_const_stable (feature = "const_slice_ptr_len_nonnull" , since = "1.63.0" )] |
1568 | #[rustc_allow_const_fn_unstable (const_slice_ptr_len)] |
1569 | #[must_use ] |
1570 | #[inline ] |
1571 | pub const fn len(self) -> usize { |
1572 | self.as_ptr().len() |
1573 | } |
1574 | |
1575 | /// Returns a non-null pointer to the slice's buffer. |
1576 | /// |
1577 | /// # Examples |
1578 | /// |
1579 | /// ```rust |
1580 | /// #![feature(slice_ptr_get)] |
1581 | /// use std::ptr::NonNull; |
1582 | /// |
1583 | /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); |
1584 | /// assert_eq!(slice.as_non_null_ptr(), NonNull::<i8>::dangling()); |
1585 | /// ``` |
1586 | #[inline ] |
1587 | #[must_use ] |
1588 | #[unstable (feature = "slice_ptr_get" , issue = "74265" )] |
1589 | #[rustc_const_unstable (feature = "slice_ptr_get" , issue = "74265" )] |
1590 | pub const fn as_non_null_ptr(self) -> NonNull<T> { |
1591 | // SAFETY: We know `self` is non-null. |
1592 | unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) } |
1593 | } |
1594 | |
1595 | /// Returns a raw pointer to the slice's buffer. |
1596 | /// |
1597 | /// # Examples |
1598 | /// |
1599 | /// ```rust |
1600 | /// #![feature(slice_ptr_get)] |
1601 | /// use std::ptr::NonNull; |
1602 | /// |
1603 | /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); |
1604 | /// assert_eq!(slice.as_mut_ptr(), NonNull::<i8>::dangling().as_ptr()); |
1605 | /// ``` |
1606 | #[inline ] |
1607 | #[must_use ] |
1608 | #[unstable (feature = "slice_ptr_get" , issue = "74265" )] |
1609 | #[rustc_const_unstable (feature = "slice_ptr_get" , issue = "74265" )] |
1610 | #[rustc_never_returns_null_ptr ] |
1611 | pub const fn as_mut_ptr(self) -> *mut T { |
1612 | self.as_non_null_ptr().as_ptr() |
1613 | } |
1614 | |
1615 | /// Returns a shared reference to a slice of possibly uninitialized values. In contrast to |
1616 | /// [`as_ref`], this does not require that the value has to be initialized. |
1617 | /// |
1618 | /// For the mutable counterpart see [`as_uninit_slice_mut`]. |
1619 | /// |
1620 | /// [`as_ref`]: NonNull::as_ref |
1621 | /// [`as_uninit_slice_mut`]: NonNull::as_uninit_slice_mut |
1622 | /// |
1623 | /// # Safety |
1624 | /// |
1625 | /// When calling this method, you have to ensure that all of the following is true: |
1626 | /// |
1627 | /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes, |
1628 | /// and it must be properly aligned. This means in particular: |
1629 | /// |
1630 | /// * The entire memory range of this slice must be contained within a single allocated object! |
1631 | /// Slices can never span across multiple allocated objects. |
1632 | /// |
1633 | /// * The pointer must be aligned even for zero-length slices. One |
1634 | /// reason for this is that enum layout optimizations may rely on references |
1635 | /// (including slices of any length) being aligned and non-null to distinguish |
1636 | /// them from other data. You can obtain a pointer that is usable as `data` |
1637 | /// for zero-length slices using [`NonNull::dangling()`]. |
1638 | /// |
1639 | /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. |
1640 | /// See the safety documentation of [`pointer::offset`]. |
1641 | /// |
1642 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
1643 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
1644 | /// In particular, while this reference exists, the memory the pointer points to must |
1645 | /// not get mutated (except inside `UnsafeCell`). |
1646 | /// |
1647 | /// This applies even if the result of this method is unused! |
1648 | /// |
1649 | /// See also [`slice::from_raw_parts`]. |
1650 | /// |
1651 | /// [valid]: crate::ptr#safety |
1652 | #[inline ] |
1653 | #[must_use ] |
1654 | #[unstable (feature = "ptr_as_uninit" , issue = "75402" )] |
1655 | #[rustc_const_unstable (feature = "const_ptr_as_ref" , issue = "91822" )] |
1656 | pub const unsafe fn as_uninit_slice<'a>(self) -> &'a [MaybeUninit<T>] { |
1657 | // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`. |
1658 | unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) } |
1659 | } |
1660 | |
1661 | /// Returns a unique reference to a slice of possibly uninitialized values. In contrast to |
1662 | /// [`as_mut`], this does not require that the value has to be initialized. |
1663 | /// |
1664 | /// For the shared counterpart see [`as_uninit_slice`]. |
1665 | /// |
1666 | /// [`as_mut`]: NonNull::as_mut |
1667 | /// [`as_uninit_slice`]: NonNull::as_uninit_slice |
1668 | /// |
1669 | /// # Safety |
1670 | /// |
1671 | /// When calling this method, you have to ensure that all of the following is true: |
1672 | /// |
1673 | /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()` |
1674 | /// many bytes, and it must be properly aligned. This means in particular: |
1675 | /// |
1676 | /// * The entire memory range of this slice must be contained within a single allocated object! |
1677 | /// Slices can never span across multiple allocated objects. |
1678 | /// |
1679 | /// * The pointer must be aligned even for zero-length slices. One |
1680 | /// reason for this is that enum layout optimizations may rely on references |
1681 | /// (including slices of any length) being aligned and non-null to distinguish |
1682 | /// them from other data. You can obtain a pointer that is usable as `data` |
1683 | /// for zero-length slices using [`NonNull::dangling()`]. |
1684 | /// |
1685 | /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`. |
1686 | /// See the safety documentation of [`pointer::offset`]. |
1687 | /// |
1688 | /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is |
1689 | /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. |
1690 | /// In particular, while this reference exists, the memory the pointer points to must |
1691 | /// not get accessed (read or written) through any other pointer. |
1692 | /// |
1693 | /// This applies even if the result of this method is unused! |
1694 | /// |
1695 | /// See also [`slice::from_raw_parts_mut`]. |
1696 | /// |
1697 | /// [valid]: crate::ptr#safety |
1698 | /// |
1699 | /// # Examples |
1700 | /// |
1701 | /// ```rust |
1702 | /// #![feature(allocator_api, ptr_as_uninit)] |
1703 | /// |
1704 | /// use std::alloc::{Allocator, Layout, Global}; |
1705 | /// use std::mem::MaybeUninit; |
1706 | /// use std::ptr::NonNull; |
1707 | /// |
1708 | /// let memory: NonNull<[u8]> = Global.allocate(Layout::new::<[u8; 32]>())?; |
1709 | /// // This is safe as `memory` is valid for reads and writes for `memory.len()` many bytes. |
1710 | /// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized. |
1711 | /// # #[allow (unused_variables)] |
1712 | /// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() }; |
1713 | /// # Ok::<_, std::alloc::AllocError>(()) |
1714 | /// ``` |
1715 | #[inline ] |
1716 | #[must_use ] |
1717 | #[unstable (feature = "ptr_as_uninit" , issue = "75402" )] |
1718 | #[rustc_const_unstable (feature = "const_ptr_as_ref" , issue = "91822" )] |
1719 | pub const unsafe fn as_uninit_slice_mut<'a>(self) -> &'a mut [MaybeUninit<T>] { |
1720 | // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`. |
1721 | unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) } |
1722 | } |
1723 | |
1724 | /// Returns a raw pointer to an element or subslice, without doing bounds |
1725 | /// checking. |
1726 | /// |
1727 | /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable |
1728 | /// is *[undefined behavior]* even if the resulting pointer is not used. |
1729 | /// |
1730 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html |
1731 | /// |
1732 | /// # Examples |
1733 | /// |
1734 | /// ``` |
1735 | /// #![feature(slice_ptr_get)] |
1736 | /// use std::ptr::NonNull; |
1737 | /// |
1738 | /// let x = &mut [1, 2, 4]; |
1739 | /// let x = NonNull::slice_from_raw_parts(NonNull::new(x.as_mut_ptr()).unwrap(), x.len()); |
1740 | /// |
1741 | /// unsafe { |
1742 | /// assert_eq!(x.get_unchecked_mut(1).as_ptr(), x.as_non_null_ptr().as_ptr().add(1)); |
1743 | /// } |
1744 | /// ``` |
1745 | #[unstable (feature = "slice_ptr_get" , issue = "74265" )] |
1746 | #[inline ] |
1747 | pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output> |
1748 | where |
1749 | I: SliceIndex<[T]>, |
1750 | { |
1751 | // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. |
1752 | // As a consequence, the resulting pointer cannot be null. |
1753 | unsafe { NonNull::new_unchecked(self.as_ptr().get_unchecked_mut(index)) } |
1754 | } |
1755 | } |
1756 | |
1757 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1758 | impl<T: ?Sized> Clone for NonNull<T> { |
1759 | #[inline (always)] |
1760 | fn clone(&self) -> Self { |
1761 | *self |
1762 | } |
1763 | } |
1764 | |
1765 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1766 | impl<T: ?Sized> Copy for NonNull<T> {} |
1767 | |
1768 | #[unstable (feature = "coerce_unsized" , issue = "18598" )] |
1769 | impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} |
1770 | |
1771 | #[unstable (feature = "dispatch_from_dyn" , issue = "none" )] |
1772 | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} |
1773 | |
1774 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1775 | impl<T: ?Sized> fmt::Debug for NonNull<T> { |
1776 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1777 | fmt::Pointer::fmt(&self.as_ptr(), f) |
1778 | } |
1779 | } |
1780 | |
1781 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1782 | impl<T: ?Sized> fmt::Pointer for NonNull<T> { |
1783 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1784 | fmt::Pointer::fmt(&self.as_ptr(), f) |
1785 | } |
1786 | } |
1787 | |
1788 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1789 | impl<T: ?Sized> Eq for NonNull<T> {} |
1790 | |
1791 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1792 | impl<T: ?Sized> PartialEq for NonNull<T> { |
1793 | #[inline ] |
1794 | #[allow (ambiguous_wide_pointer_comparisons)] |
1795 | fn eq(&self, other: &Self) -> bool { |
1796 | self.as_ptr() == other.as_ptr() |
1797 | } |
1798 | } |
1799 | |
1800 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1801 | impl<T: ?Sized> Ord for NonNull<T> { |
1802 | #[inline ] |
1803 | fn cmp(&self, other: &Self) -> Ordering { |
1804 | self.as_ptr().cmp(&other.as_ptr()) |
1805 | } |
1806 | } |
1807 | |
1808 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1809 | impl<T: ?Sized> PartialOrd for NonNull<T> { |
1810 | #[inline ] |
1811 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
1812 | self.as_ptr().partial_cmp(&other.as_ptr()) |
1813 | } |
1814 | } |
1815 | |
1816 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1817 | impl<T: ?Sized> hash::Hash for NonNull<T> { |
1818 | #[inline ] |
1819 | fn hash<H: hash::Hasher>(&self, state: &mut H) { |
1820 | self.as_ptr().hash(state) |
1821 | } |
1822 | } |
1823 | |
1824 | #[unstable (feature = "ptr_internals" , issue = "none" )] |
1825 | impl<T: ?Sized> From<Unique<T>> for NonNull<T> { |
1826 | #[inline ] |
1827 | fn from(unique: Unique<T>) -> Self { |
1828 | // SAFETY: A Unique pointer cannot be null, so the conditions for |
1829 | // new_unchecked() are respected. |
1830 | unsafe { NonNull::new_unchecked(unique.as_ptr()) } |
1831 | } |
1832 | } |
1833 | |
1834 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1835 | impl<T: ?Sized> From<&mut T> for NonNull<T> { |
1836 | /// Converts a `&mut T` to a `NonNull<T>`. |
1837 | /// |
1838 | /// This conversion is safe and infallible since references cannot be null. |
1839 | #[inline ] |
1840 | fn from(reference: &mut T) -> Self { |
1841 | // SAFETY: A mutable reference cannot be null. |
1842 | unsafe { NonNull { pointer: reference as *mut T } } |
1843 | } |
1844 | } |
1845 | |
1846 | #[stable (feature = "nonnull" , since = "1.25.0" )] |
1847 | impl<T: ?Sized> From<&T> for NonNull<T> { |
1848 | /// Converts a `&T` to a `NonNull<T>`. |
1849 | /// |
1850 | /// This conversion is safe and infallible since references cannot be null. |
1851 | #[inline ] |
1852 | fn from(reference: &T) -> Self { |
1853 | // SAFETY: A reference cannot be null, so the conditions for |
1854 | // new_unchecked() are respected. |
1855 | unsafe { NonNull { pointer: reference as *const T } } |
1856 | } |
1857 | } |
1858 | |