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