@@ -33,21 +33,15 @@ enum AllocInit {
3333 Zeroed ,
3434}
3535
36- #[ repr( transparent) ]
37- #[ cfg_attr( target_pointer_width = "16" , rustc_layout_scalar_valid_range_end( 0x7fff ) ) ]
38- #[ cfg_attr( target_pointer_width = "32" , rustc_layout_scalar_valid_range_end( 0x7fff_ffff ) ) ]
39- #[ cfg_attr( target_pointer_width = "64" , rustc_layout_scalar_valid_range_end( 0x7fff_ffff_ffff_ffff ) ) ]
40- struct Cap ( usize ) ;
36+ type Cap = core:: num:: niche_types:: UsizeNoHighBit ;
4137
42- impl Cap {
43- const ZERO : Cap = unsafe { Cap ( 0 ) } ;
38+ const ZERO_CAP : Cap = unsafe { Cap :: new_unchecked ( 0 ) } ;
4439
45- /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`.
46- ///
47- /// # Safety: cap must be <= `isize::MAX`.
48- unsafe fn new < T > ( cap : usize ) -> Self {
49- if T :: IS_ZST { Cap :: ZERO } else { unsafe { Self ( cap) } }
50- }
40+ /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`.
41+ ///
42+ /// # Safety: cap must be <= `isize::MAX`.
43+ unsafe fn new_cap < T > ( cap : usize ) -> Cap {
44+ if T :: IS_ZST { ZERO_CAP } else { unsafe { Cap :: new_unchecked ( cap) } }
5145}
5246
5347/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
@@ -257,7 +251,7 @@ impl<T, A: Allocator> RawVec<T, A> {
257251 // SAFETY: Precondition passed to the caller
258252 unsafe {
259253 let ptr = ptr. cast ( ) ;
260- let capacity = Cap :: new :: < T > ( capacity) ;
254+ let capacity = new_cap :: < T > ( capacity) ;
261255 Self {
262256 inner : RawVecInner :: from_raw_parts_in ( ptr, capacity, alloc) ,
263257 _marker : PhantomData ,
@@ -275,7 +269,7 @@ impl<T, A: Allocator> RawVec<T, A> {
275269 // SAFETY: Precondition passed to the caller
276270 unsafe {
277271 let ptr = ptr. cast ( ) ;
278- let capacity = Cap :: new :: < T > ( capacity) ;
272+ let capacity = new_cap :: < T > ( capacity) ;
279273 Self { inner : RawVecInner :: from_nonnull_in ( ptr, capacity, alloc) , _marker : PhantomData }
280274 }
281275 }
@@ -410,7 +404,7 @@ impl<A: Allocator> RawVecInner<A> {
410404 const fn new_in ( alloc : A , align : usize ) -> Self {
411405 let ptr = unsafe { core:: mem:: transmute ( align) } ;
412406 // `cap: 0` means "unallocated". zero-sized types are ignored.
413- Self { ptr, cap : Cap :: ZERO , alloc }
407+ Self { ptr, cap : ZERO_CAP , alloc }
414408 }
415409
416410 #[ cfg( not( no_global_oom_handling) ) ]
@@ -483,7 +477,11 @@ impl<A: Allocator> RawVecInner<A> {
483477 // Allocators currently return a `NonNull<[u8]>` whose length
484478 // matches the size requested. If that ever changes, the capacity
485479 // here should change to `ptr.len() / mem::size_of::<T>()`.
486- Ok ( Self { ptr : Unique :: from ( ptr. cast ( ) ) , cap : unsafe { Cap ( capacity) } , alloc } )
480+ Ok ( Self {
481+ ptr : Unique :: from ( ptr. cast ( ) ) ,
482+ cap : unsafe { Cap :: new_unchecked ( capacity) } ,
483+ alloc,
484+ } )
487485 }
488486
489487 #[ inline]
@@ -508,7 +506,7 @@ impl<A: Allocator> RawVecInner<A> {
508506
509507 #[ inline]
510508 const fn capacity ( & self , elem_size : usize ) -> usize {
511- if elem_size == 0 { usize:: MAX } else { self . cap . 0 }
509+ if elem_size == 0 { usize:: MAX } else { self . cap . as_inner ( ) }
512510 }
513511
514512 #[ inline]
@@ -518,15 +516,15 @@ impl<A: Allocator> RawVecInner<A> {
518516
519517 #[ inline]
520518 fn current_memory ( & self , elem_layout : Layout ) -> Option < ( NonNull < u8 > , Layout ) > {
521- if elem_layout. size ( ) == 0 || self . cap . 0 == 0 {
519+ if elem_layout. size ( ) == 0 || self . cap . as_inner ( ) == 0 {
522520 None
523521 } else {
524522 // We could use Layout::array here which ensures the absence of isize and usize overflows
525523 // and could hypothetically handle differences between stride and size, but this memory
526524 // has already been allocated so we know it can't overflow and currently Rust does not
527525 // support such types. So we can do better by skipping some checks and avoid an unwrap.
528526 unsafe {
529- let alloc_size = elem_layout. size ( ) . unchecked_mul ( self . cap . 0 ) ;
527+ let alloc_size = elem_layout. size ( ) . unchecked_mul ( self . cap . as_inner ( ) ) ;
530528 let layout = Layout :: from_size_align_unchecked ( alloc_size, elem_layout. align ( ) ) ;
531529 Some ( ( self . ptr . into ( ) , layout) )
532530 }
@@ -562,7 +560,7 @@ impl<A: Allocator> RawVecInner<A> {
562560 #[ inline]
563561 #[ track_caller]
564562 fn grow_one ( & mut self , elem_layout : Layout ) {
565- if let Err ( err) = self . grow_amortized ( self . cap . 0 , 1 , elem_layout) {
563+ if let Err ( err) = self . grow_amortized ( self . cap . as_inner ( ) , 1 , elem_layout) {
566564 handle_error ( err) ;
567565 }
568566 }
@@ -627,7 +625,7 @@ impl<A: Allocator> RawVecInner<A> {
627625 // the size requested. If that ever changes, the capacity here should
628626 // change to `ptr.len() / mem::size_of::<T>()`.
629627 self . ptr = Unique :: from ( ptr. cast ( ) ) ;
630- self . cap = unsafe { Cap ( cap) } ;
628+ self . cap = unsafe { Cap :: new_unchecked ( cap) } ;
631629 }
632630
633631 fn grow_amortized (
@@ -650,7 +648,7 @@ impl<A: Allocator> RawVecInner<A> {
650648
651649 // This guarantees exponential growth. The doubling cannot overflow
652650 // because `cap <= isize::MAX` and the type of `cap` is `usize`.
653- let cap = cmp:: max ( self . cap . 0 * 2 , required_cap) ;
651+ let cap = cmp:: max ( self . cap . as_inner ( ) * 2 , required_cap) ;
654652 let cap = cmp:: max ( min_non_zero_cap ( elem_layout. size ( ) ) , cap) ;
655653
656654 let new_layout = layout_array ( cap, elem_layout) ?;
@@ -719,7 +717,7 @@ impl<A: Allocator> RawVecInner<A> {
719717 unsafe { self . alloc . deallocate ( ptr, layout) } ;
720718 self . ptr =
721719 unsafe { Unique :: new_unchecked ( ptr:: without_provenance_mut ( elem_layout. align ( ) ) ) } ;
722- self . cap = Cap :: ZERO ;
720+ self . cap = ZERO_CAP ;
723721 } else {
724722 let ptr = unsafe {
725723 // Layout cannot overflow here because it would have
0 commit comments