From 8f8b563673cd37a790b0b390134209114babde52 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Fri, 31 Jul 2020 10:07:18 +0200 Subject: [PATCH 1/2] adds changes back after cleaning up merge disaster --- library/core/src/ptr/const_ptr.rs | 32 +++++++++++++++++++++++++++++++ library/core/src/ptr/mut_ptr.rs | 32 +++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a2acc239bd38f..6bae99d280e7b 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -656,6 +656,38 @@ impl *const T { self.wrapping_offset((count as isize).wrapping_neg()) } + /// Sets the pointer value to `ptr`. + /// + /// In case `self` is a (fat) pointer to an unsized type, this operation + /// will only affect the pointer part, whereas for (thin) pointers to + /// sized types, this has the same effect as a simple assignment. + /// + /// # Examples + /// + /// This function is primarily useful for allowing byte-wise pointer + /// arithmetic on potentially fat pointers: + /// + /// ``` + /// ![feature(set_ptr_value)] + /// # use core::fmt::Debug; + /// let arr: [i32; 3] = [1, 2, 3]; + /// let mut ptr = &arr[0] as *const dyn Debug; + /// let thin = ptr as *const u8; + /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); + /// assert_eq!(unsafe { *(ptr as *const i32) }, 3); + /// ``` + #[unstable(feature = "set_ptr_value", issue = "none")] + #[inline] + pub fn set_ptr_value(mut self, val: *const ()) -> Self { + let thin = &mut self as *mut *const T as *mut *const (); + // SAFETY: In case of a thin pointer, this operations is identical + // to a simple assignment. In case of a fat pointer, with the current + // fat pointer layout implementation, the first field of such a + // pointer is always the data pointer, which is likewise assigned. + unsafe { *thin = val }; + self + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 17fa90ecc08b5..13f5684dafacb 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -712,6 +712,38 @@ impl *mut T { self.wrapping_offset((count as isize).wrapping_neg()) } + /// Sets the pointer value to `ptr`. + /// + /// In case `self` is a (fat) pointer to an unsized type, this operation + /// will only affect the pointer part, whereas for (thin) pointers to + /// sized types, this has the same effect as a simple assignment. + /// + /// # Examples + /// + /// This function is primarily useful for allowing byte-wise pointer + /// arithmetic on potentially fat pointers: + /// + /// ``` + /// #![feature(set_ptr_value)] + /// # use core::fmt::Debug; + /// let mut arr: [i32; 3] = [1, 2, 3]; + /// let mut ptr = &mut arr[0] as *mut dyn Debug; + /// let thin = ptr as *mut u8; + /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); + /// assert_eq!(unsafe { *(ptr as *mut i32) }, 3); + /// ``` + #[unstable(feature = "set_ptr_value", issue = "none")] + #[inline] + pub fn set_ptr_value(mut self, val: *mut ()) -> Self { + let thin = &mut self as *mut *mut T as *mut *mut (); + // SAFETY: In case of a thin pointer, this operations is identical + // to a simple assignment. In case of a fat pointer, with the current + // fat pointer layout implementation, the first field of such a + // pointer is always the data pointer, which is likewise assigned. + unsafe { *thin = val }; + self + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// From 6bad927c13e051a46895fc0d7eba6003c828cc49 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Fri, 31 Jul 2020 10:47:28 +0200 Subject: [PATCH 2/2] adds back missing # char to feature gate --- library/core/src/ptr/const_ptr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 6bae99d280e7b..738b00661917d 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -668,7 +668,7 @@ impl *const T { /// arithmetic on potentially fat pointers: /// /// ``` - /// ![feature(set_ptr_value)] + /// #![feature(set_ptr_value)] /// # use core::fmt::Debug; /// let arr: [i32; 3] = [1, 2, 3]; /// let mut ptr = &arr[0] as *const dyn Debug;