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