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