Skip to main content

core/ptr/
const_ptr.rs

1use super::*;
2use crate::cmp::Ordering::{Equal, Greater, Less};
3use crate::intrinsics::const_eval_select;
4use crate::mem::{self, SizedTypeProperties};
5use crate::slice::{self, SliceIndex};
6
7impl<T: PointeeSized> *const T {
8    #[doc = include_str!("docs/is_null.md")]
9    ///
10    /// # Examples
11    ///
12    /// ```
13    /// let s: &str = "Follow the rabbit";
14    /// let ptr: *const u8 = s.as_ptr();
15    /// assert!(!ptr.is_null());
16    /// ```
17    #[stable(feature = "rust1", since = "1.0.0")]
18    #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
19    #[rustc_diagnostic_item = "ptr_const_is_null"]
20    #[inline]
21    #[rustc_allow_const_fn_unstable(const_eval_select)]
22    pub const fn is_null(self) -> bool {
23        // Compare via a cast to a thin pointer, so fat pointers are only
24        // considering their "data" part for null-ness.
25        let ptr = self as *const u8;
26        const_eval_select!(
27            @capture { ptr: *const u8 } -> bool:
28            // This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang.
29            if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] {
30                match (ptr).guaranteed_eq(null_mut()) {
31                    Some(res) => res,
32                    // To remain maximally conservative, we stop execution when we don't
33                    // know whether the pointer is null or not.
34                    // We can *not* return `false` here, that would be unsound in `NonNull::new`!
35                    None => panic!("null-ness of this pointer cannot be determined in const context"),
36                }
37            } else {
38                ptr.addr() == 0
39            }
40        )
41    }
42
43    /// Casts to a pointer of another type.
44    #[stable(feature = "ptr_cast", since = "1.38.0")]
45    #[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
46    #[rustc_diagnostic_item = "const_ptr_cast"]
47    #[inline(always)]
48    pub const fn cast<U>(self) -> *const U {
49        self as _
50    }
51
52    /// Try to cast to a pointer of another type by checking alignment.
53    ///
54    /// If the pointer is properly aligned to the target type, it will be
55    /// cast to the target type. Otherwise, `None` is returned.
56    ///
57    /// # Examples
58    ///
59    /// ```rust
60    /// #![feature(pointer_try_cast_aligned)]
61    ///
62    /// let x = 0u64;
63    ///
64    /// let aligned: *const u64 = &x;
65    /// let unaligned = unsafe { aligned.byte_add(1) };
66    ///
67    /// assert!(aligned.try_cast_aligned::<u32>().is_some());
68    /// assert!(unaligned.try_cast_aligned::<u32>().is_none());
69    /// ```
70    #[unstable(feature = "pointer_try_cast_aligned", issue = "141221")]
71    #[must_use = "this returns the result of the operation, \
72                  without modifying the original"]
73    #[inline]
74    pub fn try_cast_aligned<U>(self) -> Option<*const U> {
75        if self.is_aligned_to(align_of::<U>()) { Some(self.cast()) } else { None }
76    }
77
78    /// Uses the address value in a new pointer of another type.
79    ///
80    /// This operation will ignore the address part of its `meta` operand and discard existing
81    /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
82    /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
83    /// with new metadata such as slice lengths or `dyn`-vtable.
84    ///
85    /// The resulting pointer will have provenance of `self`. This operation is semantically the
86    /// same as creating a new pointer with the data pointer value of `self` but the metadata of
87    /// `meta`, being fat or thin depending on the `meta` operand.
88    ///
89    /// # Examples
90    ///
91    /// This function is primarily useful for enabling pointer arithmetic on potentially fat
92    /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
93    /// recombined with its own original metadata.
94    ///
95    /// ```
96    /// #![feature(set_ptr_value)]
97    /// # use core::fmt::Debug;
98    /// let arr: [i32; 3] = [1, 2, 3];
99    /// let mut ptr = arr.as_ptr() as *const dyn Debug;
100    /// let thin = ptr as *const u8;
101    /// unsafe {
102    ///     ptr = thin.add(8).with_metadata_of(ptr);
103    ///     # assert_eq!(*(ptr as *const i32), 3);
104    ///     println!("{:?}", &*ptr); // will print "3"
105    /// }
106    /// ```
107    ///
108    /// # *Incorrect* usage
109    ///
110    /// The provenance from pointers is *not* combined. The result must only be used to refer to the
111    /// address allowed by `self`.
112    ///
113    /// ```rust,no_run
114    /// #![feature(set_ptr_value)]
115    /// let x = 0u32;
116    /// let y = 1u32;
117    ///
118    /// let x = (&x) as *const u32;
119    /// let y = (&y) as *const u32;
120    ///
121    /// let offset = (x as usize - y as usize) / 4;
122    /// let bad = x.wrapping_add(offset).with_metadata_of(y);
123    ///
124    /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
125    /// println!("{:?}", unsafe { &*bad });
126    /// ```
127    #[unstable(feature = "set_ptr_value", issue = "75091")]
128    #[must_use = "returns a new pointer rather than modifying its argument"]
129    #[inline]
130    pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
131    where
132        U: PointeeSized,
133    {
134        from_raw_parts::<U>(self as *const (), metadata(meta))
135    }
136
137    /// Changes constness without changing the type.
138    ///
139    /// This is a bit safer than `as` because it wouldn't silently change the type if the code is
140    /// refactored.
141    #[stable(feature = "ptr_const_cast", since = "1.65.0")]
142    #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
143    #[rustc_diagnostic_item = "ptr_cast_mut"]
144    #[inline(always)]
145    pub const fn cast_mut(self) -> *mut T {
146        self as _
147    }
148
149    #[doc = include_str!("./docs/addr.md")]
150    #[must_use]
151    #[inline(always)]
152    #[stable(feature = "strict_provenance", since = "1.84.0")]
153    pub fn addr(self) -> usize {
154        // A pointer-to-integer transmute currently has exactly the right semantics: it returns the
155        // address without exposing the provenance. Note that this is *not* a stable guarantee about
156        // transmute semantics, it relies on sysroot crates having special status.
157        // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
158        // provenance).
159        unsafe { mem::transmute(self.cast::<()>()) }
160    }
161
162    /// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in
163    /// [`with_exposed_provenance`] and returns the "address" portion.
164    ///
165    /// This is equivalent to `self as usize`, which semantically discards provenance information.
166    /// Furthermore, this (like the `as` cast) has the implicit side-effect of marking the
167    /// provenance as 'exposed', so on platforms that support it you can later call
168    /// [`with_exposed_provenance`] to reconstitute the original pointer including its provenance.
169    ///
170    /// Due to its inherent ambiguity, [`with_exposed_provenance`] may not be supported by tools
171    /// that help you to stay conformant with the Rust memory model. It is recommended to use
172    /// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [`with_addr`][pointer::with_addr]
173    /// wherever possible, in which case [`addr`][pointer::addr] should be used instead of `expose_provenance`.
174    ///
175    /// On most platforms this will produce a value with the same bytes as the original pointer,
176    /// because all the bytes are dedicated to describing the address. Platforms which need to store
177    /// additional information in the pointer may not support this operation, since the 'expose'
178    /// side-effect which is required for [`with_exposed_provenance`] to work is typically not
179    /// available.
180    ///
181    /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
182    ///
183    /// [`with_exposed_provenance`]: with_exposed_provenance
184    #[inline(always)]
185    #[stable(feature = "exposed_provenance", since = "1.84.0")]
186    #[expect(lossy_provenance_casts, reason = "this *is* the replacement")]
187    pub fn expose_provenance(self) -> usize {
188        self.cast::<()>() as usize
189    }
190
191    /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
192    /// `self`.
193    ///
194    /// This is similar to a `addr as *const T` cast, but copies
195    /// the *provenance* of `self` to the new pointer.
196    /// This avoids the inherent ambiguity of the unary cast.
197    ///
198    /// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
199    /// `self` to the given address, and therefore has all the same capabilities and restrictions.
200    ///
201    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
202    #[must_use]
203    #[inline]
204    #[stable(feature = "strict_provenance", since = "1.84.0")]
205    pub fn with_addr(self, addr: usize) -> Self {
206        // This should probably be an intrinsic to avoid doing any sort of arithmetic, but
207        // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's
208        // provenance.
209        let self_addr = self.addr() as isize;
210        let dest_addr = addr as isize;
211        let offset = dest_addr.wrapping_sub(self_addr);
212        self.wrapping_byte_offset(offset)
213    }
214
215    /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
216    /// [provenance][crate::ptr#provenance] of `self`.
217    ///
218    /// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
219    ///
220    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
221    #[must_use]
222    #[inline]
223    #[stable(feature = "strict_provenance", since = "1.84.0")]
224    pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
225        self.with_addr(f(self.addr()))
226    }
227
228    /// Decompose a (possibly wide) pointer into its data pointer and metadata components.
229    ///
230    /// The pointer can be later reconstructed with [`from_raw_parts`].
231    #[unstable(feature = "ptr_metadata", issue = "81513")]
232    #[inline]
233    pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata) {
234        (self.cast(), metadata(self))
235    }
236
237    #[doc = include_str!("./docs/as_ref.md")]
238    ///
239    /// ```
240    /// let ptr: *const u8 = &10u8 as *const u8;
241    ///
242    /// unsafe {
243    ///     let val_back = ptr.as_ref_unchecked();
244    ///     assert_eq!(val_back, &10);
245    /// }
246    /// ```
247    ///
248    /// # Examples
249    ///
250    /// ```
251    /// let ptr: *const u8 = &10u8 as *const u8;
252    ///
253    /// unsafe {
254    ///     if let Some(val_back) = ptr.as_ref() {
255    ///         assert_eq!(val_back, &10);
256    ///     }
257    /// }
258    /// ```
259    ///
260    ///
261    /// [`is_null`]: #method.is_null
262    /// [`as_uninit_ref`]: #method.as_uninit_ref
263    /// [`as_ref_unchecked`]: #method.as_ref_unchecked
264    #[stable(feature = "ptr_as_ref", since = "1.9.0")]
265    #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
266    #[inline]
267    pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
268        // SAFETY: the caller must guarantee that `self` is valid
269        // for a reference if it isn't null.
270        if self.is_null() { None } else { unsafe { Some(&*self) } }
271    }
272
273    /// Returns a shared reference to the value behind the pointer.
274    /// If the pointer may be null or the value may be uninitialized, [`as_uninit_ref`] must be used instead.
275    /// If the pointer may be null, but the value is known to have been initialized, [`as_ref`] must be used instead.
276    ///
277    /// [`as_ref`]: #method.as_ref
278    /// [`as_uninit_ref`]: #method.as_uninit_ref
279    ///
280    /// # Safety
281    ///
282    /// When calling this method, you have to ensure that
283    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// let ptr: *const u8 = &10u8 as *const u8;
289    ///
290    /// unsafe {
291    ///     assert_eq!(ptr.as_ref_unchecked(), &10);
292    /// }
293    /// ```
294    #[stable(feature = "ptr_as_ref_unchecked", since = "1.95.0")]
295    #[rustc_const_stable(feature = "ptr_as_ref_unchecked", since = "1.95.0")]
296    #[inline]
297    #[must_use]
298    pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
299        // SAFETY: the caller must guarantee that `self` is valid for a reference
300        unsafe { &*self }
301    }
302
303    #[doc = include_str!("./docs/as_uninit_ref.md")]
304    ///
305    /// [`is_null`]: #method.is_null
306    /// [`as_ref`]: #method.as_ref
307    ///
308    /// # Examples
309    ///
310    /// ```
311    /// #![feature(ptr_as_uninit)]
312    ///
313    /// let ptr: *const u8 = &10u8 as *const u8;
314    ///
315    /// unsafe {
316    ///     if let Some(val_back) = ptr.as_uninit_ref() {
317    ///         assert_eq!(val_back.assume_init(), 10);
318    ///     }
319    /// }
320    /// ```
321    #[inline]
322    #[unstable(feature = "ptr_as_uninit", issue = "75402")]
323    pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
324    where
325        T: Sized,
326    {
327        // SAFETY: the caller must guarantee that `self` meets all the
328        // requirements for a reference.
329        if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
330    }
331
332    #[doc = include_str!("./docs/offset.md")]
333    ///
334    /// # Examples
335    ///
336    /// ```
337    /// let s: &str = "123";
338    /// let ptr: *const u8 = s.as_ptr();
339    ///
340    /// unsafe {
341    ///     assert_eq!(*ptr.offset(1) as char, '2');
342    ///     assert_eq!(*ptr.offset(2) as char, '3');
343    /// }
344    /// ```
345    #[stable(feature = "rust1", since = "1.0.0")]
346    #[must_use = "returns a new pointer rather than modifying its argument"]
347    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
348    #[inline(always)]
349    #[track_caller]
350    pub const unsafe fn offset(self, count: isize) -> *const T
351    where
352        T: Sized,
353    {
354        #[inline]
355        #[rustc_allow_const_fn_unstable(const_eval_select)]
356        const fn runtime_offset_nowrap(this: *const (), count: isize, size: usize) -> bool {
357            // We can use const_eval_select here because this is only for UB checks.
358            const_eval_select!(
359                @capture { this: *const (), count: isize, size: usize } -> bool:
360                if const {
361                    true
362                } else {
363                    // `size` is the size of a Rust type, so we know that
364                    // `size <= isize::MAX` and thus `as` cast here is not lossy.
365                    let Some(byte_offset) = count.checked_mul(size as isize) else {
366                        return false;
367                    };
368                    let (_, overflow) = this.addr().overflowing_add_signed(byte_offset);
369                    !overflow
370                }
371            )
372        }
373
374        ub_checks::assert_unsafe_precondition!(
375            check_language_ub,
376            "ptr::offset requires the address calculation to not overflow",
377            (
378                this: *const () = self as *const (),
379                count: isize = count,
380                size: usize = size_of::<T>(),
381            ) => runtime_offset_nowrap(this, count, size)
382        );
383
384        // SAFETY: the caller must uphold the safety contract for `offset`.
385        unsafe { intrinsics::offset(self, count) }
386    }
387
388    /// Adds a signed offset in bytes to a pointer.
389    ///
390    /// `count` is in units of **bytes**.
391    ///
392    /// This is purely a convenience for casting to a `u8` pointer and
393    /// using [offset][pointer::offset] on it. See that method for documentation
394    /// and safety requirements.
395    ///
396    /// For non-`Sized` pointees this operation changes only the data pointer,
397    /// leaving the metadata untouched.
398    #[must_use]
399    #[inline(always)]
400    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
401    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
402    #[track_caller]
403    pub const unsafe fn byte_offset(self, count: isize) -> Self {
404        // SAFETY: the caller must uphold the safety contract for `offset`.
405        unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
406    }
407
408    /// Adds a signed offset to a pointer using wrapping arithmetic.
409    ///
410    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
411    /// offset of `3 * size_of::<T>()` bytes.
412    ///
413    /// # Safety
414    ///
415    /// This operation itself is always safe, but using the resulting pointer is not.
416    ///
417    /// The resulting pointer "remembers" the [allocation] that `self` points to
418    /// (this is called "[Provenance](ptr/index.html#provenance)").
419    /// The pointer must not be used to read or write other allocations.
420    ///
421    /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
422    /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
423    /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
424    /// `x` and `y` point into the same allocation.
425    ///
426    /// Compared to [`offset`], this method basically delays the requirement of staying within the
427    /// same allocation: [`offset`] is immediate Undefined Behavior when crossing object
428    /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a
429    /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`]
430    /// can be optimized better and is thus preferable in performance-sensitive code.
431    ///
432    /// The delayed check only considers the value of the pointer that was dereferenced, not the
433    /// intermediate values used during the computation of the final result. For example,
434    /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other
435    /// words, leaving the allocation and then re-entering it later is permitted.
436    ///
437    /// [`offset`]: #method.offset
438    /// [allocation]: crate::ptr#allocation
439    ///
440    /// # Examples
441    ///
442    /// ```
443    /// # use std::fmt::Write;
444    /// // Iterate using a raw pointer in increments of two elements
445    /// let data = [1u8, 2, 3, 4, 5];
446    /// let mut ptr: *const u8 = data.as_ptr();
447    /// let step = 2;
448    /// let end_rounded_up = ptr.wrapping_offset(6);
449    ///
450    /// let mut out = String::new();
451    /// while ptr != end_rounded_up {
452    ///     unsafe {
453    ///         write!(&mut out, "{}, ", *ptr)?;
454    ///     }
455    ///     ptr = ptr.wrapping_offset(step);
456    /// }
457    /// assert_eq!(out.as_str(), "1, 3, 5, ");
458    /// # std::fmt::Result::Ok(())
459    /// ```
460    #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
461    #[must_use = "returns a new pointer rather than modifying its argument"]
462    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
463    #[inline(always)]
464    pub const fn wrapping_offset(self, count: isize) -> *const T
465    where
466        T: Sized,
467    {
468        // SAFETY: the `arith_offset` intrinsic has no prerequisites to be called.
469        unsafe { intrinsics::arith_offset(self, count) }
470    }
471
472    /// Adds a signed offset in bytes to a pointer using wrapping arithmetic.
473    ///
474    /// `count` is in units of **bytes**.
475    ///
476    /// This is purely a convenience for casting to a `u8` pointer and
477    /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
478    /// for documentation.
479    ///
480    /// For non-`Sized` pointees this operation changes only the data pointer,
481    /// leaving the metadata untouched.
482    #[must_use]
483    #[inline(always)]
484    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
485    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
486    pub const fn wrapping_byte_offset(self, count: isize) -> Self {
487        self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
488    }
489
490    /// Masks out bits of the pointer according to a mask.
491    ///
492    /// This is convenience for `ptr.map_addr(|a| a & mask)`.
493    ///
494    /// For non-`Sized` pointees this operation changes only the data pointer,
495    /// leaving the metadata untouched.
496    ///
497    /// ## Examples
498    ///
499    /// ```
500    /// #![feature(ptr_mask)]
501    /// let v = 17_u32;
502    /// let ptr: *const u32 = &v;
503    ///
504    /// // `u32` is 4 bytes aligned,
505    /// // which means that lower 2 bits are always 0.
506    /// let tag_mask = 0b11;
507    /// let ptr_mask = !tag_mask;
508    ///
509    /// // We can store something in these lower bits
510    /// let tagged_ptr = ptr.map_addr(|a| a | 0b10);
511    ///
512    /// // Get the "tag" back
513    /// let tag = tagged_ptr.addr() & tag_mask;
514    /// assert_eq!(tag, 0b10);
515    ///
516    /// // Note that `tagged_ptr` is unaligned, it's UB to read from it.
517    /// // To get original pointer `mask` can be used:
518    /// let masked_ptr = tagged_ptr.mask(ptr_mask);
519    /// assert_eq!(unsafe { *masked_ptr }, 17);
520    /// ```
521    #[unstable(feature = "ptr_mask", issue = "98290")]
522    #[must_use = "returns a new pointer rather than modifying its argument"]
523    #[inline(always)]
524    pub fn mask(self, mask: usize) -> *const T {
525        intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
526    }
527
528    /// Calculates the distance between two pointers within the same allocation. The returned value is in
529    /// units of T: the distance in bytes divided by `size_of::<T>()`.
530    ///
531    /// This is equivalent to `(self as isize - origin as isize) / (size_of::<T>() as isize)`,
532    /// except that it has a lot more opportunities for UB, in exchange for the compiler
533    /// better understanding what you are doing.
534    ///
535    /// The primary motivation of this method is for computing the `len` of an array/slice
536    /// of `T` that you are currently representing as a "start" and "end" pointer
537    /// (and "end" is "one past the end" of the array).
538    /// In that case, `end.offset_from(start)` gets you the length of the array.
539    ///
540    /// All of the following safety requirements are trivially satisfied for this usecase.
541    ///
542    /// [`offset`]: #method.offset
543    ///
544    /// # Safety
545    ///
546    /// If any of the following conditions are violated, the result is Undefined Behavior:
547    ///
548    /// * `self` and `origin` must either
549    ///
550    ///   * point to the same address, or
551    ///   * both be [derived from][crate::ptr#provenance] a pointer to the same [allocation], and the memory range between
552    ///     the two pointers must be in bounds of that object. (See below for an example.)
553    ///
554    /// * The distance between the pointers, in bytes, must be an exact multiple
555    ///   of the size of `T`.
556    ///
557    /// As a consequence, the absolute distance between the pointers, in bytes, computed on
558    /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is
559    /// implied by the in-bounds requirement, and the fact that no allocation can be larger
560    /// than `isize::MAX` bytes.
561    ///
562    /// The requirement for pointers to be derived from the same allocation is primarily
563    /// needed for `const`-compatibility: the distance between pointers into *different* allocated
564    /// objects is not known at compile-time. However, the requirement also exists at
565    /// runtime and may be exploited by optimizations. If you wish to compute the difference between
566    /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
567    /// origin as isize) / size_of::<T>()`.
568    // FIXME: recommend `addr()` instead of `as usize` once that is stable.
569    ///
570    /// [`add`]: #method.add
571    /// [allocation]: crate::ptr#allocation
572    ///
573    /// # Panics
574    ///
575    /// This function panics if `T` is a Zero-Sized Type ("ZST").
576    ///
577    /// # Examples
578    ///
579    /// Basic usage:
580    ///
581    /// ```
582    /// let a = [0; 5];
583    /// let ptr1: *const i32 = &a[1];
584    /// let ptr2: *const i32 = &a[3];
585    /// unsafe {
586    ///     assert_eq!(ptr2.offset_from(ptr1), 2);
587    ///     assert_eq!(ptr1.offset_from(ptr2), -2);
588    ///     assert_eq!(ptr1.offset(2), ptr2);
589    ///     assert_eq!(ptr2.offset(-2), ptr1);
590    /// }
591    /// ```
592    ///
593    /// *Incorrect* usage:
594    ///
595    /// ```rust,no_run
596    /// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
597    /// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
598    /// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
599    /// // Make ptr2_other an "alias" of ptr2.add(1), but derived from ptr1.
600    /// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff).wrapping_offset(1);
601    /// assert_eq!(ptr2 as usize, ptr2_other as usize);
602    /// // Since ptr2_other and ptr2 are derived from pointers to different objects,
603    /// // computing their offset is undefined behavior, even though
604    /// // they point to addresses that are in-bounds of the same object!
605    /// unsafe {
606    ///     let one = ptr2_other.offset_from(ptr2); // Undefined Behavior! ⚠️
607    /// }
608    /// ```
609    #[stable(feature = "ptr_offset_from", since = "1.47.0")]
610    #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")]
611    #[inline]
612    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
613    pub const unsafe fn offset_from(self, origin: *const T) -> isize
614    where
615        T: Sized,
616    {
617        let pointee_size = size_of::<T>();
618        assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
619        // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
620        unsafe { intrinsics::ptr_offset_from(self, origin) }
621    }
622
623    /// Calculates the distance between two pointers within the same allocation. The returned value is in
624    /// units of **bytes**.
625    ///
626    /// This is purely a convenience for casting to a `u8` pointer and
627    /// using [`offset_from`][pointer::offset_from] on it. See that method for
628    /// documentation and safety requirements.
629    ///
630    /// For non-`Sized` pointees this operation considers only the data pointers,
631    /// ignoring the metadata.
632    #[inline(always)]
633    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
634    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
635    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
636    pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: *const U) -> isize {
637        // SAFETY: the caller must uphold the safety contract for `offset_from`.
638        unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
639    }
640
641    /// Calculates the distance between two pointers within the same allocation, *where it's known that
642    /// `self` is equal to or greater than `origin`*. The returned value is in
643    /// units of T: the distance in bytes is divided by `size_of::<T>()`.
644    ///
645    /// This computes the same value that [`offset_from`](#method.offset_from)
646    /// would compute, but with the added precondition that the offset is
647    /// guaranteed to be non-negative.  This method is equivalent to
648    /// `usize::try_from(self.offset_from(origin)).unwrap_unchecked()`,
649    /// but it provides slightly more information to the optimizer, which can
650    /// sometimes allow it to optimize slightly better with some backends.
651    ///
652    /// This method can be thought of as recovering the `count` that was passed
653    /// to [`add`](#method.add) (or, with the parameters in the other order,
654    /// to [`sub`](#method.sub)).  The following are all equivalent, assuming
655    /// that their safety preconditions are met:
656    /// ```rust
657    /// # unsafe fn blah(ptr: *const i32, origin: *const i32, count: usize) -> bool { unsafe {
658    /// ptr.offset_from_unsigned(origin) == count
659    /// # &&
660    /// origin.add(count) == ptr
661    /// # &&
662    /// ptr.sub(count) == origin
663    /// # } }
664    /// ```
665    ///
666    /// # Safety
667    ///
668    /// - The distance between the pointers must be non-negative (`self >= origin`)
669    ///
670    /// - *All* the safety conditions of [`offset_from`](#method.offset_from)
671    ///   apply to this method as well; see it for the full details.
672    ///
673    /// Importantly, despite the return type of this method being able to represent
674    /// a larger offset, it's still *not permitted* to pass pointers which differ
675    /// by more than `isize::MAX` *bytes*.  As such, the result of this method will
676    /// always be less than or equal to `isize::MAX as usize`.
677    ///
678    /// # Panics
679    ///
680    /// This function panics if `T` is a Zero-Sized Type ("ZST").
681    ///
682    /// # Examples
683    ///
684    /// ```
685    /// let a = [0; 5];
686    /// let ptr1: *const i32 = &a[1];
687    /// let ptr2: *const i32 = &a[3];
688    /// unsafe {
689    ///     assert_eq!(ptr2.offset_from_unsigned(ptr1), 2);
690    ///     assert_eq!(ptr1.add(2), ptr2);
691    ///     assert_eq!(ptr2.sub(2), ptr1);
692    ///     assert_eq!(ptr2.offset_from_unsigned(ptr2), 0);
693    /// }
694    ///
695    /// // This would be incorrect, as the pointers are not correctly ordered:
696    /// // ptr1.offset_from_unsigned(ptr2)
697    /// ```
698    #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
699    #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
700    #[inline]
701    #[track_caller]
702    pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize
703    where
704        T: Sized,
705    {
706        #[rustc_allow_const_fn_unstable(const_eval_select)]
707        const fn runtime_ptr_ge(this: *const (), origin: *const ()) -> bool {
708            const_eval_select!(
709                @capture { this: *const (), origin: *const () } -> bool:
710                if const {
711                    true
712                } else {
713                    this >= origin
714                }
715            )
716        }
717
718        ub_checks::assert_unsafe_precondition!(
719            check_language_ub,
720            "ptr::offset_from_unsigned requires `self >= origin`",
721            (
722                this: *const () = self as *const (),
723                origin: *const () = origin as *const (),
724            ) => runtime_ptr_ge(this, origin)
725        );
726
727        let pointee_size = size_of::<T>();
728        assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
729        // SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`.
730        unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
731    }
732
733    /// Calculates the distance between two pointers within the same allocation, *where it's known that
734    /// `self` is equal to or greater than `origin`*. The returned value is in
735    /// units of **bytes**.
736    ///
737    /// This is purely a convenience for casting to a `u8` pointer and
738    /// using [`offset_from_unsigned`][pointer::offset_from_unsigned] on it.
739    /// See that method for documentation and safety requirements.
740    ///
741    /// For non-`Sized` pointees this operation considers only the data pointers,
742    /// ignoring the metadata.
743    #[stable(feature = "ptr_sub_ptr", since = "1.87.0")]
744    #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")]
745    #[inline]
746    #[track_caller]
747    pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *const U) -> usize {
748        // SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`.
749        unsafe { self.cast::<u8>().offset_from_unsigned(origin.cast::<u8>()) }
750    }
751
752    /// Returns whether two pointers are guaranteed to be equal.
753    ///
754    /// At runtime this function behaves like `Some(self == other)`.
755    /// However, in some contexts (e.g., compile-time evaluation),
756    /// it is not always possible to determine equality of two pointers, so this function may
757    /// spuriously return `None` for pointers that later actually turn out to have its equality known.
758    /// But when it returns `Some`, the pointers' equality is guaranteed to be known.
759    ///
760    /// The return value may change from `Some` to `None` and vice versa depending on the compiler
761    /// version and unsafe code must not
762    /// rely on the result of this function for soundness. It is suggested to only use this function
763    /// for performance optimizations where spurious `None` return values by this function do not
764    /// affect the outcome, but just the performance.
765    /// The consequences of using this method to make runtime and compile-time code behave
766    /// differently have not been explored. This method should not be used to introduce such
767    /// differences, and it should also not be stabilized before we have a better understanding
768    /// of this issue.
769    #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
770    #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
771    #[inline]
772    pub const fn guaranteed_eq(self, other: *const T) -> Option<bool>
773    where
774        T: Sized,
775    {
776        match intrinsics::ptr_guaranteed_cmp(self, other) {
777            2 => None,
778            other => Some(other == 1),
779        }
780    }
781
782    /// Returns whether two pointers are guaranteed to be inequal.
783    ///
784    /// At runtime this function behaves like `Some(self != other)`.
785    /// However, in some contexts (e.g., compile-time evaluation),
786    /// it is not always possible to determine inequality of two pointers, so this function may
787    /// spuriously return `None` for pointers that later actually turn out to have its inequality known.
788    /// But when it returns `Some`, the pointers' inequality is guaranteed to be known.
789    ///
790    /// The return value may change from `Some` to `None` and vice versa depending on the compiler
791    /// version and unsafe code must not
792    /// rely on the result of this function for soundness. It is suggested to only use this function
793    /// for performance optimizations where spurious `None` return values by this function do not
794    /// affect the outcome, but just the performance.
795    /// The consequences of using this method to make runtime and compile-time code behave
796    /// differently have not been explored. This method should not be used to introduce such
797    /// differences, and it should also not be stabilized before we have a better understanding
798    /// of this issue.
799    #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
800    #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
801    #[inline]
802    pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
803    where
804        T: Sized,
805    {
806        match self.guaranteed_eq(other) {
807            None => None,
808            Some(eq) => Some(!eq),
809        }
810    }
811
812    #[doc = include_str!("./docs/add.md")]
813    ///
814    /// # Examples
815    ///
816    /// ```
817    /// let s: &str = "123";
818    /// let ptr: *const u8 = s.as_ptr();
819    ///
820    /// unsafe {
821    ///     assert_eq!(*ptr.add(1), b'2');
822    ///     assert_eq!(*ptr.add(2), b'3');
823    /// }
824    /// ```
825    #[stable(feature = "pointer_methods", since = "1.26.0")]
826    #[must_use = "returns a new pointer rather than modifying its argument"]
827    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
828    #[inline(always)]
829    #[track_caller]
830    pub const unsafe fn add(self, count: usize) -> Self
831    where
832        T: Sized,
833    {
834        #[cfg(debug_assertions)]
835        #[inline]
836        #[rustc_allow_const_fn_unstable(const_eval_select)]
837        const fn runtime_add_nowrap(this: *const (), count: usize, size: usize) -> bool {
838            const_eval_select!(
839                @capture { this: *const (), count: usize, size: usize } -> bool:
840                if const {
841                    true
842                } else {
843                    let Some(byte_offset) = count.checked_mul(size) else {
844                        return false;
845                    };
846                    let (_, overflow) = this.addr().overflowing_add(byte_offset);
847                    byte_offset <= (isize::MAX as usize) && !overflow
848                }
849            )
850        }
851
852        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
853        ub_checks::assert_unsafe_precondition!(
854            check_language_ub,
855            "ptr::add requires that the address calculation does not overflow",
856            (
857                this: *const () = self as *const (),
858                count: usize = count,
859                size: usize = size_of::<T>(),
860            ) => runtime_add_nowrap(this, count, size)
861        );
862
863        // SAFETY: the caller must uphold the safety contract for `offset`.
864        unsafe { intrinsics::offset(self, count) }
865    }
866
867    /// Adds an unsigned offset in bytes to a pointer.
868    ///
869    /// `count` is in units of bytes.
870    ///
871    /// This is purely a convenience for casting to a `u8` pointer and
872    /// using [add][pointer::add] on it. See that method for documentation
873    /// and safety requirements.
874    ///
875    /// For non-`Sized` pointees this operation changes only the data pointer,
876    /// leaving the metadata untouched.
877    #[must_use]
878    #[inline(always)]
879    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
880    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
881    #[track_caller]
882    pub const unsafe fn byte_add(self, count: usize) -> Self {
883        // SAFETY: the caller must uphold the safety contract for `add`.
884        unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
885    }
886
887    /// Subtracts an unsigned offset from a pointer.
888    ///
889    /// This can only move the pointer backward (or not move it). If you need to move forward or
890    /// backward depending on the value, then you might want [`offset`](#method.offset) instead
891    /// which takes a signed offset.
892    ///
893    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
894    /// offset of `3 * size_of::<T>()` bytes.
895    ///
896    /// # Safety
897    ///
898    /// If any of the following conditions are violated, the result is Undefined Behavior:
899    ///
900    /// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
901    ///   "wrapping around"), must fit in an `isize`.
902    ///
903    /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
904    ///   [allocation], and the entire memory range between `self` and the result must be in
905    ///   bounds of that allocation. In particular, this range must not "wrap around" the edge
906    ///   of the address space.
907    ///
908    /// Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
909    /// stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
910    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
911    /// safe.
912    ///
913    /// Consider using [`wrapping_sub`] instead if these constraints are
914    /// difficult to satisfy. The only advantage of this method is that it
915    /// enables more aggressive compiler optimizations.
916    ///
917    /// [`wrapping_sub`]: #method.wrapping_sub
918    /// [allocation]: crate::ptr#allocation
919    ///
920    /// # Examples
921    ///
922    /// ```
923    /// let s: &str = "123";
924    ///
925    /// unsafe {
926    ///     let end: *const u8 = s.as_ptr().add(3);
927    ///     assert_eq!(*end.sub(1), b'3');
928    ///     assert_eq!(*end.sub(2), b'2');
929    /// }
930    /// ```
931    #[stable(feature = "pointer_methods", since = "1.26.0")]
932    #[must_use = "returns a new pointer rather than modifying its argument"]
933    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
934    #[inline(always)]
935    #[track_caller]
936    pub const unsafe fn sub(self, count: usize) -> Self
937    where
938        T: Sized,
939    {
940        #[cfg(debug_assertions)]
941        #[inline]
942        #[rustc_allow_const_fn_unstable(const_eval_select)]
943        const fn runtime_sub_nowrap(this: *const (), count: usize, size: usize) -> bool {
944            const_eval_select!(
945                @capture { this: *const (), count: usize, size: usize } -> bool:
946                if const {
947                    true
948                } else {
949                    let Some(byte_offset) = count.checked_mul(size) else {
950                        return false;
951                    };
952                    byte_offset <= (isize::MAX as usize) && this.addr() >= byte_offset
953                }
954            )
955        }
956
957        #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild.
958        ub_checks::assert_unsafe_precondition!(
959            check_language_ub,
960            "ptr::sub requires that the address calculation does not overflow",
961            (
962                this: *const () = self as *const (),
963                count: usize = count,
964                size: usize = size_of::<T>(),
965            ) => runtime_sub_nowrap(this, count, size)
966        );
967
968        if T::IS_ZST {
969            // Pointer arithmetic does nothing when the pointee is a ZST.
970            self
971        } else {
972            // SAFETY: the caller must uphold the safety contract for `offset`.
973            // Because the pointee is *not* a ZST, that means that `count` is
974            // at most `isize::MAX`, and thus the negation cannot overflow.
975            unsafe { intrinsics::offset(self, intrinsics::unchecked_sub(0, count as isize)) }
976        }
977    }
978
979    /// Subtracts an unsigned offset in bytes from a pointer.
980    ///
981    /// `count` is in units of bytes.
982    ///
983    /// This is purely a convenience for casting to a `u8` pointer and
984    /// using [sub][pointer::sub] on it. See that method for documentation
985    /// and safety requirements.
986    ///
987    /// For non-`Sized` pointees this operation changes only the data pointer,
988    /// leaving the metadata untouched.
989    #[must_use]
990    #[inline(always)]
991    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
992    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
993    #[track_caller]
994    pub const unsafe fn byte_sub(self, count: usize) -> Self {
995        // SAFETY: the caller must uphold the safety contract for `sub`.
996        unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
997    }
998
999    /// Adds an unsigned offset to a pointer using wrapping arithmetic.
1000    ///
1001    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
1002    /// offset of `3 * size_of::<T>()` bytes.
1003    ///
1004    /// # Safety
1005    ///
1006    /// This operation itself is always safe, but using the resulting pointer is not.
1007    ///
1008    /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not
1009    /// be used to read or write other allocations.
1010    ///
1011    /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
1012    /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
1013    /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
1014    /// `x` and `y` point into the same allocation.
1015    ///
1016    /// Compared to [`add`], this method basically delays the requirement of staying within the
1017    /// same allocation: [`add`] is immediate Undefined Behavior when crossing object
1018    /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a
1019    /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`]
1020    /// can be optimized better and is thus preferable in performance-sensitive code.
1021    ///
1022    /// The delayed check only considers the value of the pointer that was dereferenced, not the
1023    /// intermediate values used during the computation of the final result. For example,
1024    /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
1025    /// allocation and then re-entering it later is permitted.
1026    ///
1027    /// [`add`]: #method.add
1028    /// [allocation]: crate::ptr#allocation
1029    ///
1030    /// # Examples
1031    ///
1032    /// ```
1033    /// # use std::fmt::Write;
1034    /// // Iterate using a raw pointer in increments of two elements
1035    /// let data = [1u8, 2, 3, 4, 5];
1036    /// let mut ptr: *const u8 = data.as_ptr();
1037    /// let step = 2;
1038    /// let end_rounded_up = ptr.wrapping_add(6);
1039    ///
1040    /// let mut out = String::new();
1041    /// while ptr != end_rounded_up {
1042    ///     unsafe {
1043    ///         write!(&mut out, "{}, ", *ptr)?;
1044    ///     }
1045    ///     ptr = ptr.wrapping_add(step);
1046    /// }
1047    /// assert_eq!(out, "1, 3, 5, ");
1048    /// # std::fmt::Result::Ok(())
1049    /// ```
1050    #[stable(feature = "pointer_methods", since = "1.26.0")]
1051    #[must_use = "returns a new pointer rather than modifying its argument"]
1052    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
1053    #[inline(always)]
1054    pub const fn wrapping_add(self, count: usize) -> Self
1055    where
1056        T: Sized,
1057    {
1058        self.wrapping_offset(count as isize)
1059    }
1060
1061    /// Adds an unsigned offset in bytes to a pointer using wrapping arithmetic.
1062    ///
1063    /// `count` is in units of bytes.
1064    ///
1065    /// This is purely a convenience for casting to a `u8` pointer and
1066    /// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
1067    ///
1068    /// For non-`Sized` pointees this operation changes only the data pointer,
1069    /// leaving the metadata untouched.
1070    #[must_use]
1071    #[inline(always)]
1072    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
1073    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
1074    pub const fn wrapping_byte_add(self, count: usize) -> Self {
1075        self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
1076    }
1077
1078    /// Subtracts an unsigned offset from a pointer using wrapping arithmetic.
1079    ///
1080    /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
1081    /// offset of `3 * size_of::<T>()` bytes.
1082    ///
1083    /// # Safety
1084    ///
1085    /// This operation itself is always safe, but using the resulting pointer is not.
1086    ///
1087    /// The resulting pointer "remembers" the [allocation] that `self` points to; it must not
1088    /// be used to read or write other allocations.
1089    ///
1090    /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
1091    /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
1092    /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
1093    /// `x` and `y` point into the same allocation.
1094    ///
1095    /// Compared to [`sub`], this method basically delays the requirement of staying within the
1096    /// same allocation: [`sub`] is immediate Undefined Behavior when crossing object
1097    /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a
1098    /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`]
1099    /// can be optimized better and is thus preferable in performance-sensitive code.
1100    ///
1101    /// The delayed check only considers the value of the pointer that was dereferenced, not the
1102    /// intermediate values used during the computation of the final result. For example,
1103    /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
1104    /// allocation and then re-entering it later is permitted.
1105    ///
1106    /// [`sub`]: #method.sub
1107    /// [allocation]: crate::ptr#allocation
1108    ///
1109    /// # Examples
1110    ///
1111    /// ```
1112    /// # use std::fmt::Write;
1113    /// // Iterate using a raw pointer in increments of two elements (backwards)
1114    /// let data = [1u8, 2, 3, 4, 5];
1115    /// let mut ptr: *const u8 = data.as_ptr();
1116    /// let start_rounded_down = ptr.wrapping_sub(2);
1117    /// ptr = ptr.wrapping_add(4);
1118    /// let step = 2;
1119    /// let mut out = String::new();
1120    /// while ptr != start_rounded_down {
1121    ///     unsafe {
1122    ///         write!(&mut out, "{}, ", *ptr)?;
1123    ///     }
1124    ///     ptr = ptr.wrapping_sub(step);
1125    /// }
1126    /// assert_eq!(out, "5, 3, 1, ");
1127    /// # std::fmt::Result::Ok(())
1128    /// ```
1129    #[stable(feature = "pointer_methods", since = "1.26.0")]
1130    #[must_use = "returns a new pointer rather than modifying its argument"]
1131    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
1132    #[inline(always)]
1133    pub const fn wrapping_sub(self, count: usize) -> Self
1134    where
1135        T: Sized,
1136    {
1137        self.wrapping_offset((count as isize).wrapping_neg())
1138    }
1139
1140    /// Subtracts an unsigned offset in bytes from a pointer using wrapping arithmetic.
1141    ///
1142    /// `count` is in units of bytes.
1143    ///
1144    /// This is purely a convenience for casting to a `u8` pointer and
1145    /// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
1146    ///
1147    /// For non-`Sized` pointees this operation changes only the data pointer,
1148    /// leaving the metadata untouched.
1149    #[must_use]
1150    #[inline(always)]
1151    #[stable(feature = "pointer_byte_offsets", since = "1.75.0")]
1152    #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")]
1153    pub const fn wrapping_byte_sub(self, count: usize) -> Self {
1154        self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
1155    }
1156
1157    /// Reads the value from `self` without moving it. This leaves the
1158    /// memory in `self` unchanged.
1159    ///
1160    /// See [`ptr::read`] for safety concerns and examples.
1161    ///
1162    /// [`ptr::read`]: crate::ptr::read()
1163    #[stable(feature = "pointer_methods", since = "1.26.0")]
1164    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
1165    #[inline]
1166    #[track_caller]
1167    pub const unsafe fn read(self) -> T
1168    where
1169        T: Sized,
1170    {
1171        // SAFETY: the caller must uphold the safety contract for `read`.
1172        unsafe { read(self) }
1173    }
1174
1175    /// Performs a volatile read of the value from `self` without moving it. This
1176    /// leaves the memory in `self` unchanged.
1177    ///
1178    /// Volatile operations are intended to act on I/O memory, and are guaranteed
1179    /// to not be elided or reordered by the compiler across other volatile
1180    /// operations.
1181    ///
1182    /// See [`ptr::read_volatile`] for safety concerns and examples.
1183    ///
1184    /// [`ptr::read_volatile`]: crate::ptr::read_volatile()
1185    #[stable(feature = "pointer_methods", since = "1.26.0")]
1186    #[inline]
1187    #[track_caller]
1188    pub unsafe fn read_volatile(self) -> T
1189    where
1190        T: Sized,
1191    {
1192        // SAFETY: the caller must uphold the safety contract for `read_volatile`.
1193        unsafe { read_volatile(self) }
1194    }
1195
1196    /// Reads the value from `self` without moving it. This leaves the
1197    /// memory in `self` unchanged.
1198    ///
1199    /// Unlike `read`, the pointer may be unaligned.
1200    ///
1201    /// See [`ptr::read_unaligned`] for safety concerns and examples.
1202    ///
1203    /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
1204    #[stable(feature = "pointer_methods", since = "1.26.0")]
1205    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
1206    #[inline]
1207    #[track_caller]
1208    pub const unsafe fn read_unaligned(self) -> T
1209    where
1210        T: Sized,
1211    {
1212        // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
1213        unsafe { read_unaligned(self) }
1214    }
1215
1216    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
1217    /// and destination may overlap.
1218    ///
1219    /// NOTE: this has the *same* argument order as [`ptr::copy`].
1220    ///
1221    /// See [`ptr::copy`] for safety concerns and examples.
1222    ///
1223    /// [`ptr::copy`]: crate::ptr::copy()
1224    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
1225    #[stable(feature = "pointer_methods", since = "1.26.0")]
1226    #[inline]
1227    #[track_caller]
1228    pub const unsafe fn copy_to(self, dest: *mut T, count: usize)
1229    where
1230        T: Sized,
1231    {
1232        // SAFETY: the caller must uphold the safety contract for `copy`.
1233        unsafe { copy(self, dest, count) }
1234    }
1235
1236    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
1237    /// and destination may *not* overlap.
1238    ///
1239    /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
1240    ///
1241    /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
1242    ///
1243    /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
1244    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
1245    #[stable(feature = "pointer_methods", since = "1.26.0")]
1246    #[inline]
1247    #[track_caller]
1248    pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
1249    where
1250        T: Sized,
1251    {
1252        // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
1253        unsafe { copy_nonoverlapping(self, dest, count) }
1254    }
1255
1256    /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
1257    /// `align`.
1258    ///
1259    /// If it is not possible to align the pointer, the implementation returns
1260    /// `usize::MAX`.
1261    ///
1262    /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
1263    /// used with the `wrapping_add` method.
1264    ///
1265    /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
1266    /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
1267    /// the returned offset is correct in all terms other than alignment.
1268    ///
1269    /// # Panics
1270    ///
1271    /// The function panics if `align` is not a power-of-two.
1272    ///
1273    /// # Examples
1274    ///
1275    /// Accessing adjacent `u8` as `u16`
1276    ///
1277    /// ```
1278    /// # unsafe {
1279    /// let x = [5_u8, 6, 7, 8, 9];
1280    /// let ptr = x.as_ptr();
1281    /// let offset = ptr.align_offset(align_of::<u16>());
1282    ///
1283    /// if offset < x.len() - 1 {
1284    ///     let u16_ptr = ptr.add(offset).cast::<u16>();
1285    ///     assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7]));
1286    /// } else {
1287    ///     // while the pointer can be aligned via `offset`, it would point
1288    ///     // outside the allocation
1289    /// }
1290    /// # }
1291    /// ```
1292    #[must_use]
1293    #[inline]
1294    #[stable(feature = "align_offset", since = "1.36.0")]
1295    pub fn align_offset(self, align: usize) -> usize
1296    where
1297        T: Sized,
1298    {
1299        if !align.is_power_of_two() {
1300            panic!("align_offset: align is not a power-of-two");
1301        }
1302
1303        // SAFETY: `align` has been checked to be a power of 2 above
1304        let ret = unsafe { align_offset(self, align) };
1305
1306        // Inform Miri that we want to consider the resulting pointer to be suitably aligned.
1307        #[cfg(miri)]
1308        if ret != usize::MAX {
1309            intrinsics::miri_promise_symbolic_alignment(self.wrapping_add(ret).cast(), align);
1310        }
1311
1312        ret
1313    }
1314
1315    /// Returns whether the pointer is properly aligned for `T`.
1316    ///
1317    /// # Examples
1318    ///
1319    /// ```
1320    /// // On some platforms, the alignment of i32 is less than 4.
1321    /// #[repr(align(4))]
1322    /// struct AlignedI32(i32);
1323    ///
1324    /// let data = AlignedI32(42);
1325    /// let ptr = &data as *const AlignedI32;
1326    ///
1327    /// assert!(ptr.is_aligned());
1328    /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
1329    /// ```
1330    #[must_use]
1331    #[inline]
1332    #[stable(feature = "pointer_is_aligned", since = "1.79.0")]
1333    pub fn is_aligned(self) -> bool
1334    where
1335        T: Sized,
1336    {
1337        self.is_aligned_to(align_of::<T>())
1338    }
1339
1340    /// Returns whether the pointer is aligned to `align`.
1341    ///
1342    /// For non-`Sized` pointees this operation considers only the data pointer,
1343    /// ignoring the metadata.
1344    ///
1345    /// # Panics
1346    ///
1347    /// The function panics if `align` is not a power-of-two (this includes 0).
1348    ///
1349    /// # Examples
1350    ///
1351    /// ```
1352    /// #![feature(pointer_is_aligned_to)]
1353    ///
1354    /// // On some platforms, the alignment of i32 is less than 4.
1355    /// #[repr(align(4))]
1356    /// struct AlignedI32(i32);
1357    ///
1358    /// let data = AlignedI32(42);
1359    /// let ptr = &data as *const AlignedI32;
1360    ///
1361    /// assert!(ptr.is_aligned_to(1));
1362    /// assert!(ptr.is_aligned_to(2));
1363    /// assert!(ptr.is_aligned_to(4));
1364    ///
1365    /// assert!(ptr.wrapping_byte_add(2).is_aligned_to(2));
1366    /// assert!(!ptr.wrapping_byte_add(2).is_aligned_to(4));
1367    ///
1368    /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
1369    /// ```
1370    #[must_use]
1371    #[inline]
1372    #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
1373    pub fn is_aligned_to(self, align: usize) -> bool {
1374        if !align.is_power_of_two() {
1375            panic!("is_aligned_to: align is not a power-of-two");
1376        }
1377
1378        self.addr() & (align - 1) == 0
1379    }
1380}
1381
1382impl<T> *const T {
1383    /// Casts from a type to its maybe-uninitialized version.
1384    #[must_use]
1385    #[inline(always)]
1386    #[unstable(feature = "cast_maybe_uninit", issue = "145036")]
1387    pub const fn cast_uninit(self) -> *const MaybeUninit<T> {
1388        self as _
1389    }
1390
1391    /// Forms a raw slice from a pointer and a length.
1392    ///
1393    /// The `len` argument is the number of **elements**, not the number of bytes.
1394    ///
1395    /// This function is safe, but actually using the return value is unsafe.
1396    /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements.
1397    ///
1398    /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
1399    ///
1400    /// # Examples
1401    ///
1402    /// ```rust
1403    /// #![feature(ptr_cast_slice)]
1404    ///
1405    /// // create a slice pointer when starting out with a pointer to the first element
1406    /// let x = [5, 6, 7];
1407    /// let raw_slice = x.as_ptr().cast_slice(3);
1408    /// assert_eq!(unsafe { &*raw_slice }[2], 7);
1409    /// ```
1410    ///
1411    /// You must ensure that the pointer is valid and not null before dereferencing
1412    /// the raw slice. A slice reference must never have a null pointer, even if it's empty.
1413    ///
1414    /// ```rust,should_panic
1415    /// #![feature(ptr_cast_slice)]
1416    /// use std::ptr;
1417    /// let danger: *const [u8] = ptr::null::<u8>().cast_slice(0);
1418    /// unsafe {
1419    ///     danger.as_ref().expect("references must not be null");
1420    /// }
1421    /// ```
1422    #[inline]
1423    #[unstable(feature = "ptr_cast_slice", issue = "149103")]
1424    pub const fn cast_slice(self, len: usize) -> *const [T] {
1425        slice_from_raw_parts(self, len)
1426    }
1427}
1428impl<T> *const MaybeUninit<T> {
1429    /// Casts from a maybe-uninitialized type to its initialized version.
1430    ///
1431    /// This is always safe, since UB can only occur if the pointer is read
1432    /// before being initialized.
1433    #[must_use]
1434    #[inline(always)]
1435    #[unstable(feature = "cast_maybe_uninit", issue = "145036")]
1436    pub const fn cast_init(self) -> *const T {
1437        self as _
1438    }
1439}
1440
1441impl<T> *const [T] {
1442    /// Returns the length of a raw slice.
1443    ///
1444    /// The returned value is the number of **elements**, not the number of bytes.
1445    ///
1446    /// This function is safe, even when the raw slice cannot be cast to a slice
1447    /// reference because the pointer is null or unaligned.
1448    ///
1449    /// # Examples
1450    ///
1451    /// ```rust
1452    /// use std::ptr;
1453    ///
1454    /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
1455    /// assert_eq!(slice.len(), 3);
1456    /// ```
1457    #[inline]
1458    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
1459    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
1460    pub const fn len(self) -> usize {
1461        metadata(self)
1462    }
1463
1464    /// Returns `true` if the raw slice has a length of 0.
1465    ///
1466    /// # Examples
1467    ///
1468    /// ```
1469    /// use std::ptr;
1470    ///
1471    /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
1472    /// assert!(!slice.is_empty());
1473    /// ```
1474    #[inline(always)]
1475    #[stable(feature = "slice_ptr_len", since = "1.79.0")]
1476    #[rustc_const_stable(feature = "const_slice_ptr_len", since = "1.79.0")]
1477    pub const fn is_empty(self) -> bool {
1478        self.len() == 0
1479    }
1480
1481    /// Returns a raw pointer to the slice's buffer.
1482    ///
1483    /// This is equivalent to casting `self` to `*const T`, but more type-safe.
1484    ///
1485    /// # Examples
1486    ///
1487    /// ```rust
1488    /// #![feature(slice_ptr_get)]
1489    /// use std::ptr;
1490    ///
1491    /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
1492    /// assert_eq!(slice.as_ptr(), ptr::null());
1493    /// ```
1494    #[inline]
1495    #[unstable(feature = "slice_ptr_get", issue = "74265")]
1496    pub const fn as_ptr(self) -> *const T {
1497        self as *const T
1498    }
1499
1500    /// Gets a raw pointer to the underlying array.
1501    ///
1502    /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1503    #[stable(feature = "core_slice_as_array", since = "1.93.0")]
1504    #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")]
1505    #[inline]
1506    #[must_use]
1507    pub const fn as_array<const N: usize>(self) -> Option<*const [T; N]> {
1508        if self.len() == N {
1509            let me = self.as_ptr() as *const [T; N];
1510            Some(me)
1511        } else {
1512            None
1513        }
1514    }
1515
1516    /// Returns a raw pointer to an element or subslice, without doing bounds
1517    /// checking.
1518    ///
1519    /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
1520    /// is *[undefined behavior]* even if the resulting pointer is not used.
1521    ///
1522    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1523    ///
1524    /// # Examples
1525    ///
1526    /// ```
1527    /// #![feature(slice_ptr_get)]
1528    ///
1529    /// let x = &[1, 2, 4] as *const [i32];
1530    ///
1531    /// unsafe {
1532    ///     assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
1533    /// }
1534    /// ```
1535    #[unstable(feature = "slice_ptr_get", issue = "74265")]
1536    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
1537    #[inline]
1538    pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
1539    where
1540        I: [const] SliceIndex<[T]>,
1541    {
1542        // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
1543        unsafe { index.get_unchecked(self) }
1544    }
1545
1546    #[doc = include_str!("docs/as_uninit_slice.md")]
1547    #[inline]
1548    #[unstable(feature = "ptr_as_uninit", issue = "75402")]
1549    pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
1550        if self.is_null() {
1551            None
1552        } else {
1553            // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
1554            Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
1555        }
1556    }
1557}
1558
1559impl<T> *const T {
1560    /// Casts from a pointer-to-`T` to a pointer-to-`[T; N]`.
1561    #[inline]
1562    #[unstable(feature = "ptr_cast_array", issue = "144514")]
1563    pub const fn cast_array<const N: usize>(self) -> *const [T; N] {
1564        self.cast()
1565    }
1566}
1567
1568impl<T, const N: usize> *const [T; N] {
1569    /// Returns a raw pointer to the array's buffer.
1570    ///
1571    /// This is equivalent to casting `self` to `*const T`, but more type-safe.
1572    ///
1573    /// # Examples
1574    ///
1575    /// ```rust
1576    /// #![feature(array_ptr_get)]
1577    /// use std::ptr;
1578    ///
1579    /// let arr: *const [i8; 3] = ptr::null();
1580    /// assert_eq!(arr.as_ptr(), ptr::null());
1581    /// ```
1582    #[inline]
1583    #[unstable(feature = "array_ptr_get", issue = "119834")]
1584    pub const fn as_ptr(self) -> *const T {
1585        self as *const T
1586    }
1587
1588    /// Returns a raw pointer to a slice containing the entire array.
1589    ///
1590    /// # Examples
1591    ///
1592    /// ```
1593    /// #![feature(array_ptr_get)]
1594    ///
1595    /// let arr: *const [i32; 3] = &[1, 2, 4] as *const [i32; 3];
1596    /// let slice: *const [i32] = arr.as_slice();
1597    /// assert_eq!(slice.len(), 3);
1598    /// ```
1599    #[inline]
1600    #[unstable(feature = "array_ptr_get", issue = "119834")]
1601    pub const fn as_slice(self) -> *const [T] {
1602        self
1603    }
1604}
1605
1606/// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method.
1607#[stable(feature = "rust1", since = "1.0.0")]
1608#[diagnostic::on_const(
1609    message = "pointers cannot be reliably compared during const eval",
1610    note = "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information"
1611)]
1612impl<T: PointeeSized> PartialEq for *const T {
1613    #[inline]
1614    #[allow(ambiguous_wide_pointer_comparisons)]
1615    fn eq(&self, other: &*const T) -> bool {
1616        *self == *other
1617    }
1618}
1619
1620/// Pointer equality is an equivalence relation.
1621#[stable(feature = "rust1", since = "1.0.0")]
1622#[diagnostic::on_const(
1623    message = "pointers cannot be reliably compared during const eval",
1624    note = "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information"
1625)]
1626impl<T: PointeeSized> Eq for *const T {}
1627
1628/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
1629#[stable(feature = "rust1", since = "1.0.0")]
1630#[diagnostic::on_const(
1631    message = "pointers cannot be reliably compared during const eval",
1632    note = "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information"
1633)]
1634impl<T: PointeeSized> Ord for *const T {
1635    #[inline]
1636    #[allow(ambiguous_wide_pointer_comparisons)]
1637    fn cmp(&self, other: &*const T) -> Ordering {
1638        if self < other {
1639            Less
1640        } else if self == other {
1641            Equal
1642        } else {
1643            Greater
1644        }
1645    }
1646}
1647
1648/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
1649#[stable(feature = "rust1", since = "1.0.0")]
1650#[diagnostic::on_const(
1651    message = "pointers cannot be reliably compared during const eval",
1652    note = "see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information"
1653)]
1654impl<T: PointeeSized> PartialOrd for *const T {
1655    #[inline]
1656    #[allow(ambiguous_wide_pointer_comparisons)]
1657    fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
1658        Some(self.cmp(other))
1659    }
1660
1661    #[inline]
1662    #[allow(ambiguous_wide_pointer_comparisons)]
1663    fn lt(&self, other: &*const T) -> bool {
1664        *self < *other
1665    }
1666
1667    #[inline]
1668    #[allow(ambiguous_wide_pointer_comparisons)]
1669    fn le(&self, other: &*const T) -> bool {
1670        *self <= *other
1671    }
1672
1673    #[inline]
1674    #[allow(ambiguous_wide_pointer_comparisons)]
1675    fn gt(&self, other: &*const T) -> bool {
1676        *self > *other
1677    }
1678
1679    #[inline]
1680    #[allow(ambiguous_wide_pointer_comparisons)]
1681    fn ge(&self, other: &*const T) -> bool {
1682        *self >= *other
1683    }
1684}
1685
1686#[stable(feature = "raw_ptr_default", since = "1.88.0")]
1687impl<T: ?Sized + Thin> Default for *const T {
1688    /// Returns the default value of [`null()`][crate::ptr::null].
1689    fn default() -> Self {
1690        crate::ptr::null()
1691    }
1692}