diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-07 19:35:37 -0800 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2025-01-09 23:47:11 -0800 |
| commit | 6f2a78345ee7f55c5ce33fd7b9804c665c646dd2 (patch) | |
| tree | 733a3be2e42e4cf70a5194c0fbfcb370e7ae7045 /library/alloc/src | |
| parent | 88ab2d8acb342a36324103b6f95ec1335db27d7d (diff) | |
| download | rust-6f2a78345ee7f55c5ce33fd7b9804c665c646dd2.tar.gz rust-6f2a78345ee7f55c5ce33fd7b9804c665c646dd2.zip | |
Update a bunch of library types for MCP807
This greatly reduces the number of places that actually use the `rustc_layout_scalar_valid_range_*` attributes down to just 3: ``` library/core\src\ptr\non_null.rs 68:#[rustc_layout_scalar_valid_range_start(1)] library/core\src\num\niche_types.rs 19: #[rustc_layout_scalar_valid_range_start($low)] 20: #[rustc_layout_scalar_valid_range_end($high)] ``` Everything else -- PAL Nanoseconds, alloc's `Cap`, niched FDs, etc -- all just wrap those `niche_types` types.
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/alloc/src/raw_vec.rs | 46 |
2 files changed, 23 insertions, 24 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 784af940769..a4c3b7dd1b1 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -142,6 +142,7 @@ #![feature(slice_range)] #![feature(std_internals)] #![feature(str_internals)] +#![feature(temporary_niche_types)] #![feature(trusted_fused)] #![feature(trusted_len)] #![feature(trusted_random_access)] diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index e93ff2f9023..ad86bf4bf07 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -33,21 +33,15 @@ enum AllocInit { Zeroed, } -#[repr(transparent)] -#[cfg_attr(target_pointer_width = "16", rustc_layout_scalar_valid_range_end(0x7fff))] -#[cfg_attr(target_pointer_width = "32", rustc_layout_scalar_valid_range_end(0x7fff_ffff))] -#[cfg_attr(target_pointer_width = "64", rustc_layout_scalar_valid_range_end(0x7fff_ffff_ffff_ffff))] -struct Cap(usize); +type Cap = core::num::niche_types::UsizeNoHighBit; -impl Cap { - const ZERO: Cap = unsafe { Cap(0) }; +const ZERO_CAP: Cap = unsafe { Cap::new_unchecked(0) }; - /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. - /// - /// # Safety: cap must be <= `isize::MAX`. - unsafe fn new<T>(cap: usize) -> Self { - if T::IS_ZST { Cap::ZERO } else { unsafe { Self(cap) } } - } +/// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. +/// +/// # Safety: cap must be <= `isize::MAX`. +unsafe fn new_cap<T>(cap: usize) -> Cap { + if T::IS_ZST { ZERO_CAP } else { unsafe { Cap::new_unchecked(cap) } } } /// A low-level utility for more ergonomically allocating, reallocating, and deallocating @@ -257,7 +251,7 @@ impl<T, A: Allocator> RawVec<T, A> { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); - let capacity = Cap::new::<T>(capacity); + let capacity = new_cap::<T>(capacity); Self { inner: RawVecInner::from_raw_parts_in(ptr, capacity, alloc), _marker: PhantomData, @@ -275,7 +269,7 @@ impl<T, A: Allocator> RawVec<T, A> { // SAFETY: Precondition passed to the caller unsafe { let ptr = ptr.cast(); - let capacity = Cap::new::<T>(capacity); + let capacity = new_cap::<T>(capacity); Self { inner: RawVecInner::from_nonnull_in(ptr, capacity, alloc), _marker: PhantomData } } } @@ -410,7 +404,7 @@ impl<A: Allocator> RawVecInner<A> { const fn new_in(alloc: A, align: usize) -> Self { let ptr = unsafe { core::mem::transmute(align) }; // `cap: 0` means "unallocated". zero-sized types are ignored. - Self { ptr, cap: Cap::ZERO, alloc } + Self { ptr, cap: ZERO_CAP, alloc } } #[cfg(not(no_global_oom_handling))] @@ -483,7 +477,11 @@ impl<A: Allocator> RawVecInner<A> { // Allocators currently return a `NonNull<[u8]>` whose length // matches the size requested. If that ever changes, the capacity // here should change to `ptr.len() / mem::size_of::<T>()`. - Ok(Self { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap(capacity) }, alloc }) + Ok(Self { + ptr: Unique::from(ptr.cast()), + cap: unsafe { Cap::new_unchecked(capacity) }, + alloc, + }) } #[inline] @@ -508,7 +506,7 @@ impl<A: Allocator> RawVecInner<A> { #[inline] const fn capacity(&self, elem_size: usize) -> usize { - if elem_size == 0 { usize::MAX } else { self.cap.0 } + if elem_size == 0 { usize::MAX } else { self.cap.as_inner() } } #[inline] @@ -518,7 +516,7 @@ impl<A: Allocator> RawVecInner<A> { #[inline] fn current_memory(&self, elem_layout: Layout) -> Option<(NonNull<u8>, Layout)> { - if elem_layout.size() == 0 || self.cap.0 == 0 { + if elem_layout.size() == 0 || self.cap.as_inner() == 0 { None } else { // We could use Layout::array here which ensures the absence of isize and usize overflows @@ -526,7 +524,7 @@ impl<A: Allocator> RawVecInner<A> { // has already been allocated so we know it can't overflow and currently Rust does not // support such types. So we can do better by skipping some checks and avoid an unwrap. unsafe { - let alloc_size = elem_layout.size().unchecked_mul(self.cap.0); + let alloc_size = elem_layout.size().unchecked_mul(self.cap.as_inner()); let layout = Layout::from_size_align_unchecked(alloc_size, elem_layout.align()); Some((self.ptr.into(), layout)) } @@ -562,7 +560,7 @@ impl<A: Allocator> RawVecInner<A> { #[inline] #[track_caller] fn grow_one(&mut self, elem_layout: Layout) { - if let Err(err) = self.grow_amortized(self.cap.0, 1, elem_layout) { + if let Err(err) = self.grow_amortized(self.cap.as_inner(), 1, elem_layout) { handle_error(err); } } @@ -627,7 +625,7 @@ impl<A: Allocator> RawVecInner<A> { // the size requested. If that ever changes, the capacity here should // change to `ptr.len() / mem::size_of::<T>()`. self.ptr = Unique::from(ptr.cast()); - self.cap = unsafe { Cap(cap) }; + self.cap = unsafe { Cap::new_unchecked(cap) }; } fn grow_amortized( @@ -650,7 +648,7 @@ impl<A: Allocator> RawVecInner<A> { // This guarantees exponential growth. The doubling cannot overflow // because `cap <= isize::MAX` and the type of `cap` is `usize`. - let cap = cmp::max(self.cap.0 * 2, required_cap); + let cap = cmp::max(self.cap.as_inner() * 2, required_cap); let cap = cmp::max(min_non_zero_cap(elem_layout.size()), cap); let new_layout = layout_array(cap, elem_layout)?; @@ -719,7 +717,7 @@ impl<A: Allocator> RawVecInner<A> { unsafe { self.alloc.deallocate(ptr, layout) }; self.ptr = unsafe { Unique::new_unchecked(ptr::without_provenance_mut(elem_layout.align())) }; - self.cap = Cap::ZERO; + self.cap = ZERO_CAP; } else { let ptr = unsafe { // Layout cannot overflow here because it would have |
