Skip to content

Commit 1a52fae

Browse files
author
Lukas Markeffsky
committed
allow casting to fat pointers with ptr.cast()
1 parent f0f90eb commit 1a52fae

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

library/core/src/ptr/const_ptr.rs

+14
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,24 @@ impl<T: ?Sized> *const T {
5757
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
5858
#[rustc_diagnostic_item = "const_ptr_cast"]
5959
#[inline(always)]
60+
#[cfg(bootstrap)]
6061
pub const fn cast<U>(self) -> *const U {
6162
self as _
6263
}
6364

65+
/// Casts to a pointer of another type.
66+
#[stable(feature = "ptr_cast", since = "1.38.0")]
67+
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
68+
#[rustc_diagnostic_item = "const_ptr_cast"]
69+
#[inline(always)]
70+
#[cfg(not(bootstrap))]
71+
pub const fn cast<U: ?Sized>(self) -> *const U
72+
where
73+
T: PointerCast<U>,
74+
{
75+
self as _
76+
}
77+
6478
/// Use the pointer value in a new pointer of another type.
6579
///
6680
/// In case `meta` is a (fat) pointer to an unsized type, this operation

library/core/src/ptr/mut_ptr.rs

+14
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,24 @@ impl<T: ?Sized> *mut T {
5757
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
5858
#[rustc_diagnostic_item = "ptr_cast"]
5959
#[inline(always)]
60+
#[cfg(bootstrap)]
6061
pub const fn cast<U>(self) -> *mut U {
6162
self as _
6263
}
6364

65+
/// Casts to a pointer of another type.
66+
#[stable(feature = "ptr_cast", since = "1.38.0")]
67+
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
68+
#[rustc_diagnostic_item = "ptr_cast"]
69+
#[inline(always)]
70+
#[cfg(not(bootstrap))]
71+
pub const fn cast<U: ?Sized>(self) -> *mut U
72+
where
73+
T: PointerCast<U>,
74+
{
75+
self as _
76+
}
77+
6478
/// Use the pointer value in a new pointer of another type.
6579
///
6680
/// In case `meta` is a (fat) pointer to an unsized type, this operation

library/core/src/ptr/non_null.rs

+28
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,39 @@ impl<T: ?Sized> NonNull<T> {
468468
#[must_use = "this returns the result of the operation, \
469469
without modifying the original"]
470470
#[inline]
471+
#[cfg(bootstrap)]
471472
pub const fn cast<U>(self) -> NonNull<U> {
472473
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
473474
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
474475
}
475476

477+
/// Casts to a pointer of another type.
478+
///
479+
/// # Examples
480+
///
481+
/// ```
482+
/// use std::ptr::NonNull;
483+
///
484+
/// let mut x = 0u32;
485+
/// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer");
486+
///
487+
/// let casted_ptr = ptr.cast::<i8>();
488+
/// let raw_ptr: *mut i8 = casted_ptr.as_ptr();
489+
/// ```
490+
#[stable(feature = "nonnull_cast", since = "1.27.0")]
491+
#[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")]
492+
#[must_use = "this returns the result of the operation, \
493+
without modifying the original"]
494+
#[inline]
495+
#[cfg(not(bootstrap))]
496+
pub const fn cast<U: ?Sized>(self) -> NonNull<U>
497+
where
498+
T: super::PointerCast<U>,
499+
{
500+
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
501+
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
502+
}
503+
476504
/// Calculates the offset from a pointer.
477505
///
478506
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer

0 commit comments

Comments
 (0)