@@ -56,7 +56,7 @@ use std::fmt;
5656use std:: hash:: { Hash , Hasher } ;
5757use std:: iter:: { IntoIterator , FromIterator , repeat} ;
5858use std:: mem;
59- use std:: mem:: ManuallyDrop ;
59+ use std:: mem:: MaybeUninit ;
6060use std:: ops;
6161use std:: ptr;
6262use std:: slice;
@@ -275,26 +275,26 @@ impl<'a, T: 'a> Drop for Drain<'a,T> {
275275
276276#[ cfg( feature = "union" ) ]
277277union SmallVecData < A : Array > {
278- inline : ManuallyDrop < A > ,
278+ inline : MaybeUninit < A > ,
279279 heap : ( * mut A :: Item , usize ) ,
280280}
281281
282282#[ cfg( feature = "union" ) ]
283283impl < A : Array > SmallVecData < A > {
284284 #[ inline]
285- unsafe fn inline ( & self ) -> & A {
286- & self . inline
285+ unsafe fn inline ( & self ) -> * const A :: Item {
286+ self . inline . as_ptr ( ) as * const A :: Item
287287 }
288288 #[ inline]
289- unsafe fn inline_mut ( & mut self ) -> & mut A {
290- & mut self . inline
289+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
290+ self . inline . as_mut_ptr ( ) as * mut A :: Item
291291 }
292292 #[ inline]
293- fn from_inline ( inline : A ) -> SmallVecData < A > {
294- SmallVecData { inline : ManuallyDrop :: new ( inline ) }
293+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
294+ SmallVecData { inline }
295295 }
296296 #[ inline]
297- unsafe fn into_inline ( self ) -> A { ManuallyDrop :: into_inner ( self . inline ) }
297+ unsafe fn into_inline ( self ) -> MaybeUninit < A > { self . inline }
298298 #[ inline]
299299 unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
300300 self . heap
@@ -311,34 +311,34 @@ impl<A: Array> SmallVecData<A> {
311311
312312#[ cfg( not( feature = "union" ) ) ]
313313enum SmallVecData < A : Array > {
314- Inline ( ManuallyDrop < A > ) ,
314+ Inline ( MaybeUninit < A > ) ,
315315 Heap ( ( * mut A :: Item , usize ) ) ,
316316}
317317
318318#[ cfg( not( feature = "union" ) ) ]
319319impl < A : Array > SmallVecData < A > {
320320 #[ inline]
321- unsafe fn inline ( & self ) -> & A {
321+ unsafe fn inline ( & self ) -> * const A :: Item {
322322 match * self {
323- SmallVecData :: Inline ( ref a) => a,
323+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
324324 _ => debug_unreachable ! ( ) ,
325325 }
326326 }
327327 #[ inline]
328- unsafe fn inline_mut ( & mut self ) -> & mut A {
328+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
329329 match * self {
330- SmallVecData :: Inline ( ref mut a) => a,
330+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
331331 _ => debug_unreachable ! ( ) ,
332332 }
333333 }
334334 #[ inline]
335- fn from_inline ( inline : A ) -> SmallVecData < A > {
336- SmallVecData :: Inline ( ManuallyDrop :: new ( inline) )
335+ fn from_inline ( inline : MaybeUninit < A > ) -> SmallVecData < A > {
336+ SmallVecData :: Inline ( inline)
337337 }
338338 #[ inline]
339- unsafe fn into_inline ( self ) -> A {
339+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
340340 match self {
341- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
341+ SmallVecData :: Inline ( a) => a ,
342342 _ => debug_unreachable ! ( ) ,
343343 }
344344 }
@@ -403,11 +403,13 @@ impl<A: Array> SmallVec<A> {
403403 /// Construct an empty vector
404404 #[ inline]
405405 pub fn new ( ) -> SmallVec < A > {
406- unsafe {
407- SmallVec {
408- capacity : 0 ,
409- data : SmallVecData :: from_inline ( mem:: uninitialized ( ) ) ,
410- }
406+ debug_assert ! (
407+ ( mem:: size_of:: <A >( ) == A :: size( ) * mem:: size_of:: <A :: Item >( ) ) &&
408+ ( mem:: align_of:: <A >( ) >= mem:: align_of:: <A :: Item >( ) )
409+ ) ;
410+ SmallVec {
411+ capacity : 0 ,
412+ data : SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ,
411413 }
412414 }
413415
@@ -447,10 +449,10 @@ impl<A: Array> SmallVec<A> {
447449 pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448450 if vec. capacity ( ) <= A :: size ( ) {
449451 unsafe {
450- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
452+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451453 let len = vec. len ( ) ;
452454 vec. set_len ( 0 ) ;
453- ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) . ptr_mut ( ) , len) ;
455+ ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) , len) ;
454456
455457 SmallVec {
456458 capacity : len,
@@ -483,7 +485,7 @@ impl<A: Array> SmallVec<A> {
483485 pub fn from_buf ( buf : A ) -> SmallVec < A > {
484486 SmallVec {
485487 capacity : A :: size ( ) ,
486- data : SmallVecData :: from_inline ( buf) ,
488+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487489 }
488490 }
489491
@@ -502,7 +504,7 @@ impl<A: Array> SmallVec<A> {
502504 #[ inline]
503505 pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
504506 assert ! ( len <= A :: size( ) ) ;
505- unsafe { SmallVec :: from_buf_and_len_unchecked ( buf, len) }
507+ unsafe { SmallVec :: from_buf_and_len_unchecked ( MaybeUninit :: new ( buf) , len) }
506508 }
507509
508510 /// Constructs a new `SmallVec` on the stack from an `A` without
@@ -511,16 +513,17 @@ impl<A: Array> SmallVec<A> {
511513 ///
512514 /// ```rust
513515 /// use smallvec::SmallVec;
516+ /// use std::mem::MaybeUninit;
514517 ///
515518 /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
516519 /// let small_vec: SmallVec<_> = unsafe {
517- /// SmallVec::from_buf_and_len_unchecked(buf, 5)
520+ /// SmallVec::from_buf_and_len_unchecked(MaybeUninit::new( buf) , 5)
518521 /// };
519522 ///
520523 /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
521524 /// ```
522525 #[ inline]
523- pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
526+ pub unsafe fn from_buf_and_len_unchecked ( buf : MaybeUninit < A > , len : usize ) -> SmallVec < A > {
524527 SmallVec {
525528 capacity : len,
526529 data : SmallVecData :: from_inline ( buf) ,
@@ -571,7 +574,7 @@ impl<A: Array> SmallVec<A> {
571574 let ( ptr, len) = self . data . heap ( ) ;
572575 ( ptr, len, self . capacity )
573576 } else {
574- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
577+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575578 }
576579 }
577580 }
@@ -584,7 +587,7 @@ impl<A: Array> SmallVec<A> {
584587 let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585588 ( ptr, len_ptr, self . capacity )
586589 } else {
587- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
590+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588591 }
589592 }
590593 }
@@ -651,8 +654,8 @@ impl<A: Array> SmallVec<A> {
651654 if unspilled {
652655 return ;
653656 }
654- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
655- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
657+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
658+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
656659 self . capacity = len;
657660 } else if new_cap != cap {
658661 let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +720,8 @@ impl<A: Array> SmallVec<A> {
717720 if self . inline_size ( ) >= len {
718721 unsafe {
719722 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) ;
723+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
724+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
722725 deallocate ( ptr, self . capacity ) ;
723726 self . capacity = len;
724727 }
@@ -883,7 +886,7 @@ impl<A: Array> SmallVec<A> {
883886 unsafe {
884887 let data = ptr:: read ( & self . data ) ;
885888 mem:: forget ( self ) ;
886- Ok ( data. into_inline ( ) )
889+ Ok ( data. into_inline ( ) . assume_init ( ) )
887890 }
888891 }
889892 }
@@ -1041,8 +1044,8 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
10411044 SmallVec {
10421045 capacity : len,
10431046 data : SmallVecData :: from_inline ( unsafe {
1044- let mut data: A = mem :: uninitialized ( ) ;
1045- ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. ptr_mut ( ) , len) ;
1047+ let mut data: MaybeUninit < A > = MaybeUninit :: uninit ( ) ;
1048+ ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. as_mut_ptr ( ) as * mut A :: Item , len) ;
10461049 data
10471050 } )
10481051 }
@@ -1543,10 +1546,6 @@ pub unsafe trait Array {
15431546 type Item ;
15441547 /// Returns the number of items the array can hold.
15451548 fn size ( ) -> usize ;
1546- /// Returns a pointer to the first element of the array.
1547- fn ptr ( & self ) -> * const Self :: Item ;
1548- /// Returns a mutable pointer to the first element of the array.
1549- fn ptr_mut ( & mut self ) -> * mut Self :: Item ;
15501549}
15511550
15521551/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1587,8 +1586,6 @@ macro_rules! impl_array(
15871586 unsafe impl <T > Array for [ T ; $size] {
15881587 type Item = T ;
15891588 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( ) }
15921589 }
15931590 ) +
15941591 }
@@ -1889,7 +1886,7 @@ mod tests {
18891886 assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
18901887 }
18911888
1892- #[ cfg( feature = "std" ) ]
1889+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
18931890 #[ test]
18941891 // https://github.com/servo/rust-smallvec/issues/96
18951892 fn test_insert_many_panic ( ) {
0 commit comments