@@ -45,18 +45,21 @@ use alloc::vec::Vec;
4545#[ cfg( feature = "serde" ) ]
4646extern crate serde;
4747
48+ extern crate maybe_uninit;
49+
4850#[ cfg( not( feature = "std" ) ) ]
4951mod std {
5052 pub use core:: * ;
5153}
5254
55+ use maybe_uninit:: MaybeUninit ;
56+
5357use std:: borrow:: { Borrow , BorrowMut } ;
5458use std:: cmp;
5559use std:: fmt;
5660use std:: hash:: { Hash , Hasher } ;
5761use std:: iter:: { IntoIterator , FromIterator , repeat} ;
5862use std:: mem;
59- use std:: mem:: ManuallyDrop ;
6063use std:: ops;
6164use std:: ptr;
6265use std:: slice;
@@ -275,26 +278,28 @@ impl<'a, T: 'a> Drop for Drain<'a,T> {
275278
276279#[ cfg( feature = "union" ) ]
277280union SmallVecData < A : Array > {
278- inline : ManuallyDrop < A > ,
281+ inline : MaybeUninit < A > ,
279282 heap : ( * mut A :: Item , usize ) ,
280283}
281284
282285#[ cfg( feature = "union" ) ]
283286impl < A : Array > SmallVecData < A > {
284287 #[ 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
287290 }
288291 #[ 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
291294 }
292295 #[ 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 }
295298 }
296299 #[ 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+ }
298303 #[ inline]
299304 unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
300305 self . heap
@@ -311,34 +316,34 @@ impl<A: Array> SmallVecData<A> {
311316
312317#[ cfg( not( feature = "union" ) ) ]
313318enum SmallVecData < A : Array > {
314- Inline ( ManuallyDrop < A > ) ,
319+ Inline ( MaybeUninit < A > ) ,
315320 Heap ( ( * mut A :: Item , usize ) ) ,
316321}
317322
318323#[ cfg( not( feature = "union" ) ) ]
319324impl < A : Array > SmallVecData < A > {
320325 #[ inline]
321- unsafe fn inline ( & self ) -> & A {
326+ unsafe fn inline ( & self ) -> * const A :: Item {
322327 match * self {
323- SmallVecData :: Inline ( ref a) => a,
328+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
324329 _ => debug_unreachable ! ( ) ,
325330 }
326331 }
327332 #[ inline]
328- unsafe fn inline_mut ( & mut self ) -> & mut A {
333+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
329334 match * self {
330- SmallVecData :: Inline ( ref mut a) => a,
335+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
331336 _ => debug_unreachable ! ( ) ,
332337 }
333338 }
334339 #[ 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)
337342 }
338343 #[ inline]
339- unsafe fn into_inline ( self ) -> A {
344+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
340345 match self {
341- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
346+ SmallVecData :: Inline ( a) => a ,
342347 _ => debug_unreachable ! ( ) ,
343348 }
344349 }
@@ -403,11 +408,15 @@ impl<A: Array> SmallVec<A> {
403408 /// Construct an empty vector
404409 #[ inline]
405410 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 ( ) ) ,
411420 }
412421 }
413422
@@ -447,10 +456,10 @@ impl<A: Array> SmallVec<A> {
447456 pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448457 if vec. capacity ( ) <= A :: size ( ) {
449458 unsafe {
450- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
459+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451460 let len = vec. len ( ) ;
452461 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) ;
454463
455464 SmallVec {
456465 capacity : len,
@@ -483,7 +492,7 @@ impl<A: Array> SmallVec<A> {
483492 pub fn from_buf ( buf : A ) -> SmallVec < A > {
484493 SmallVec {
485494 capacity : A :: size ( ) ,
486- data : SmallVecData :: from_inline ( buf) ,
495+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487496 }
488497 }
489498
@@ -523,7 +532,7 @@ impl<A: Array> SmallVec<A> {
523532 pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
524533 SmallVec {
525534 capacity : len,
526- data : SmallVecData :: from_inline ( buf) ,
535+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
527536 }
528537 }
529538
@@ -571,7 +580,7 @@ impl<A: Array> SmallVec<A> {
571580 let ( ptr, len) = self . data . heap ( ) ;
572581 ( ptr, len, self . capacity )
573582 } else {
574- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
583+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575584 }
576585 }
577586 }
@@ -584,7 +593,7 @@ impl<A: Array> SmallVec<A> {
584593 let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585594 ( ptr, len_ptr, self . capacity )
586595 } else {
587- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
596+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588597 }
589598 }
590599 }
@@ -651,8 +660,8 @@ impl<A: Array> SmallVec<A> {
651660 if unspilled {
652661 return ;
653662 }
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) ;
656665 self . capacity = len;
657666 } else if new_cap != cap {
658667 let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +726,8 @@ impl<A: Array> SmallVec<A> {
717726 if self . inline_size ( ) >= len {
718727 unsafe {
719728 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) ;
722731 deallocate ( ptr, self . capacity ) ;
723732 self . capacity = len;
724733 }
@@ -883,7 +892,7 @@ impl<A: Array> SmallVec<A> {
883892 unsafe {
884893 let data = ptr:: read ( & self . data ) ;
885894 mem:: forget ( self ) ;
886- Ok ( data. into_inline ( ) )
895+ Ok ( data. into_inline ( ) . assume_init ( ) )
887896 }
888897 }
889898 }
@@ -1041,8 +1050,12 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
10411050 SmallVec {
10421051 capacity : len,
10431052 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+ ) ;
10461059 data
10471060 } )
10481061 }
@@ -1587,8 +1600,8 @@ macro_rules! impl_array(
15871600 unsafe impl <T > Array for [ T ; $size] {
15881601 type Item = T ;
15891602 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! ( ) }
15921605 }
15931606 ) +
15941607 }
@@ -1889,7 +1902,7 @@ mod tests {
18891902 assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
18901903 }
18911904
1892- #[ cfg( feature = "std" ) ]
1905+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
18931906 #[ test]
18941907 // https://github.com/servo/rust-smallvec/issues/96
18951908 fn test_insert_many_panic ( ) {
0 commit comments