@@ -45,18 +45,21 @@ use alloc::vec::Vec;
45
45
#[ cfg( feature = "serde" ) ]
46
46
extern crate serde;
47
47
48
+ extern crate maybe_uninit;
49
+
48
50
#[ cfg( not( feature = "std" ) ) ]
49
51
mod std {
50
52
pub use core:: * ;
51
53
}
52
54
55
+ use maybe_uninit:: MaybeUninit ;
56
+
53
57
use std:: borrow:: { Borrow , BorrowMut } ;
54
58
use std:: cmp;
55
59
use std:: fmt;
56
60
use std:: hash:: { Hash , Hasher } ;
57
61
use std:: iter:: { IntoIterator , FromIterator , repeat} ;
58
62
use std:: mem;
59
- use std:: mem:: ManuallyDrop ;
60
63
use std:: ops;
61
64
use std:: ptr;
62
65
use std:: slice;
@@ -275,26 +278,28 @@ impl<'a, T: 'a> Drop for Drain<'a,T> {
275
278
276
279
#[ cfg( feature = "union" ) ]
277
280
union SmallVecData < A : Array > {
278
- inline : ManuallyDrop < A > ,
281
+ inline : MaybeUninit < A > ,
279
282
heap : ( * mut A :: Item , usize ) ,
280
283
}
281
284
282
285
#[ cfg( feature = "union" ) ]
283
286
impl < A : Array > SmallVecData < A > {
284
287
#[ inline]
285
- unsafe fn inline ( & self ) -> & A {
286
- & self . inline
288
+ unsafe fn inline ( & self ) -> * const A :: Item {
289
+ self . inline . as_ptr ( ) as * const A :: Item
287
290
}
288
291
#[ inline]
289
- unsafe fn inline_mut ( & mut self ) -> & mut A {
290
- & mut self . inline
292
+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
293
+ self . inline . as_mut_ptr ( ) as * mut A :: Item
291
294
}
292
295
#[ inline]
293
- fn from_inline ( inline : A ) -> SmallVecData < A > {
294
- SmallVecData { inline : ManuallyDrop :: new ( inline ) }
296
+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
297
+ SmallVecData { inline }
295
298
}
296
299
#[ inline]
297
- unsafe fn into_inline ( self ) -> A { ManuallyDrop :: into_inner ( self . inline ) }
300
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
301
+ self . inline
302
+ }
298
303
#[ inline]
299
304
unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
300
305
self . heap
@@ -311,34 +316,34 @@ impl<A: Array> SmallVecData<A> {
311
316
312
317
#[ cfg( not( feature = "union" ) ) ]
313
318
enum SmallVecData < A : Array > {
314
- Inline ( ManuallyDrop < A > ) ,
319
+ Inline ( MaybeUninit < A > ) ,
315
320
Heap ( ( * mut A :: Item , usize ) ) ,
316
321
}
317
322
318
323
#[ cfg( not( feature = "union" ) ) ]
319
324
impl < A : Array > SmallVecData < A > {
320
325
#[ inline]
321
- unsafe fn inline ( & self ) -> & A {
326
+ unsafe fn inline ( & self ) -> * const A :: Item {
322
327
match * self {
323
- SmallVecData :: Inline ( ref a) => a,
328
+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
324
329
_ => debug_unreachable ! ( ) ,
325
330
}
326
331
}
327
332
#[ inline]
328
- unsafe fn inline_mut ( & mut self ) -> & mut A {
333
+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
329
334
match * self {
330
- SmallVecData :: Inline ( ref mut a) => a,
335
+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
331
336
_ => debug_unreachable ! ( ) ,
332
337
}
333
338
}
334
339
#[ inline]
335
- fn from_inline ( inline : A ) -> SmallVecData < A > {
336
- SmallVecData :: Inline ( ManuallyDrop :: new ( inline) )
340
+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
341
+ SmallVecData :: Inline ( inline)
337
342
}
338
343
#[ inline]
339
- unsafe fn into_inline ( self ) -> A {
344
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
340
345
match self {
341
- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
346
+ SmallVecData :: Inline ( a) => a ,
342
347
_ => debug_unreachable ! ( ) ,
343
348
}
344
349
}
@@ -403,11 +408,15 @@ impl<A: Array> SmallVec<A> {
403
408
/// Construct an empty vector
404
409
#[ inline]
405
410
pub fn new ( ) -> SmallVec < A > {
406
- unsafe {
407
- SmallVec {
408
- capacity : 0 ,
409
- data : SmallVecData :: from_inline ( mem:: uninitialized ( ) ) ,
410
- }
411
+ // Try to detect invalid custom implementations of `Array`. Hopefuly,
412
+ // this check should be optimized away entirely for valid ones.
413
+ assert ! (
414
+ mem:: size_of:: <A >( ) == A :: size( ) * mem:: size_of:: <A :: Item >( )
415
+ && mem:: align_of:: <A >( ) >= mem:: align_of:: <A :: Item >( )
416
+ ) ;
417
+ SmallVec {
418
+ capacity : 0 ,
419
+ data : SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ,
411
420
}
412
421
}
413
422
@@ -447,10 +456,10 @@ impl<A: Array> SmallVec<A> {
447
456
pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448
457
if vec. capacity ( ) <= A :: size ( ) {
449
458
unsafe {
450
- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
459
+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451
460
let len = vec. len ( ) ;
452
461
vec. set_len ( 0 ) ;
453
- ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) . ptr_mut ( ) , len) ;
462
+ ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) , len) ;
454
463
455
464
SmallVec {
456
465
capacity : len,
@@ -483,7 +492,7 @@ impl<A: Array> SmallVec<A> {
483
492
pub fn from_buf ( buf : A ) -> SmallVec < A > {
484
493
SmallVec {
485
494
capacity : A :: size ( ) ,
486
- data : SmallVecData :: from_inline ( buf) ,
495
+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487
496
}
488
497
}
489
498
@@ -523,7 +532,7 @@ impl<A: Array> SmallVec<A> {
523
532
pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
524
533
SmallVec {
525
534
capacity : len,
526
- data : SmallVecData :: from_inline ( buf) ,
535
+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
527
536
}
528
537
}
529
538
@@ -571,7 +580,7 @@ impl<A: Array> SmallVec<A> {
571
580
let ( ptr, len) = self . data . heap ( ) ;
572
581
( ptr, len, self . capacity )
573
582
} else {
574
- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
583
+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575
584
}
576
585
}
577
586
}
@@ -584,7 +593,7 @@ impl<A: Array> SmallVec<A> {
584
593
let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585
594
( ptr, len_ptr, self . capacity )
586
595
} else {
587
- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
596
+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588
597
}
589
598
}
590
599
}
@@ -651,8 +660,8 @@ impl<A: Array> SmallVec<A> {
651
660
if unspilled {
652
661
return ;
653
662
}
654
- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
655
- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
663
+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
664
+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
656
665
self . capacity = len;
657
666
} else if new_cap != cap {
658
667
let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +726,8 @@ impl<A: Array> SmallVec<A> {
717
726
if self . inline_size ( ) >= len {
718
727
unsafe {
719
728
let ( ptr, len) = self . data . heap ( ) ;
720
- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
721
- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
729
+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
730
+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
722
731
deallocate ( ptr, self . capacity ) ;
723
732
self . capacity = len;
724
733
}
@@ -883,7 +892,7 @@ impl<A: Array> SmallVec<A> {
883
892
unsafe {
884
893
let data = ptr:: read ( & self . data ) ;
885
894
mem:: forget ( self ) ;
886
- Ok ( data. into_inline ( ) )
895
+ Ok ( data. into_inline ( ) . assume_init ( ) )
887
896
}
888
897
}
889
898
}
@@ -1041,8 +1050,12 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
1041
1050
SmallVec {
1042
1051
capacity : len,
1043
1052
data : SmallVecData :: from_inline ( unsafe {
1044
- let mut data: A = mem:: uninitialized ( ) ;
1045
- ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. ptr_mut ( ) , len) ;
1053
+ let mut data: MaybeUninit < A > = MaybeUninit :: uninit ( ) ;
1054
+ ptr:: copy_nonoverlapping (
1055
+ slice. as_ptr ( ) ,
1056
+ data. as_mut_ptr ( ) as * mut A :: Item ,
1057
+ len,
1058
+ ) ;
1046
1059
data
1047
1060
} )
1048
1061
}
@@ -1587,8 +1600,8 @@ macro_rules! impl_array(
1587
1600
unsafe impl <T > Array for [ T ; $size] {
1588
1601
type Item = T ;
1589
1602
fn size( ) -> usize { $size }
1590
- fn ptr( & self ) -> * const T { self . as_ptr ( ) }
1591
- fn ptr_mut( & mut self ) -> * mut T { self . as_mut_ptr ( ) }
1603
+ fn ptr( & self ) -> * const T { unimplemented! ( ) }
1604
+ fn ptr_mut( & mut self ) -> * mut T { unimplemented! ( ) }
1592
1605
}
1593
1606
) +
1594
1607
}
@@ -1889,7 +1902,7 @@ mod tests {
1889
1902
assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
1890
1903
}
1891
1904
1892
- #[ cfg( feature = "std" ) ]
1905
+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
1893
1906
#[ test]
1894
1907
// https://github.com/servo/rust-smallvec/issues/96
1895
1908
fn test_insert_many_panic ( ) {
0 commit comments