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