]> git.lizzy.rs Git - rust.git/blob - library/core/src/ptr/const_ptr.rs
Rollup merge of #94703 - kjetilkjeka:nvptx-kernel-args-abi2, r=nagisa
[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;
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         // Compare via a cast to a thin pointer, so fat pointers are only
38         // considering their "data" part for null-ness.
39         (self as *const u8).guaranteed_eq(null())
40     }
41
42     /// Casts to a pointer of another type.
43     #[stable(feature = "ptr_cast", since = "1.38.0")]
44     #[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
45     #[inline]
46     pub const fn cast<U>(self) -> *const U {
47         self as _
48     }
49
50     /// Use the pointer value in a new pointer of another type.
51     ///
52     /// In case `val` is a (fat) pointer to an unsized type, this operation
53     /// will ignore the pointer part, whereas for (thin) pointers to sized
54     /// types, this has the same effect as a simple cast.
55     ///
56     /// The resulting pointer will have provenance of `self`, i.e., for a fat
57     /// pointer, this operation is semantically the same as creating a new
58     /// fat pointer with the data pointer value of `self` but the metadata of
59     /// `val`.
60     ///
61     /// # Examples
62     ///
63     /// This function is primarily useful for allowing byte-wise pointer
64     /// arithmetic on potentially fat pointers:
65     ///
66     /// ```
67     /// #![feature(set_ptr_value)]
68     /// # use core::fmt::Debug;
69     /// let arr: [i32; 3] = [1, 2, 3];
70     /// let mut ptr = arr.as_ptr() as *const dyn Debug;
71     /// let thin = ptr as *const u8;
72     /// unsafe {
73     ///     ptr = thin.add(8).with_metadata_of(ptr);
74     ///     # assert_eq!(*(ptr as *const i32), 3);
75     ///     println!("{:?}", &*ptr); // will print "3"
76     /// }
77     /// ```
78     #[unstable(feature = "set_ptr_value", issue = "75091")]
79     #[must_use = "returns a new pointer rather than modifying its argument"]
80     #[inline]
81     pub fn with_metadata_of<U>(self, mut val: *const U) -> *const U
82     where
83         U: ?Sized,
84     {
85         let target = &mut val as *mut *const U as *mut *const u8;
86         // SAFETY: In case of a thin pointer, this operations is identical
87         // to a simple assignment. In case of a fat pointer, with the current
88         // fat pointer layout implementation, the first field of such a
89         // pointer is always the data pointer, which is likewise assigned.
90         unsafe { *target = self as *const u8 };
91         val
92     }
93
94     /// Changes constness without changing the type.
95     ///
96     /// This is a bit safer than `as` because it wouldn't silently change the type if the code is
97     /// refactored.
98     #[unstable(feature = "ptr_const_cast", issue = "92675")]
99     #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")]
100     pub const fn as_mut(self) -> *mut T {
101         self as _
102     }
103
104     /// Casts a pointer to its raw bits.
105     ///
106     /// This is equivalent to `as usize`, but is more specific to enhance readability.
107     /// The inverse method is [`from_bits`](#method.from_bits).
108     ///
109     /// In particular, `*p as usize` and `p as usize` will both compile for
110     /// pointers to numeric types but do very different things, so using this
111     /// helps emphasize that reading the bits was intentional.
112     ///
113     /// # Examples
114     ///
115     /// ```
116     /// #![feature(ptr_to_from_bits)]
117     /// let array = [13, 42];
118     /// let p0: *const i32 = &array[0];
119     /// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
120     /// let p1: *const i32 = &array[1];
121     /// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
122     /// ```
123     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
124     pub fn to_bits(self) -> usize
125     where
126         T: Sized,
127     {
128         self as usize
129     }
130
131     /// Creates a pointer from its raw bits.
132     ///
133     /// This is equivalent to `as *const T`, but is more specific to enhance readability.
134     /// The inverse method is [`to_bits`](#method.to_bits).
135     ///
136     /// # Examples
137     ///
138     /// ```
139     /// #![feature(ptr_to_from_bits)]
140     /// use std::ptr::NonNull;
141     /// let dangling: *const u8 = NonNull::dangling().as_ptr();
142     /// assert_eq!(<*const u8>::from_bits(1), dangling);
143     /// ```
144     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
145     pub fn from_bits(bits: usize) -> Self
146     where
147         T: Sized,
148     {
149         bits as Self
150     }
151
152     /// Gets the "address" portion of the pointer.
153     ///
154     /// This is similar to `self as usize`, which semantically discards *provenance* and
155     /// *address-space* information. However, unlike `self as usize`, casting the returned address
156     /// back to a pointer yields [`invalid`][], which is undefined behavior to dereference. To
157     /// properly restore the lost information and obtain a dereferencable pointer, use
158     /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
159     ///
160     /// If using those APIs is not possible because there is no way to preserve a pointer with the
161     /// required provenance, use [`expose_addr`][pointer::expose_addr] and
162     /// [`from_exposed_addr`][from_exposed_addr] instead. However, note that this makes
163     /// your code less portable and less amenable to tools that check for compliance with the Rust
164     /// memory model.
165     ///
166     /// On most platforms this will produce a value with the same bytes as the original
167     /// pointer, because all the bytes are dedicated to describing the address.
168     /// Platforms which need to store additional information in the pointer may
169     /// perform a change of representation to produce a value containing only the address
170     /// portion of the pointer. What that means is up to the platform to define.
171     ///
172     /// This API and its claimed semantics are part of the Strict Provenance experiment, and as such
173     /// might change in the future (including possibly weakening this so it becomes wholly
174     /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details.
175     #[must_use]
176     #[inline]
177     #[unstable(feature = "strict_provenance", issue = "95228")]
178     pub fn addr(self) -> usize
179     where
180         T: Sized,
181     {
182         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
183         self as usize
184     }
185
186     /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
187     /// use in [`from_exposed_addr`][].
188     ///
189     /// This is equivalent to `self as usize`, which semantically discards *provenance* and
190     /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
191     /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
192     /// later call [`from_exposed_addr`][] to reconstitute the original pointer including its
193     /// provenance. (Reconstructing address space information, if required, is your responsibility.)
194     ///
195     /// Using this method means that code is *not* following Strict Provenance rules. Supporting
196     /// [`from_exposed_addr`][] complicates specification and reasoning and may not be supported by
197     /// tools that help you to stay conformant with the Rust memory model, so it is recommended to
198     /// use [`addr`][pointer::addr] wherever possible.
199     ///
200     /// On most platforms this will produce a value with the same bytes as the original pointer,
201     /// because all the bytes are dedicated to describing the address. Platforms which need to store
202     /// additional information in the pointer may not support this operation, since the 'expose'
203     /// side-effect which is required for [`from_exposed_addr`][] to work is typically not
204     /// available.
205     ///
206     /// This API and its claimed semantics are part of the Strict Provenance experiment, see the
207     /// [module documentation][crate::ptr] for details.
208     ///
209     /// [`from_exposed_addr`]: from_exposed_addr
210     #[must_use]
211     #[inline]
212     #[unstable(feature = "strict_provenance", issue = "95228")]
213     pub fn expose_addr(self) -> usize
214     where
215         T: Sized,
216     {
217         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
218         self as usize
219     }
220
221     /// Creates a new pointer with the given address.
222     ///
223     /// This performs the same operation as an `addr as ptr` cast, but copies
224     /// the *address-space* and *provenance* of `self` to the new pointer.
225     /// This allows us to dynamically preserve and propagate this important
226     /// information in a way that is otherwise impossible with a unary cast.
227     ///
228     /// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
229     /// `self` to the given address, and therefore has all the same capabilities and restrictions.
230     ///
231     /// This API and its claimed semantics are part of the Strict Provenance experiment,
232     /// see the [module documentation][crate::ptr] for details.
233     #[must_use]
234     #[inline]
235     #[unstable(feature = "strict_provenance", issue = "95228")]
236     pub fn with_addr(self, addr: usize) -> Self
237     where
238         T: Sized,
239     {
240         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
241         //
242         // In the mean-time, this operation is defined to be "as if" it was
243         // a wrapping_offset, so we can emulate it as such. This should properly
244         // restore pointer provenance even under today's compiler.
245         let self_addr = self.addr() as isize;
246         let dest_addr = addr as isize;
247         let offset = dest_addr.wrapping_sub(self_addr);
248
249         // This is the canonical desugarring of this operation
250         self.cast::<u8>().wrapping_offset(offset).cast::<T>()
251     }
252
253     /// Creates a new pointer by mapping `self`'s address to a new one.
254     ///
255     /// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
256     ///
257     /// This API and its claimed semantics are part of the Strict Provenance experiment,
258     /// see the [module documentation][crate::ptr] for details.
259     #[must_use]
260     #[inline]
261     #[unstable(feature = "strict_provenance", issue = "95228")]
262     pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self
263     where
264         T: Sized,
265     {
266         self.with_addr(f(self.addr()))
267     }
268
269     /// Decompose a (possibly wide) pointer into its address and metadata components.
270     ///
271     /// The pointer can be later reconstructed with [`from_raw_parts`].
272     #[unstable(feature = "ptr_metadata", issue = "81513")]
273     #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
274     #[inline]
275     pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata) {
276         (self.cast(), metadata(self))
277     }
278
279     /// Returns `None` if the pointer is null, or else returns a shared reference to
280     /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
281     /// must be used instead.
282     ///
283     /// [`as_uninit_ref`]: #method.as_uninit_ref
284     ///
285     /// # Safety
286     ///
287     /// When calling this method, you have to ensure that *either* the pointer is null *or*
288     /// all of the following is true:
289     ///
290     /// * The pointer must be properly aligned.
291     ///
292     /// * It must be "dereferenceable" in the sense defined in [the module documentation].
293     ///
294     /// * The pointer must point to an initialized instance of `T`.
295     ///
296     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
297     ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
298     ///   In particular, while this reference exists, the memory the pointer points to must
299     ///   not get mutated (except inside `UnsafeCell`).
300     ///
301     /// This applies even if the result of this method is unused!
302     /// (The part about being initialized is not yet fully decided, but until
303     /// it is, the only safe approach is to ensure that they are indeed initialized.)
304     ///
305     /// [the module documentation]: crate::ptr#safety
306     ///
307     /// # Examples
308     ///
309     /// Basic usage:
310     ///
311     /// ```
312     /// let ptr: *const u8 = &10u8 as *const u8;
313     ///
314     /// unsafe {
315     ///     if let Some(val_back) = ptr.as_ref() {
316     ///         println!("We got back the value: {val_back}!");
317     ///     }
318     /// }
319     /// ```
320     ///
321     /// # Null-unchecked version
322     ///
323     /// If you are sure the pointer can never be null and are looking for some kind of
324     /// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
325     /// dereference the pointer directly.
326     ///
327     /// ```
328     /// let ptr: *const u8 = &10u8 as *const u8;
329     ///
330     /// unsafe {
331     ///     let val_back = &*ptr;
332     ///     println!("We got back the value: {val_back}!");
333     /// }
334     /// ```
335     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
336     #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
337     #[inline]
338     pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
339         // SAFETY: the caller must guarantee that `self` is valid
340         // for a reference if it isn't null.
341         if self.is_null() { None } else { unsafe { Some(&*self) } }
342     }
343
344     /// Returns `None` if the pointer is null, or else returns a shared reference to
345     /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
346     /// that the value has to be initialized.
347     ///
348     /// [`as_ref`]: #method.as_ref
349     ///
350     /// # Safety
351     ///
352     /// When calling this method, you have to ensure that *either* the pointer is null *or*
353     /// all of the following is true:
354     ///
355     /// * The pointer must be properly aligned.
356     ///
357     /// * It must be "dereferenceable" in the sense defined in [the module documentation].
358     ///
359     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
360     ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
361     ///   In particular, while this reference exists, the memory the pointer points to must
362     ///   not get mutated (except inside `UnsafeCell`).
363     ///
364     /// This applies even if the result of this method is unused!
365     ///
366     /// [the module documentation]: crate::ptr#safety
367     ///
368     /// # Examples
369     ///
370     /// Basic usage:
371     ///
372     /// ```
373     /// #![feature(ptr_as_uninit)]
374     ///
375     /// let ptr: *const u8 = &10u8 as *const u8;
376     ///
377     /// unsafe {
378     ///     if let Some(val_back) = ptr.as_uninit_ref() {
379     ///         println!("We got back the value: {}!", val_back.assume_init());
380     ///     }
381     /// }
382     /// ```
383     #[inline]
384     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
385     #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
386     pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
387     where
388         T: Sized,
389     {
390         // SAFETY: the caller must guarantee that `self` meets all the
391         // requirements for a reference.
392         if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
393     }
394
395     /// Calculates the offset from a pointer.
396     ///
397     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
398     /// offset of `3 * size_of::<T>()` bytes.
399     ///
400     /// # Safety
401     ///
402     /// If any of the following conditions are violated, the result is Undefined
403     /// Behavior:
404     ///
405     /// * Both the starting and resulting pointer must be either in bounds or one
406     ///   byte past the end of the same [allocated object].
407     ///
408     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
409     ///
410     /// * The offset being in bounds cannot rely on "wrapping around" the address
411     ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
412     ///
413     /// The compiler and standard library generally tries to ensure allocations
414     /// never reach a size where an offset is a concern. For instance, `Vec`
415     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
416     /// `vec.as_ptr().add(vec.len())` is always safe.
417     ///
418     /// Most platforms fundamentally can't even construct such an allocation.
419     /// For instance, no known 64-bit platform can ever serve a request
420     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
421     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
422     /// more than `isize::MAX` bytes with things like Physical Address
423     /// Extension. As such, memory acquired directly from allocators or memory
424     /// mapped files *may* be too large to handle with this function.
425     ///
426     /// Consider using [`wrapping_offset`] instead if these constraints are
427     /// difficult to satisfy. The only advantage of this method is that it
428     /// enables more aggressive compiler optimizations.
429     ///
430     /// [`wrapping_offset`]: #method.wrapping_offset
431     /// [allocated object]: crate::ptr#allocated-object
432     ///
433     /// # Examples
434     ///
435     /// Basic usage:
436     ///
437     /// ```
438     /// let s: &str = "123";
439     /// let ptr: *const u8 = s.as_ptr();
440     ///
441     /// unsafe {
442     ///     println!("{}", *ptr.offset(1) as char);
443     ///     println!("{}", *ptr.offset(2) as char);
444     /// }
445     /// ```
446     #[stable(feature = "rust1", since = "1.0.0")]
447     #[must_use = "returns a new pointer rather than modifying its argument"]
448     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
449     #[inline(always)]
450     pub const unsafe fn offset(self, count: isize) -> *const T
451     where
452         T: Sized,
453     {
454         // SAFETY: the caller must uphold the safety contract for `offset`.
455         unsafe { intrinsics::offset(self, count) }
456     }
457
458     /// Calculates the offset from a pointer using wrapping arithmetic.
459     ///
460     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
461     /// offset of `3 * size_of::<T>()` bytes.
462     ///
463     /// # Safety
464     ///
465     /// This operation itself is always safe, but using the resulting pointer is not.
466     ///
467     /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
468     /// be used to read or write other allocated objects.
469     ///
470     /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
471     /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
472     /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
473     /// `x` and `y` point into the same allocated object.
474     ///
475     /// Compared to [`offset`], this method basically delays the requirement of staying within the
476     /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object
477     /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a
478     /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`]
479     /// can be optimized better and is thus preferable in performance-sensitive code.
480     ///
481     /// The delayed check only considers the value of the pointer that was dereferenced, not the
482     /// intermediate values used during the computation of the final result. For example,
483     /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other
484     /// words, leaving the allocated object and then re-entering it later is permitted.
485     ///
486     /// [`offset`]: #method.offset
487     /// [allocated object]: crate::ptr#allocated-object
488     ///
489     /// # Examples
490     ///
491     /// Basic usage:
492     ///
493     /// ```
494     /// // Iterate using a raw pointer in increments of two elements
495     /// let data = [1u8, 2, 3, 4, 5];
496     /// let mut ptr: *const u8 = data.as_ptr();
497     /// let step = 2;
498     /// let end_rounded_up = ptr.wrapping_offset(6);
499     ///
500     /// // This loop prints "1, 3, 5, "
501     /// while ptr != end_rounded_up {
502     ///     unsafe {
503     ///         print!("{}, ", *ptr);
504     ///     }
505     ///     ptr = ptr.wrapping_offset(step);
506     /// }
507     /// ```
508     #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
509     #[must_use = "returns a new pointer rather than modifying its argument"]
510     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
511     #[inline(always)]
512     pub const fn wrapping_offset(self, count: isize) -> *const T
513     where
514         T: Sized,
515     {
516         // SAFETY: the `arith_offset` intrinsic has no prerequisites to be called.
517         unsafe { intrinsics::arith_offset(self, count) }
518     }
519
520     /// Calculates the distance between two pointers. The returned value is in
521     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
522     ///
523     /// This function is the inverse of [`offset`].
524     ///
525     /// [`offset`]: #method.offset
526     ///
527     /// # Safety
528     ///
529     /// If any of the following conditions are violated, the result is Undefined
530     /// Behavior:
531     ///
532     /// * Both the starting and other pointer must be either in bounds or one
533     ///   byte past the end of the same [allocated object].
534     ///
535     /// * Both pointers must be *derived from* a pointer to the same object.
536     ///   (See below for an example.)
537     ///
538     /// * The distance between the pointers, in bytes, must be an exact multiple
539     ///   of the size of `T`.
540     ///
541     /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
542     ///
543     /// * The distance being in bounds cannot rely on "wrapping around" the address space.
544     ///
545     /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the
546     /// address space, so two pointers within some value of any Rust type `T` will always satisfy
547     /// the last two conditions. The standard library also generally ensures that allocations
548     /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they
549     /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())`
550     /// always satisfies the last two conditions.
551     ///
552     /// Most platforms fundamentally can't even construct such a large allocation.
553     /// For instance, no known 64-bit platform can ever serve a request
554     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
555     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
556     /// more than `isize::MAX` bytes with things like Physical Address
557     /// Extension. As such, memory acquired directly from allocators or memory
558     /// mapped files *may* be too large to handle with this function.
559     /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
560     /// such large allocations either.)
561     ///
562     /// [`add`]: #method.add
563     /// [allocated object]: crate::ptr#allocated-object
564     ///
565     /// # Panics
566     ///
567     /// This function panics if `T` is a Zero-Sized Type ("ZST").
568     ///
569     /// # Examples
570     ///
571     /// Basic usage:
572     ///
573     /// ```
574     /// let a = [0; 5];
575     /// let ptr1: *const i32 = &a[1];
576     /// let ptr2: *const i32 = &a[3];
577     /// unsafe {
578     ///     assert_eq!(ptr2.offset_from(ptr1), 2);
579     ///     assert_eq!(ptr1.offset_from(ptr2), -2);
580     ///     assert_eq!(ptr1.offset(2), ptr2);
581     ///     assert_eq!(ptr2.offset(-2), ptr1);
582     /// }
583     /// ```
584     ///
585     /// *Incorrect* usage:
586     ///
587     /// ```rust,no_run
588     /// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
589     /// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
590     /// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
591     /// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
592     /// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff);
593     /// assert_eq!(ptr2 as usize, ptr2_other as usize);
594     /// // Since ptr2_other and ptr2 are derived from pointers to different objects,
595     /// // computing their offset is undefined behavior, even though
596     /// // they point to the same address!
597     /// unsafe {
598     ///     let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
599     /// }
600     /// ```
601     #[stable(feature = "ptr_offset_from", since = "1.47.0")]
602     #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")]
603     #[inline]
604     pub const unsafe fn offset_from(self, origin: *const T) -> isize
605     where
606         T: Sized,
607     {
608         let pointee_size = mem::size_of::<T>();
609         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
610         // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
611         unsafe { intrinsics::ptr_offset_from(self, origin) }
612     }
613
614     /// Returns whether two pointers are guaranteed to be equal.
615     ///
616     /// At runtime this function behaves like `self == other`.
617     /// However, in some contexts (e.g., compile-time evaluation),
618     /// it is not always possible to determine equality of two pointers, so this function may
619     /// spuriously return `false` for pointers that later actually turn out to be equal.
620     /// But when it returns `true`, the pointers are guaranteed to be equal.
621     ///
622     /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
623     /// comparisons for which both functions return `false`.
624     ///
625     /// [`guaranteed_ne`]: #method.guaranteed_ne
626     ///
627     /// The return value may change depending on the compiler version and unsafe code must not
628     /// rely on the result of this function for soundness. It is suggested to only use this function
629     /// for performance optimizations where spurious `false` return values by this function do not
630     /// affect the outcome, but just the performance.
631     /// The consequences of using this method to make runtime and compile-time code behave
632     /// differently have not been explored. This method should not be used to introduce such
633     /// differences, and it should also not be stabilized before we have a better understanding
634     /// of this issue.
635     #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
636     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
637     #[inline]
638     pub const fn guaranteed_eq(self, other: *const T) -> bool
639     where
640         T: Sized,
641     {
642         intrinsics::ptr_guaranteed_eq(self, other)
643     }
644
645     /// Returns whether two pointers are guaranteed to be unequal.
646     ///
647     /// At runtime this function behaves like `self != other`.
648     /// However, in some contexts (e.g., compile-time evaluation),
649     /// it is not always possible to determine the inequality of two pointers, so this function may
650     /// spuriously return `false` for pointers that later actually turn out to be unequal.
651     /// But when it returns `true`, the pointers are guaranteed to be unequal.
652     ///
653     /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
654     /// comparisons for which both functions return `false`.
655     ///
656     /// [`guaranteed_eq`]: #method.guaranteed_eq
657     ///
658     /// The return value may change depending on the compiler version and unsafe code must not
659     /// rely on the result of this function for soundness. It is suggested to only use this function
660     /// for performance optimizations where spurious `false` return values by this function do not
661     /// affect the outcome, but just the performance.
662     /// The consequences of using this method to make runtime and compile-time code behave
663     /// differently have not been explored. This method should not be used to introduce such
664     /// differences, and it should also not be stabilized before we have a better understanding
665     /// of this issue.
666     #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
667     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
668     #[inline]
669     pub const fn guaranteed_ne(self, other: *const T) -> bool
670     where
671         T: Sized,
672     {
673         intrinsics::ptr_guaranteed_ne(self, other)
674     }
675
676     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
677     ///
678     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
679     /// offset of `3 * size_of::<T>()` bytes.
680     ///
681     /// # Safety
682     ///
683     /// If any of the following conditions are violated, the result is Undefined
684     /// Behavior:
685     ///
686     /// * Both the starting and resulting pointer must be either in bounds or one
687     ///   byte past the end of the same [allocated object].
688     ///
689     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
690     ///
691     /// * The offset being in bounds cannot rely on "wrapping around" the address
692     ///   space. That is, the infinite-precision sum must fit in a `usize`.
693     ///
694     /// The compiler and standard library generally tries to ensure allocations
695     /// never reach a size where an offset is a concern. For instance, `Vec`
696     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
697     /// `vec.as_ptr().add(vec.len())` is always safe.
698     ///
699     /// Most platforms fundamentally can't even construct such an allocation.
700     /// For instance, no known 64-bit platform can ever serve a request
701     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
702     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
703     /// more than `isize::MAX` bytes with things like Physical Address
704     /// Extension. As such, memory acquired directly from allocators or memory
705     /// mapped files *may* be too large to handle with this function.
706     ///
707     /// Consider using [`wrapping_add`] instead if these constraints are
708     /// difficult to satisfy. The only advantage of this method is that it
709     /// enables more aggressive compiler optimizations.
710     ///
711     /// [`wrapping_add`]: #method.wrapping_add
712     /// [allocated object]: crate::ptr#allocated-object
713     ///
714     /// # Examples
715     ///
716     /// Basic usage:
717     ///
718     /// ```
719     /// let s: &str = "123";
720     /// let ptr: *const u8 = s.as_ptr();
721     ///
722     /// unsafe {
723     ///     println!("{}", *ptr.add(1) as char);
724     ///     println!("{}", *ptr.add(2) as char);
725     /// }
726     /// ```
727     #[stable(feature = "pointer_methods", since = "1.26.0")]
728     #[must_use = "returns a new pointer rather than modifying its argument"]
729     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
730     #[inline(always)]
731     pub const unsafe fn add(self, count: usize) -> Self
732     where
733         T: Sized,
734     {
735         // SAFETY: the caller must uphold the safety contract for `offset`.
736         unsafe { self.offset(count as isize) }
737     }
738
739     /// Calculates the offset from a pointer (convenience for
740     /// `.offset((count as isize).wrapping_neg())`).
741     ///
742     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
743     /// offset of `3 * size_of::<T>()` bytes.
744     ///
745     /// # Safety
746     ///
747     /// If any of the following conditions are violated, the result is Undefined
748     /// Behavior:
749     ///
750     /// * Both the starting and resulting pointer must be either in bounds or one
751     ///   byte past the end of the same [allocated object].
752     ///
753     /// * The computed offset cannot exceed `isize::MAX` **bytes**.
754     ///
755     /// * The offset being in bounds cannot rely on "wrapping around" the address
756     ///   space. That is, the infinite-precision sum must fit in a usize.
757     ///
758     /// The compiler and standard library generally tries to ensure allocations
759     /// never reach a size where an offset is a concern. For instance, `Vec`
760     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
761     /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
762     ///
763     /// Most platforms fundamentally can't even construct such an allocation.
764     /// For instance, no known 64-bit platform can ever serve a request
765     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
766     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
767     /// more than `isize::MAX` bytes with things like Physical Address
768     /// Extension. As such, memory acquired directly from allocators or memory
769     /// mapped files *may* be too large to handle with this function.
770     ///
771     /// Consider using [`wrapping_sub`] instead if these constraints are
772     /// difficult to satisfy. The only advantage of this method is that it
773     /// enables more aggressive compiler optimizations.
774     ///
775     /// [`wrapping_sub`]: #method.wrapping_sub
776     /// [allocated object]: crate::ptr#allocated-object
777     ///
778     /// # Examples
779     ///
780     /// Basic usage:
781     ///
782     /// ```
783     /// let s: &str = "123";
784     ///
785     /// unsafe {
786     ///     let end: *const u8 = s.as_ptr().add(3);
787     ///     println!("{}", *end.sub(1) as char);
788     ///     println!("{}", *end.sub(2) as char);
789     /// }
790     /// ```
791     #[stable(feature = "pointer_methods", since = "1.26.0")]
792     #[must_use = "returns a new pointer rather than modifying its argument"]
793     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
794     #[inline]
795     pub const unsafe fn sub(self, count: usize) -> Self
796     where
797         T: Sized,
798     {
799         // SAFETY: the caller must uphold the safety contract for `offset`.
800         unsafe { self.offset((count as isize).wrapping_neg()) }
801     }
802
803     /// Calculates the offset from a pointer using wrapping arithmetic.
804     /// (convenience for `.wrapping_offset(count as isize)`)
805     ///
806     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
807     /// offset of `3 * size_of::<T>()` bytes.
808     ///
809     /// # Safety
810     ///
811     /// This operation itself is always safe, but using the resulting pointer is not.
812     ///
813     /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
814     /// be used to read or write other allocated objects.
815     ///
816     /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
817     /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
818     /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
819     /// `x` and `y` point into the same allocated object.
820     ///
821     /// Compared to [`add`], this method basically delays the requirement of staying within the
822     /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object
823     /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a
824     /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`]
825     /// can be optimized better and is thus preferable in performance-sensitive code.
826     ///
827     /// The delayed check only considers the value of the pointer that was dereferenced, not the
828     /// intermediate values used during the computation of the final result. For example,
829     /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
830     /// allocated object and then re-entering it later is permitted.
831     ///
832     /// [`add`]: #method.add
833     /// [allocated object]: crate::ptr#allocated-object
834     ///
835     /// # Examples
836     ///
837     /// Basic usage:
838     ///
839     /// ```
840     /// // Iterate using a raw pointer in increments of two elements
841     /// let data = [1u8, 2, 3, 4, 5];
842     /// let mut ptr: *const u8 = data.as_ptr();
843     /// let step = 2;
844     /// let end_rounded_up = ptr.wrapping_add(6);
845     ///
846     /// // This loop prints "1, 3, 5, "
847     /// while ptr != end_rounded_up {
848     ///     unsafe {
849     ///         print!("{}, ", *ptr);
850     ///     }
851     ///     ptr = ptr.wrapping_add(step);
852     /// }
853     /// ```
854     #[stable(feature = "pointer_methods", since = "1.26.0")]
855     #[must_use = "returns a new pointer rather than modifying its argument"]
856     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
857     #[inline(always)]
858     pub const fn wrapping_add(self, count: usize) -> Self
859     where
860         T: Sized,
861     {
862         self.wrapping_offset(count as isize)
863     }
864
865     /// Calculates the offset from a pointer using wrapping arithmetic.
866     /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
867     ///
868     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
869     /// offset of `3 * size_of::<T>()` bytes.
870     ///
871     /// # Safety
872     ///
873     /// This operation itself is always safe, but using the resulting pointer is not.
874     ///
875     /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
876     /// be used to read or write other allocated objects.
877     ///
878     /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
879     /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
880     /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
881     /// `x` and `y` point into the same allocated object.
882     ///
883     /// Compared to [`sub`], this method basically delays the requirement of staying within the
884     /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object
885     /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a
886     /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`]
887     /// can be optimized better and is thus preferable in performance-sensitive code.
888     ///
889     /// The delayed check only considers the value of the pointer that was dereferenced, not the
890     /// intermediate values used during the computation of the final result. For example,
891     /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
892     /// allocated object and then re-entering it later is permitted.
893     ///
894     /// [`sub`]: #method.sub
895     /// [allocated object]: crate::ptr#allocated-object
896     ///
897     /// # Examples
898     ///
899     /// Basic usage:
900     ///
901     /// ```
902     /// // Iterate using a raw pointer in increments of two elements (backwards)
903     /// let data = [1u8, 2, 3, 4, 5];
904     /// let mut ptr: *const u8 = data.as_ptr();
905     /// let start_rounded_down = ptr.wrapping_sub(2);
906     /// ptr = ptr.wrapping_add(4);
907     /// let step = 2;
908     /// // This loop prints "5, 3, 1, "
909     /// while ptr != start_rounded_down {
910     ///     unsafe {
911     ///         print!("{}, ", *ptr);
912     ///     }
913     ///     ptr = ptr.wrapping_sub(step);
914     /// }
915     /// ```
916     #[stable(feature = "pointer_methods", since = "1.26.0")]
917     #[must_use = "returns a new pointer rather than modifying its argument"]
918     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
919     #[inline]
920     pub const fn wrapping_sub(self, count: usize) -> Self
921     where
922         T: Sized,
923     {
924         self.wrapping_offset((count as isize).wrapping_neg())
925     }
926
927     /// Reads the value from `self` without moving it. This leaves the
928     /// memory in `self` unchanged.
929     ///
930     /// See [`ptr::read`] for safety concerns and examples.
931     ///
932     /// [`ptr::read`]: crate::ptr::read()
933     #[stable(feature = "pointer_methods", since = "1.26.0")]
934     #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
935     #[inline]
936     pub const unsafe fn read(self) -> T
937     where
938         T: Sized,
939     {
940         // SAFETY: the caller must uphold the safety contract for `read`.
941         unsafe { read(self) }
942     }
943
944     /// Performs a volatile read of the value from `self` without moving it. This
945     /// leaves the memory in `self` unchanged.
946     ///
947     /// Volatile operations are intended to act on I/O memory, and are guaranteed
948     /// to not be elided or reordered by the compiler across other volatile
949     /// operations.
950     ///
951     /// See [`ptr::read_volatile`] for safety concerns and examples.
952     ///
953     /// [`ptr::read_volatile`]: crate::ptr::read_volatile()
954     #[stable(feature = "pointer_methods", since = "1.26.0")]
955     #[inline]
956     pub unsafe fn read_volatile(self) -> T
957     where
958         T: Sized,
959     {
960         // SAFETY: the caller must uphold the safety contract for `read_volatile`.
961         unsafe { read_volatile(self) }
962     }
963
964     /// Reads the value from `self` without moving it. This leaves the
965     /// memory in `self` unchanged.
966     ///
967     /// Unlike `read`, the pointer may be unaligned.
968     ///
969     /// See [`ptr::read_unaligned`] for safety concerns and examples.
970     ///
971     /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
972     #[stable(feature = "pointer_methods", since = "1.26.0")]
973     #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
974     #[inline]
975     pub const unsafe fn read_unaligned(self) -> T
976     where
977         T: Sized,
978     {
979         // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
980         unsafe { read_unaligned(self) }
981     }
982
983     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
984     /// and destination may overlap.
985     ///
986     /// NOTE: this has the *same* argument order as [`ptr::copy`].
987     ///
988     /// See [`ptr::copy`] for safety concerns and examples.
989     ///
990     /// [`ptr::copy`]: crate::ptr::copy()
991     #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
992     #[stable(feature = "pointer_methods", since = "1.26.0")]
993     #[inline]
994     pub const unsafe fn copy_to(self, dest: *mut T, count: usize)
995     where
996         T: Sized,
997     {
998         // SAFETY: the caller must uphold the safety contract for `copy`.
999         unsafe { copy(self, dest, count) }
1000     }
1001
1002     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
1003     /// and destination may *not* overlap.
1004     ///
1005     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
1006     ///
1007     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
1008     ///
1009     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
1010     #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
1011     #[stable(feature = "pointer_methods", since = "1.26.0")]
1012     #[inline]
1013     pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
1014     where
1015         T: Sized,
1016     {
1017         // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
1018         unsafe { copy_nonoverlapping(self, dest, count) }
1019     }
1020
1021     /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
1022     /// `align`.
1023     ///
1024     /// If it is not possible to align the pointer, the implementation returns
1025     /// `usize::MAX`. It is permissible for the implementation to *always*
1026     /// return `usize::MAX`. Only your algorithm's performance can depend
1027     /// on getting a usable offset here, not its correctness.
1028     ///
1029     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
1030     /// used with the `wrapping_add` method.
1031     ///
1032     /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
1033     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
1034     /// the returned offset is correct in all terms other than alignment.
1035     ///
1036     /// # Panics
1037     ///
1038     /// The function panics if `align` is not a power-of-two.
1039     ///
1040     /// # Examples
1041     ///
1042     /// Accessing adjacent `u8` as `u16`
1043     ///
1044     /// ```
1045     /// # fn foo(n: usize) {
1046     /// # use std::mem::align_of;
1047     /// # unsafe {
1048     /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
1049     /// let ptr = x.as_ptr().add(n) as *const u8;
1050     /// let offset = ptr.align_offset(align_of::<u16>());
1051     /// if offset < x.len() - n - 1 {
1052     ///     let u16_ptr = ptr.add(offset) as *const u16;
1053     ///     assert_ne!(*u16_ptr, 500);
1054     /// } else {
1055     ///     // while the pointer can be aligned via `offset`, it would point
1056     ///     // outside the allocation
1057     /// }
1058     /// # } }
1059     /// ```
1060     #[stable(feature = "align_offset", since = "1.36.0")]
1061     #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1062     pub const fn align_offset(self, align: usize) -> usize
1063     where
1064         T: Sized,
1065     {
1066         if !align.is_power_of_two() {
1067             panic!("align_offset: align is not a power-of-two");
1068         }
1069
1070         fn rt_impl<T>(p: *const T, align: usize) -> usize {
1071             // SAFETY: `align` has been checked to be a power of 2 above
1072             unsafe { align_offset(p, align) }
1073         }
1074
1075         const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
1076             usize::MAX
1077         }
1078
1079         // SAFETY:
1080         // It is permisseble for `align_offset` to always return `usize::MAX`,
1081         // algorithm correctness can not depend on `align_offset` returning non-max values.
1082         //
1083         // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
1084         unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
1085     }
1086 }
1087
1088 impl<T> *const [T] {
1089     /// Returns the length of a raw slice.
1090     ///
1091     /// The returned value is the number of **elements**, not the number of bytes.
1092     ///
1093     /// This function is safe, even when the raw slice cannot be cast to a slice
1094     /// reference because the pointer is null or unaligned.
1095     ///
1096     /// # Examples
1097     ///
1098     /// ```rust
1099     /// #![feature(slice_ptr_len)]
1100     ///
1101     /// use std::ptr;
1102     ///
1103     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
1104     /// assert_eq!(slice.len(), 3);
1105     /// ```
1106     #[inline]
1107     #[unstable(feature = "slice_ptr_len", issue = "71146")]
1108     #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
1109     pub const fn len(self) -> usize {
1110         metadata(self)
1111     }
1112
1113     /// Returns a raw pointer to the slice's buffer.
1114     ///
1115     /// This is equivalent to casting `self` to `*const T`, but more type-safe.
1116     ///
1117     /// # Examples
1118     ///
1119     /// ```rust
1120     /// #![feature(slice_ptr_get)]
1121     /// use std::ptr;
1122     ///
1123     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
1124     /// assert_eq!(slice.as_ptr(), ptr::null());
1125     /// ```
1126     #[inline]
1127     #[unstable(feature = "slice_ptr_get", issue = "74265")]
1128     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
1129     pub const fn as_ptr(self) -> *const T {
1130         self as *const T
1131     }
1132
1133     /// Returns a raw pointer to an element or subslice, without doing bounds
1134     /// checking.
1135     ///
1136     /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
1137     /// is *[undefined behavior]* even if the resulting pointer is not used.
1138     ///
1139     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1140     ///
1141     /// # Examples
1142     ///
1143     /// ```
1144     /// #![feature(slice_ptr_get)]
1145     ///
1146     /// let x = &[1, 2, 4] as *const [i32];
1147     ///
1148     /// unsafe {
1149     ///     assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
1150     /// }
1151     /// ```
1152     #[unstable(feature = "slice_ptr_get", issue = "74265")]
1153     #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
1154     #[inline]
1155     pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
1156     where
1157         I: ~const SliceIndex<[T]>,
1158     {
1159         // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
1160         unsafe { index.get_unchecked(self) }
1161     }
1162
1163     /// Returns `None` if the pointer is null, or else returns a shared slice to
1164     /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
1165     /// that the value has to be initialized.
1166     ///
1167     /// [`as_ref`]: #method.as_ref
1168     ///
1169     /// # Safety
1170     ///
1171     /// When calling this method, you have to ensure that *either* the pointer is null *or*
1172     /// all of the following is true:
1173     ///
1174     /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
1175     ///   and it must be properly aligned. This means in particular:
1176     ///
1177     ///     * The entire memory range of this slice must be contained within a single [allocated object]!
1178     ///       Slices can never span across multiple allocated objects.
1179     ///
1180     ///     * The pointer must be aligned even for zero-length slices. One
1181     ///       reason for this is that enum layout optimizations may rely on references
1182     ///       (including slices of any length) being aligned and non-null to distinguish
1183     ///       them from other data. You can obtain a pointer that is usable as `data`
1184     ///       for zero-length slices using [`NonNull::dangling()`].
1185     ///
1186     /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
1187     ///   See the safety documentation of [`pointer::offset`].
1188     ///
1189     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
1190     ///   arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
1191     ///   In particular, while this reference exists, the memory the pointer points to must
1192     ///   not get mutated (except inside `UnsafeCell`).
1193     ///
1194     /// This applies even if the result of this method is unused!
1195     ///
1196     /// See also [`slice::from_raw_parts`][].
1197     ///
1198     /// [valid]: crate::ptr#safety
1199     /// [allocated object]: crate::ptr#allocated-object
1200     #[inline]
1201     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
1202     #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
1203     pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
1204         if self.is_null() {
1205             None
1206         } else {
1207             // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
1208             Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
1209         }
1210     }
1211 }
1212
1213 // Equality for pointers
1214 #[stable(feature = "rust1", since = "1.0.0")]
1215 impl<T: ?Sized> PartialEq for *const T {
1216     #[inline]
1217     fn eq(&self, other: &*const T) -> bool {
1218         *self == *other
1219     }
1220 }
1221
1222 #[stable(feature = "rust1", since = "1.0.0")]
1223 impl<T: ?Sized> Eq for *const T {}
1224
1225 // Comparison for pointers
1226 #[stable(feature = "rust1", since = "1.0.0")]
1227 impl<T: ?Sized> Ord for *const T {
1228     #[inline]
1229     fn cmp(&self, other: &*const T) -> Ordering {
1230         if self < other {
1231             Less
1232         } else if self == other {
1233             Equal
1234         } else {
1235             Greater
1236         }
1237     }
1238 }
1239
1240 #[stable(feature = "rust1", since = "1.0.0")]
1241 impl<T: ?Sized> PartialOrd for *const T {
1242     #[inline]
1243     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
1244         Some(self.cmp(other))
1245     }
1246
1247     #[inline]
1248     fn lt(&self, other: &*const T) -> bool {
1249         *self < *other
1250     }
1251
1252     #[inline]
1253     fn le(&self, other: &*const T) -> bool {
1254         *self <= *other
1255     }
1256
1257     #[inline]
1258     fn gt(&self, other: &*const T) -> bool {
1259         *self > *other
1260     }
1261
1262     #[inline]
1263     fn ge(&self, other: &*const T) -> bool {
1264         *self >= *other
1265     }
1266 }