@@ -63,7 +63,7 @@ use std::iter::{repeat, FromIterator, IntoIterator};
6363#[ cfg( feature = "serde" ) ]
6464use std:: marker:: PhantomData ;
6565use std:: mem;
66- use std:: mem:: ManuallyDrop ;
66+ use std:: mem:: MaybeUninit ;
6767use std:: ops;
6868use std:: ptr;
6969use std:: slice;
@@ -280,29 +280,27 @@ impl<'a, T: 'a> Drop for Drain<'a, T> {
280280
281281#[ cfg( feature = "union" ) ]
282282union SmallVecData < A : Array > {
283- inline : ManuallyDrop < A > ,
283+ inline : MaybeUninit < A > ,
284284 heap : ( * mut A :: Item , usize ) ,
285285}
286286
287287#[ cfg( feature = "union" ) ]
288288impl < A : Array > SmallVecData < A > {
289289 #[ 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
292292 }
293293 #[ 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
296296 }
297297 #[ 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 }
302300 }
303301 #[ 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
306304 }
307305 #[ inline]
308306 unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
@@ -320,34 +318,34 @@ impl<A: Array> SmallVecData<A> {
320318
321319#[ cfg( not( feature = "union" ) ) ]
322320enum SmallVecData < A : Array > {
323- Inline ( ManuallyDrop < A > ) ,
321+ Inline ( MaybeUninit < A > ) ,
324322 Heap ( ( * mut A :: Item , usize ) ) ,
325323}
326324
327325#[ cfg( not( feature = "union" ) ) ]
328326impl < A : Array > SmallVecData < A > {
329327 #[ inline]
330- unsafe fn inline ( & self ) -> & A {
328+ unsafe fn inline ( & self ) -> * const A :: Item {
331329 match * self {
332- SmallVecData :: Inline ( ref a) => a,
330+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
333331 _ => debug_unreachable ! ( ) ,
334332 }
335333 }
336334 #[ inline]
337- unsafe fn inline_mut ( & mut self ) -> & mut A {
335+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
338336 match * self {
339- SmallVecData :: Inline ( ref mut a) => a,
337+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
340338 _ => debug_unreachable ! ( ) ,
341339 }
342340 }
343341 #[ 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)
346344 }
347345 #[ inline]
348- unsafe fn into_inline ( self ) -> A {
346+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
349347 match self {
350- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
348+ SmallVecData :: Inline ( a) => a ,
351349 _ => debug_unreachable ! ( ) ,
352350 }
353351 }
@@ -412,11 +410,15 @@ impl<A: Array> SmallVec<A> {
412410 /// Construct an empty vector
413411 #[ inline]
414412 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 ( ) ) ,
420422 }
421423 }
422424
@@ -456,10 +458,10 @@ impl<A: Array> SmallVec<A> {
456458 pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
457459 if vec. capacity ( ) <= A :: size ( ) {
458460 unsafe {
459- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
461+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
460462 let len = vec. len ( ) ;
461463 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) ;
463465
464466 SmallVec {
465467 capacity : len,
@@ -492,7 +494,7 @@ impl<A: Array> SmallVec<A> {
492494 pub fn from_buf ( buf : A ) -> SmallVec < A > {
493495 SmallVec {
494496 capacity : A :: size ( ) ,
495- data : SmallVecData :: from_inline ( buf) ,
497+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
496498 }
497499 }
498500
@@ -511,7 +513,7 @@ impl<A: Array> SmallVec<A> {
511513 #[ inline]
512514 pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
513515 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) }
515517 }
516518
517519 /// Constructs a new `SmallVec` on the stack from an `A` without
@@ -520,16 +522,17 @@ impl<A: Array> SmallVec<A> {
520522 ///
521523 /// ```rust
522524 /// use smallvec::SmallVec;
525+ /// use std::mem::MaybeUninit;
523526 ///
524527 /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
525528 /// 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)
527530 /// };
528531 ///
529532 /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
530533 /// ```
531534 #[ 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 > {
533536 SmallVec {
534537 capacity : len,
535538 data : SmallVecData :: from_inline ( buf) ,
@@ -579,7 +582,7 @@ impl<A: Array> SmallVec<A> {
579582 let ( ptr, len) = self . data . heap ( ) ;
580583 ( ptr, len, self . capacity )
581584 } else {
582- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
585+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
583586 }
584587 }
585588 }
@@ -592,11 +595,7 @@ impl<A: Array> SmallVec<A> {
592595 let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
593596 ( ptr, len_ptr, self . capacity )
594597 } 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 ( ) )
600599 }
601600 }
602601 }
@@ -663,8 +662,8 @@ impl<A: Array> SmallVec<A> {
663662 if unspilled {
664663 return ;
665664 }
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) ;
668667 self . capacity = len;
669668 } else if new_cap != cap {
670669 let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -730,8 +729,8 @@ impl<A: Array> SmallVec<A> {
730729 if self . inline_size ( ) >= len {
731730 unsafe {
732731 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) ;
735734 deallocate ( ptr, self . capacity ) ;
736735 self . capacity = len;
737736 }
@@ -900,7 +899,7 @@ impl<A: Array> SmallVec<A> {
900899 unsafe {
901900 let data = ptr:: read ( & self . data ) ;
902901 mem:: forget ( self ) ;
903- Ok ( data. into_inline ( ) )
902+ Ok ( data. into_inline ( ) . assume_init ( ) )
904903 }
905904 }
906905 }
@@ -1062,8 +1061,12 @@ where
10621061 SmallVec {
10631062 capacity : len,
10641063 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+ ) ;
10671070 data
10681071 } ) ,
10691072 }
@@ -1603,10 +1606,6 @@ pub unsafe trait Array {
16031606 type Item ;
16041607 /// Returns the number of items the array can hold.
16051608 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 ;
16101609}
16111610
16121611/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1650,8 +1649,6 @@ macro_rules! impl_array(
16501649 unsafe impl <T > Array for [ T ; $size] {
16511650 type Item = T ;
16521651 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( ) }
16551652 }
16561653 ) +
16571654 }
@@ -1985,7 +1982,7 @@ mod tests {
19851982 ) ;
19861983 }
19871984
1988- #[ cfg( feature = "std" ) ]
1985+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
19891986 #[ test]
19901987 // https://github.com/servo/rust-smallvec/issues/96
19911988 fn test_insert_many_panic ( ) {
0 commit comments