From 246f239d9f40f633160f0c18f87a20922d4e77bb Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:06:37 +0200 Subject: Merging debian version 1.65.0+dfsg1-2. Signed-off-by: Daniel Baumann --- library/core/src/ptr/mut_ptr.rs | 98 +++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 44 deletions(-) (limited to 'library/core/src/ptr/mut_ptr.rs') diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fc3dd2a9b..e277b8181 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -35,7 +35,10 @@ impl *mut T { pub const fn is_null(self) -> bool { // Compare via a cast to a thin pointer, so fat pointers are only // considering their "data" part for null-ness. - (self as *mut u8).guaranteed_eq(null_mut()) + match (self as *mut u8).guaranteed_eq(null_mut()) { + None => false, + Some(res) => res, + } } /// Casts to a pointer of another type. @@ -100,8 +103,8 @@ impl *mut T { /// coercion. /// /// [`cast_mut`]: #method.cast_mut - #[unstable(feature = "ptr_const_cast", issue = "92675")] - #[rustc_const_unstable(feature = "ptr_const_cast", issue = "92675")] + #[stable(feature = "ptr_const_cast", since = "1.65.0")] + #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")] pub const fn cast_const(self) -> *const T { self as _ } @@ -160,7 +163,7 @@ impl *mut T { /// This is similar to `self as usize`, which semantically discards *provenance* and /// *address-space* information. However, unlike `self as usize`, casting the returned address /// back to a pointer yields [`invalid`][], which is undefined behavior to dereference. To - /// properly restore the lost information and obtain a dereferencable pointer, use + /// properly restore the lost information and obtain a dereferenceable pointer, use /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr]. /// /// If using those APIs is not possible because there is no way to preserve a pointer with the @@ -255,7 +258,7 @@ impl *mut T { let offset = dest_addr.wrapping_sub(self_addr); // This is the canonical desugarring of this operation - self.cast::().wrapping_offset(offset).cast::() + self.wrapping_byte_offset(offset) } /// Creates a new pointer by mapping `self`'s address to a new one. @@ -575,6 +578,21 @@ impl *mut T { ) } + /// Masks out bits of the pointer according to a mask. + /// + /// This is convenience for `ptr.map_addr(|a| a & mask)`. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. + #[cfg(not(bootstrap))] + #[unstable(feature = "ptr_mask", issue = "98290")] + #[must_use = "returns a new pointer rather than modifying its argument"] + #[inline(always)] + pub fn mask(self, mask: usize) -> *mut T { + let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut (); + from_raw_parts_mut::(this, metadata(self)) + } + /// Returns `None` if the pointer is null, or else returns a unique reference to /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_mut`] /// must be used instead. @@ -682,20 +700,16 @@ impl *mut T { /// Returns whether two pointers are guaranteed to be equal. /// - /// At runtime this function behaves like `self == other`. + /// At runtime this function behaves like `Some(self == other)`. /// However, in some contexts (e.g., compile-time evaluation), /// it is not always possible to determine equality of two pointers, so this function may - /// spuriously return `false` for pointers that later actually turn out to be equal. - /// But when it returns `true`, the pointers are guaranteed to be equal. + /// spuriously return `None` for pointers that later actually turn out to have its equality known. + /// But when it returns `Some`, the pointers' equality is guaranteed to be known. /// - /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer - /// comparisons for which both functions return `false`. - /// - /// [`guaranteed_ne`]: #method.guaranteed_ne - /// - /// The return value may change depending on the compiler version and unsafe code might not + /// The return value may change from `Some` to `None` and vice versa depending on the compiler + /// version and unsafe code must not /// rely on the result of this function for soundness. It is suggested to only use this function - /// for performance optimizations where spurious `false` return values by this function do not + /// for performance optimizations where spurious `None` return values by this function do not /// affect the outcome, but just the performance. /// The consequences of using this method to make runtime and compile-time code behave /// differently have not been explored. This method should not be used to introduce such @@ -704,29 +718,25 @@ impl *mut T { #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[inline] - pub const fn guaranteed_eq(self, other: *mut T) -> bool + pub const fn guaranteed_eq(self, other: *mut T) -> Option where T: Sized, { - intrinsics::ptr_guaranteed_eq(self as *const _, other as *const _) + (self as *const T).guaranteed_eq(other as _) } - /// Returns whether two pointers are guaranteed to be unequal. + /// Returns whether two pointers are guaranteed to be inequal. /// - /// At runtime this function behaves like `self != other`. + /// At runtime this function behaves like `Some(self == other)`. /// However, in some contexts (e.g., compile-time evaluation), - /// it is not always possible to determine the inequality of two pointers, so this function may - /// spuriously return `false` for pointers that later actually turn out to be unequal. - /// But when it returns `true`, the pointers are guaranteed to be unequal. - /// - /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer - /// comparisons for which both functions return `false`. + /// it is not always possible to determine inequality of two pointers, so this function may + /// spuriously return `None` for pointers that later actually turn out to have its inequality known. + /// But when it returns `Some`, the pointers' inequality is guaranteed to be known. /// - /// [`guaranteed_eq`]: #method.guaranteed_eq - /// - /// The return value may change depending on the compiler version and unsafe code might not + /// The return value may change from `Some` to `None` and vice versa depending on the compiler + /// version and unsafe code must not /// rely on the result of this function for soundness. It is suggested to only use this function - /// for performance optimizations where spurious `false` return values by this function do not + /// for performance optimizations where spurious `None` return values by this function do not /// affect the outcome, but just the performance. /// The consequences of using this method to make runtime and compile-time code behave /// differently have not been explored. This method should not be used to introduce such @@ -735,11 +745,11 @@ impl *mut T { #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] #[inline] - pub const unsafe fn guaranteed_ne(self, other: *mut T) -> bool + pub const fn guaranteed_ne(self, other: *mut T) -> Option where T: Sized, { - intrinsics::ptr_guaranteed_ne(self as *const _, other as *const _) + (self as *const T).guaranteed_ne(other as _) } /// Calculates the distance between two pointers. The returned value is in @@ -824,7 +834,7 @@ impl *mut T { /// } /// ``` #[stable(feature = "ptr_offset_from", since = "1.47.0")] - #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "92980")] + #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn offset_from(self, origin: *const T) -> isize @@ -1545,20 +1555,23 @@ impl *mut T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// # fn foo(n: usize) { - /// # use std::mem::align_of; + /// use std::mem::align_of; + /// /// # unsafe { - /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = x.as_ptr().add(n) as *const u8; + /// let mut x = [5_u8, 6, 7, 8, 9]; + /// let ptr = x.as_mut_ptr(); /// let offset = ptr.align_offset(align_of::()); - /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *const u16; - /// assert_ne!(*u16_ptr, 500); + /// + /// if offset < x.len() - 1 { + /// let u16_ptr = ptr.add(offset).cast::(); + /// *u16_ptr = 0; + /// + /// assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]); /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation /// } - /// # } } + /// # } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] @@ -1614,11 +1627,8 @@ impl *mut T { panic!("is_aligned_to: align is not a power-of-two"); } - // SAFETY: `is_power_of_two()` will return `false` for zero. - unsafe { core::intrinsics::assume(align != 0) }; - // Cast is needed for `T: !Sized` - self.cast::().addr() % align == 0 + self.cast::().addr() & align - 1 == 0 } } -- cgit v1.2.3