Skip to content

Commit 6c81556

Browse files
oliver-gierschdtolnay
oliver-giersch
authored andcommitted
adds [*mut|*const] ptr::set_ptr_value
1 parent 66b97dc commit 6c81556

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

library/core/src/ptr/const_ptr.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,38 @@ impl<T: ?Sized> *const T {
656656
self.wrapping_offset((count as isize).wrapping_neg())
657657
}
658658

659+
/// Sets the pointer value to `ptr`.
660+
///
661+
/// In case `self` is a (fat) pointer to an unsized type, this operation
662+
/// will only affect the pointer part, whereas for (thin) pointers to
663+
/// sized types, this has the same effect as a simple assignment.
664+
///
665+
/// # Examples
666+
///
667+
/// This function is primarily useful for allowing byte-wise pointer
668+
/// arithmetic on potentially fat pointers:
669+
///
670+
/// ```
671+
/// #![feature(set_ptr_value)]
672+
/// # use core::fmt::Debug;
673+
/// let arr: [i32; 3] = [1, 2, 3];
674+
/// let mut ptr = &arr[0] as *const dyn Debug;
675+
/// let thin = ptr as *const u8;
676+
/// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
677+
/// assert_eq!(unsafe { *(ptr as *const i32) }, 3);
678+
/// ```
679+
#[unstable(feature = "set_ptr_value", issue = "75091")]
680+
#[inline]
681+
pub fn set_ptr_value(mut self, val: *const ()) -> Self {
682+
let thin = &mut self as *mut *const T as *mut *const ();
683+
// SAFETY: In case of a thin pointer, this operations is identical
684+
// to a simple assignment. In case of a fat pointer, with the current
685+
// fat pointer layout implementation, the first field of such a
686+
// pointer is always the data pointer, which is likewise assigned.
687+
unsafe { *thin = val };
688+
self
689+
}
690+
659691
/// Reads the value from `self` without moving it. This leaves the
660692
/// memory in `self` unchanged.
661693
///

library/core/src/ptr/mut_ptr.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,38 @@ impl<T: ?Sized> *mut T {
712712
self.wrapping_offset((count as isize).wrapping_neg())
713713
}
714714

715+
/// Sets the pointer value to `ptr`.
716+
///
717+
/// In case `self` is a (fat) pointer to an unsized type, this operation
718+
/// will only affect the pointer part, whereas for (thin) pointers to
719+
/// sized types, this has the same effect as a simple assignment.
720+
///
721+
/// # Examples
722+
///
723+
/// This function is primarily useful for allowing byte-wise pointer
724+
/// arithmetic on potentially fat pointers:
725+
///
726+
/// ```
727+
/// #![feature(set_ptr_value)]
728+
/// # use core::fmt::Debug;
729+
/// let mut arr: [i32; 3] = [1, 2, 3];
730+
/// let mut ptr = &mut arr[0] as *mut dyn Debug;
731+
/// let thin = ptr as *mut u8;
732+
/// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
733+
/// assert_eq!(unsafe { *(ptr as *mut i32) }, 3);
734+
/// ```
735+
#[unstable(feature = "set_ptr_value", issue = "75091")]
736+
#[inline]
737+
pub fn set_ptr_value(mut self, val: *mut ()) -> Self {
738+
let thin = &mut self as *mut *mut T as *mut *mut ();
739+
// SAFETY: In case of a thin pointer, this operations is identical
740+
// to a simple assignment. In case of a fat pointer, with the current
741+
// fat pointer layout implementation, the first field of such a
742+
// pointer is always the data pointer, which is likewise assigned.
743+
unsafe { *thin = val };
744+
self
745+
}
746+
715747
/// Reads the value from `self` without moving it. This leaves the
716748
/// memory in `self` unchanged.
717749
///

0 commit comments

Comments
 (0)