@@ -241,10 +241,15 @@ impl<T, A: Allocator> RawVec<T, A> {
241
241
if T :: IS_ZST || self . cap == 0 {
242
242
None
243
243
} else {
244
- // We have an allocated chunk of memory, so we can bypass runtime
245
- // checks to get our current layout.
244
+ // We could use Layout::array here which ensures the absence of isize and usize overflows
245
+ // and could hypothetically handle differences between stride and size, but this memory
246
+ // has already been allocated so we know it can't overflow and currently rust does not
247
+ // support such types. So we can do better by skipping some checks and avoid an unwrap.
248
+ let _: ( ) = const { assert ! ( mem:: size_of:: <T >( ) % mem:: align_of:: <T >( ) == 0 ) } ;
246
249
unsafe {
247
- let layout = Layout :: array :: < T > ( self . cap ) . unwrap_unchecked ( ) ;
250
+ let align = mem:: align_of :: < T > ( ) ;
251
+ let size = mem:: size_of :: < T > ( ) . unchecked_mul ( self . cap ) ;
252
+ let layout = Layout :: from_size_align_unchecked ( size, align) ;
248
253
Some ( ( self . ptr . cast ( ) . into ( ) , layout) )
249
254
}
250
255
}
@@ -426,11 +431,13 @@ impl<T, A: Allocator> RawVec<T, A> {
426
431
assert ! ( cap <= self . capacity( ) , "Tried to shrink to a larger capacity" ) ;
427
432
428
433
let ( ptr, layout) = if let Some ( mem) = self . current_memory ( ) { mem } else { return Ok ( ( ) ) } ;
429
-
434
+ // See current_memory() why this assert is here
435
+ let _: ( ) = const { assert ! ( mem:: size_of:: <T >( ) % mem:: align_of:: <T >( ) == 0 ) } ;
430
436
let ptr = unsafe {
431
437
// `Layout::array` cannot overflow here because it would have
432
438
// overflowed earlier when capacity was larger.
433
- let new_layout = Layout :: array :: < T > ( cap) . unwrap_unchecked ( ) ;
439
+ let new_size = mem:: size_of :: < T > ( ) . unchecked_mul ( cap) ;
440
+ let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
434
441
self . alloc
435
442
. shrink ( ptr, layout, new_layout)
436
443
. map_err ( |_| AllocError { layout : new_layout, non_exhaustive : ( ) } ) ?
0 commit comments