@@ -33,21 +33,15 @@ enum AllocInit {
33
33
Zeroed ,
34
34
}
35
35
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 ;
41
37
42
- impl Cap {
43
- const ZERO : Cap = unsafe { Cap ( 0 ) } ;
38
+ const ZERO_CAP : Cap = unsafe { Cap :: new_unchecked ( 0 ) } ;
44
39
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) } }
51
45
}
52
46
53
47
/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
@@ -257,7 +251,7 @@ impl<T, A: Allocator> RawVec<T, A> {
257
251
// SAFETY: Precondition passed to the caller
258
252
unsafe {
259
253
let ptr = ptr. cast ( ) ;
260
- let capacity = Cap :: new :: < T > ( capacity) ;
254
+ let capacity = new_cap :: < T > ( capacity) ;
261
255
Self {
262
256
inner : RawVecInner :: from_raw_parts_in ( ptr, capacity, alloc) ,
263
257
_marker : PhantomData ,
@@ -275,7 +269,7 @@ impl<T, A: Allocator> RawVec<T, A> {
275
269
// SAFETY: Precondition passed to the caller
276
270
unsafe {
277
271
let ptr = ptr. cast ( ) ;
278
- let capacity = Cap :: new :: < T > ( capacity) ;
272
+ let capacity = new_cap :: < T > ( capacity) ;
279
273
Self { inner : RawVecInner :: from_nonnull_in ( ptr, capacity, alloc) , _marker : PhantomData }
280
274
}
281
275
}
@@ -410,7 +404,7 @@ impl<A: Allocator> RawVecInner<A> {
410
404
const fn new_in ( alloc : A , align : usize ) -> Self {
411
405
let ptr = unsafe { core:: mem:: transmute ( align) } ;
412
406
// `cap: 0` means "unallocated". zero-sized types are ignored.
413
- Self { ptr, cap : Cap :: ZERO , alloc }
407
+ Self { ptr, cap : ZERO_CAP , alloc }
414
408
}
415
409
416
410
#[ cfg( not( no_global_oom_handling) ) ]
@@ -483,7 +477,11 @@ impl<A: Allocator> RawVecInner<A> {
483
477
// Allocators currently return a `NonNull<[u8]>` whose length
484
478
// matches the size requested. If that ever changes, the capacity
485
479
// 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
+ } )
487
485
}
488
486
489
487
#[ inline]
@@ -508,7 +506,7 @@ impl<A: Allocator> RawVecInner<A> {
508
506
509
507
#[ inline]
510
508
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 ( ) }
512
510
}
513
511
514
512
#[ inline]
@@ -518,15 +516,15 @@ impl<A: Allocator> RawVecInner<A> {
518
516
519
517
#[ inline]
520
518
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 {
522
520
None
523
521
} else {
524
522
// We could use Layout::array here which ensures the absence of isize and usize overflows
525
523
// and could hypothetically handle differences between stride and size, but this memory
526
524
// has already been allocated so we know it can't overflow and currently Rust does not
527
525
// support such types. So we can do better by skipping some checks and avoid an unwrap.
528
526
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 ( ) ) ;
530
528
let layout = Layout :: from_size_align_unchecked ( alloc_size, elem_layout. align ( ) ) ;
531
529
Some ( ( self . ptr . into ( ) , layout) )
532
530
}
@@ -562,7 +560,7 @@ impl<A: Allocator> RawVecInner<A> {
562
560
#[ inline]
563
561
#[ track_caller]
564
562
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) {
566
564
handle_error ( err) ;
567
565
}
568
566
}
@@ -627,7 +625,7 @@ impl<A: Allocator> RawVecInner<A> {
627
625
// the size requested. If that ever changes, the capacity here should
628
626
// change to `ptr.len() / mem::size_of::<T>()`.
629
627
self . ptr = Unique :: from ( ptr. cast ( ) ) ;
630
- self . cap = unsafe { Cap ( cap) } ;
628
+ self . cap = unsafe { Cap :: new_unchecked ( cap) } ;
631
629
}
632
630
633
631
fn grow_amortized (
@@ -650,7 +648,7 @@ impl<A: Allocator> RawVecInner<A> {
650
648
651
649
// This guarantees exponential growth. The doubling cannot overflow
652
650
// 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) ;
654
652
let cap = cmp:: max ( min_non_zero_cap ( elem_layout. size ( ) ) , cap) ;
655
653
656
654
let new_layout = layout_array ( cap, elem_layout) ?;
@@ -719,7 +717,7 @@ impl<A: Allocator> RawVecInner<A> {
719
717
unsafe { self . alloc . deallocate ( ptr, layout) } ;
720
718
self . ptr =
721
719
unsafe { Unique :: new_unchecked ( ptr:: without_provenance_mut ( elem_layout. align ( ) ) ) } ;
722
- self . cap = Cap :: ZERO ;
720
+ self . cap = ZERO_CAP ;
723
721
} else {
724
722
let ptr = unsafe {
725
723
// Layout cannot overflow here because it would have
0 commit comments