@@ -63,7 +63,7 @@ use std::iter::{repeat, FromIterator, IntoIterator};
63
63
#[ cfg( feature = "serde" ) ]
64
64
use std:: marker:: PhantomData ;
65
65
use std:: mem;
66
- use std:: mem:: ManuallyDrop ;
66
+ use std:: mem:: MaybeUninit ;
67
67
use std:: ops;
68
68
use std:: ptr;
69
69
use std:: slice;
@@ -280,29 +280,27 @@ impl<'a, T: 'a> Drop for Drain<'a, T> {
280
280
281
281
#[ cfg( feature = "union" ) ]
282
282
union SmallVecData < A : Array > {
283
- inline : ManuallyDrop < A > ,
283
+ inline : MaybeUninit < A > ,
284
284
heap : ( * mut A :: Item , usize ) ,
285
285
}
286
286
287
287
#[ cfg( feature = "union" ) ]
288
288
impl < A : Array > SmallVecData < A > {
289
289
#[ inline]
290
- unsafe fn inline ( & self ) -> & A {
291
- & self . inline
290
+ unsafe fn inline ( & self ) -> * const A :: Item {
291
+ self . inline . as_ptr ( ) as * const A :: Item
292
292
}
293
293
#[ inline]
294
- unsafe fn inline_mut ( & mut self ) -> & mut A {
295
- & mut self . inline
294
+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
295
+ self . inline . as_mut_ptr ( ) as * mut A :: Item
296
296
}
297
297
#[ inline]
298
- fn from_inline ( inline : A ) -> SmallVecData < A > {
299
- SmallVecData {
300
- inline : ManuallyDrop :: new ( inline) ,
301
- }
298
+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
299
+ SmallVecData { inline }
302
300
}
303
301
#[ inline]
304
- unsafe fn into_inline ( self ) -> A {
305
- ManuallyDrop :: into_inner ( self . inline )
302
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
303
+ self . inline
306
304
}
307
305
#[ inline]
308
306
unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
@@ -320,34 +318,34 @@ impl<A: Array> SmallVecData<A> {
320
318
321
319
#[ cfg( not( feature = "union" ) ) ]
322
320
enum SmallVecData < A : Array > {
323
- Inline ( ManuallyDrop < A > ) ,
321
+ Inline ( MaybeUninit < A > ) ,
324
322
Heap ( ( * mut A :: Item , usize ) ) ,
325
323
}
326
324
327
325
#[ cfg( not( feature = "union" ) ) ]
328
326
impl < A : Array > SmallVecData < A > {
329
327
#[ inline]
330
- unsafe fn inline ( & self ) -> & A {
328
+ unsafe fn inline ( & self ) -> * const A :: Item {
331
329
match * self {
332
- SmallVecData :: Inline ( ref a) => a,
330
+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
333
331
_ => debug_unreachable ! ( ) ,
334
332
}
335
333
}
336
334
#[ inline]
337
- unsafe fn inline_mut ( & mut self ) -> & mut A {
335
+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
338
336
match * self {
339
- SmallVecData :: Inline ( ref mut a) => a,
337
+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
340
338
_ => debug_unreachable ! ( ) ,
341
339
}
342
340
}
343
341
#[ inline]
344
- fn from_inline ( inline : A ) -> SmallVecData < A > {
345
- SmallVecData :: Inline ( ManuallyDrop :: new ( inline) )
342
+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
343
+ SmallVecData :: Inline ( inline)
346
344
}
347
345
#[ inline]
348
- unsafe fn into_inline ( self ) -> A {
346
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
349
347
match self {
350
- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
348
+ SmallVecData :: Inline ( a) => a ,
351
349
_ => debug_unreachable ! ( ) ,
352
350
}
353
351
}
@@ -412,11 +410,15 @@ impl<A: Array> SmallVec<A> {
412
410
/// Construct an empty vector
413
411
#[ inline]
414
412
pub fn new ( ) -> SmallVec < A > {
415
- unsafe {
416
- SmallVec {
417
- capacity : 0 ,
418
- data : SmallVecData :: from_inline ( mem:: uninitialized ( ) ) ,
419
- }
413
+ // Try to detect invalid custom implementations of `Array`. Hopefuly,
414
+ // this check should be optimized away entirely for valid ones.
415
+ assert ! (
416
+ mem:: size_of:: <A >( ) == A :: size( ) * mem:: size_of:: <A :: Item >( )
417
+ && mem:: align_of:: <A >( ) >= mem:: align_of:: <A :: Item >( )
418
+ ) ;
419
+ SmallVec {
420
+ capacity : 0 ,
421
+ data : SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ,
420
422
}
421
423
}
422
424
@@ -456,10 +458,10 @@ impl<A: Array> SmallVec<A> {
456
458
pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
457
459
if vec. capacity ( ) <= A :: size ( ) {
458
460
unsafe {
459
- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
461
+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
460
462
let len = vec. len ( ) ;
461
463
vec. set_len ( 0 ) ;
462
- ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) . ptr_mut ( ) , len) ;
464
+ ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) , len) ;
463
465
464
466
SmallVec {
465
467
capacity : len,
@@ -492,7 +494,7 @@ impl<A: Array> SmallVec<A> {
492
494
pub fn from_buf ( buf : A ) -> SmallVec < A > {
493
495
SmallVec {
494
496
capacity : A :: size ( ) ,
495
- data : SmallVecData :: from_inline ( buf) ,
497
+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
496
498
}
497
499
}
498
500
@@ -511,7 +513,7 @@ impl<A: Array> SmallVec<A> {
511
513
#[ inline]
512
514
pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
513
515
assert ! ( len <= A :: size( ) ) ;
514
- unsafe { SmallVec :: from_buf_and_len_unchecked ( buf, len) }
516
+ unsafe { SmallVec :: from_buf_and_len_unchecked ( MaybeUninit :: new ( buf) , len) }
515
517
}
516
518
517
519
/// Constructs a new `SmallVec` on the stack from an `A` without
@@ -520,16 +522,17 @@ impl<A: Array> SmallVec<A> {
520
522
///
521
523
/// ```rust
522
524
/// use smallvec::SmallVec;
525
+ /// use std::mem::MaybeUninit;
523
526
///
524
527
/// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
525
528
/// let small_vec: SmallVec<_> = unsafe {
526
- /// SmallVec::from_buf_and_len_unchecked(buf, 5)
529
+ /// SmallVec::from_buf_and_len_unchecked(MaybeUninit::new( buf) , 5)
527
530
/// };
528
531
///
529
532
/// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
530
533
/// ```
531
534
#[ inline]
532
- pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
535
+ pub unsafe fn from_buf_and_len_unchecked ( buf : MaybeUninit < A > , len : usize ) -> SmallVec < A > {
533
536
SmallVec {
534
537
capacity : len,
535
538
data : SmallVecData :: from_inline ( buf) ,
@@ -579,7 +582,7 @@ impl<A: Array> SmallVec<A> {
579
582
let ( ptr, len) = self . data . heap ( ) ;
580
583
( ptr, len, self . capacity )
581
584
} else {
582
- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
585
+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
583
586
}
584
587
}
585
588
}
@@ -592,11 +595,7 @@ impl<A: Array> SmallVec<A> {
592
595
let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
593
596
( ptr, len_ptr, self . capacity )
594
597
} else {
595
- (
596
- self . data . inline_mut ( ) . ptr_mut ( ) ,
597
- & mut self . capacity ,
598
- A :: size ( ) ,
599
- )
598
+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
600
599
}
601
600
}
602
601
}
@@ -663,8 +662,8 @@ impl<A: Array> SmallVec<A> {
663
662
if unspilled {
664
663
return ;
665
664
}
666
- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
667
- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
665
+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
666
+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
668
667
self . capacity = len;
669
668
} else if new_cap != cap {
670
669
let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -730,8 +729,8 @@ impl<A: Array> SmallVec<A> {
730
729
if self . inline_size ( ) >= len {
731
730
unsafe {
732
731
let ( ptr, len) = self . data . heap ( ) ;
733
- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
734
- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
732
+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
733
+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
735
734
deallocate ( ptr, self . capacity ) ;
736
735
self . capacity = len;
737
736
}
@@ -900,7 +899,7 @@ impl<A: Array> SmallVec<A> {
900
899
unsafe {
901
900
let data = ptr:: read ( & self . data ) ;
902
901
mem:: forget ( self ) ;
903
- Ok ( data. into_inline ( ) )
902
+ Ok ( data. into_inline ( ) . assume_init ( ) )
904
903
}
905
904
}
906
905
}
@@ -1062,8 +1061,12 @@ where
1062
1061
SmallVec {
1063
1062
capacity : len,
1064
1063
data : SmallVecData :: from_inline ( unsafe {
1065
- let mut data: A = mem:: uninitialized ( ) ;
1066
- ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. ptr_mut ( ) , len) ;
1064
+ let mut data: MaybeUninit < A > = MaybeUninit :: uninit ( ) ;
1065
+ ptr:: copy_nonoverlapping (
1066
+ slice. as_ptr ( ) ,
1067
+ data. as_mut_ptr ( ) as * mut A :: Item ,
1068
+ len,
1069
+ ) ;
1067
1070
data
1068
1071
} ) ,
1069
1072
}
@@ -1603,10 +1606,6 @@ pub unsafe trait Array {
1603
1606
type Item ;
1604
1607
/// Returns the number of items the array can hold.
1605
1608
fn size ( ) -> usize ;
1606
- /// Returns a pointer to the first element of the array.
1607
- fn ptr ( & self ) -> * const Self :: Item ;
1608
- /// Returns a mutable pointer to the first element of the array.
1609
- fn ptr_mut ( & mut self ) -> * mut Self :: Item ;
1610
1609
}
1611
1610
1612
1611
/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1650,8 +1649,6 @@ macro_rules! impl_array(
1650
1649
unsafe impl <T > Array for [ T ; $size] {
1651
1650
type Item = T ;
1652
1651
fn size( ) -> usize { $size }
1653
- fn ptr( & self ) -> * const T { self . as_ptr( ) }
1654
- fn ptr_mut( & mut self ) -> * mut T { self . as_mut_ptr( ) }
1655
1652
}
1656
1653
) +
1657
1654
}
@@ -1985,7 +1982,7 @@ mod tests {
1985
1982
) ;
1986
1983
}
1987
1984
1988
- #[ cfg( feature = "std" ) ]
1985
+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
1989
1986
#[ test]
1990
1987
// https://github.com/servo/rust-smallvec/issues/96
1991
1988
fn test_insert_many_panic ( ) {
0 commit comments