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