@@ -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
@@ -511,6 +520,7 @@ impl<A: Array> SmallVec<A> {
511520 ///
512521 /// ```rust
513522 /// use smallvec::SmallVec;
523+ /// use std::mem::MaybeUninit;
514524 ///
515525 /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
516526 /// let small_vec: SmallVec<_> = unsafe {
@@ -523,7 +533,7 @@ impl<A: Array> SmallVec<A> {
523533 pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
524534 SmallVec {
525535 capacity : len,
526- data : SmallVecData :: from_inline ( buf) ,
536+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
527537 }
528538 }
529539
@@ -571,7 +581,7 @@ impl<A: Array> SmallVec<A> {
571581 let ( ptr, len) = self . data . heap ( ) ;
572582 ( ptr, len, self . capacity )
573583 } else {
574- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
584+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575585 }
576586 }
577587 }
@@ -584,7 +594,7 @@ impl<A: Array> SmallVec<A> {
584594 let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585595 ( ptr, len_ptr, self . capacity )
586596 } else {
587- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
597+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588598 }
589599 }
590600 }
@@ -651,8 +661,8 @@ impl<A: Array> SmallVec<A> {
651661 if unspilled {
652662 return ;
653663 }
654- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
655- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
664+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
665+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
656666 self . capacity = len;
657667 } else if new_cap != cap {
658668 let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +727,8 @@ impl<A: Array> SmallVec<A> {
717727 if self . inline_size ( ) >= len {
718728 unsafe {
719729 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) ;
730+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
731+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
722732 deallocate ( ptr, self . capacity ) ;
723733 self . capacity = len;
724734 }
@@ -883,7 +893,7 @@ impl<A: Array> SmallVec<A> {
883893 unsafe {
884894 let data = ptr:: read ( & self . data ) ;
885895 mem:: forget ( self ) ;
886- Ok ( data. into_inline ( ) )
896+ Ok ( data. into_inline ( ) . assume_init ( ) )
887897 }
888898 }
889899 }
@@ -1041,8 +1051,12 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
10411051 SmallVec {
10421052 capacity : len,
10431053 data : SmallVecData :: from_inline ( unsafe {
1044- let mut data: A = mem:: uninitialized ( ) ;
1045- ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. ptr_mut ( ) , len) ;
1054+ let mut data: MaybeUninit < A > = MaybeUninit :: uninit ( ) ;
1055+ ptr:: copy_nonoverlapping (
1056+ slice. as_ptr ( ) ,
1057+ data. as_mut_ptr ( ) as * mut A :: Item ,
1058+ len,
1059+ ) ;
10461060 data
10471061 } )
10481062 }
@@ -1587,8 +1601,8 @@ macro_rules! impl_array(
15871601 unsafe impl <T > Array for [ T ; $size] {
15881602 type Item = T ;
15891603 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 ( ) }
1604+ fn ptr( & self ) -> * const T { unimplemented! ( ) }
1605+ fn ptr_mut( & mut self ) -> * mut T { unimplemented! ( ) }
15921606 }
15931607 ) +
15941608 }
@@ -1889,7 +1903,7 @@ mod tests {
18891903 assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
18901904 }
18911905
1892- #[ cfg( feature = "std" ) ]
1906+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
18931907 #[ test]
18941908 // https://github.com/servo/rust-smallvec/issues/96
18951909 fn test_insert_many_panic ( ) {
0 commit comments