@@ -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,15 @@ 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+ // Try to detect invalid custom implementations of `Array`. Hopefuly,
407+ // this check should be optimized away entirely for valid ones.
408+ assert ! (
409+ ( mem:: size_of:: <A >( ) == A :: size( ) * mem:: size_of:: <A :: Item >( ) ) &&
410+ ( mem:: align_of:: <A >( ) >= mem:: align_of:: <A :: Item >( ) )
411+ ) ;
412+ SmallVec {
413+ capacity : 0 ,
414+ data : SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ,
411415 }
412416 }
413417
@@ -447,10 +451,10 @@ impl<A: Array> SmallVec<A> {
447451 pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448452 if vec. capacity ( ) <= A :: size ( ) {
449453 unsafe {
450- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
454+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451455 let len = vec. len ( ) ;
452456 vec. set_len ( 0 ) ;
453- ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) . ptr_mut ( ) , len) ;
457+ ptr:: copy_nonoverlapping ( vec. as_ptr ( ) , data. inline_mut ( ) , len) ;
454458
455459 SmallVec {
456460 capacity : len,
@@ -483,7 +487,7 @@ impl<A: Array> SmallVec<A> {
483487 pub fn from_buf ( buf : A ) -> SmallVec < A > {
484488 SmallVec {
485489 capacity : A :: size ( ) ,
486- data : SmallVecData :: from_inline ( buf) ,
490+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487491 }
488492 }
489493
@@ -502,7 +506,7 @@ impl<A: Array> SmallVec<A> {
502506 #[ inline]
503507 pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
504508 assert ! ( len <= A :: size( ) ) ;
505- unsafe { SmallVec :: from_buf_and_len_unchecked ( buf, len) }
509+ unsafe { SmallVec :: from_buf_and_len_unchecked ( MaybeUninit :: new ( buf) , len) }
506510 }
507511
508512 /// Constructs a new `SmallVec` on the stack from an `A` without
@@ -511,16 +515,17 @@ impl<A: Array> SmallVec<A> {
511515 ///
512516 /// ```rust
513517 /// use smallvec::SmallVec;
518+ /// use std::mem::MaybeUninit;
514519 ///
515520 /// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
516521 /// let small_vec: SmallVec<_> = unsafe {
517- /// SmallVec::from_buf_and_len_unchecked(buf, 5)
522+ /// SmallVec::from_buf_and_len_unchecked(MaybeUninit::new( buf) , 5)
518523 /// };
519524 ///
520525 /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
521526 /// ```
522527 #[ inline]
523- pub unsafe fn from_buf_and_len_unchecked ( buf : A , len : usize ) -> SmallVec < A > {
528+ pub unsafe fn from_buf_and_len_unchecked ( buf : MaybeUninit < A > , len : usize ) -> SmallVec < A > {
524529 SmallVec {
525530 capacity : len,
526531 data : SmallVecData :: from_inline ( buf) ,
@@ -571,7 +576,7 @@ impl<A: Array> SmallVec<A> {
571576 let ( ptr, len) = self . data . heap ( ) ;
572577 ( ptr, len, self . capacity )
573578 } else {
574- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
579+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575580 }
576581 }
577582 }
@@ -584,7 +589,7 @@ impl<A: Array> SmallVec<A> {
584589 let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585590 ( ptr, len_ptr, self . capacity )
586591 } else {
587- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
592+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588593 }
589594 }
590595 }
@@ -651,8 +656,8 @@ impl<A: Array> SmallVec<A> {
651656 if unspilled {
652657 return ;
653658 }
654- self . data = SmallVecData :: from_inline ( mem :: uninitialized ( ) ) ;
655- ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) . ptr_mut ( ) , len) ;
659+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
660+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
656661 self . capacity = len;
657662 } else if new_cap != cap {
658663 let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +722,8 @@ impl<A: Array> SmallVec<A> {
717722 if self . inline_size ( ) >= len {
718723 unsafe {
719724 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) ;
725+ self . data = SmallVecData :: from_inline ( MaybeUninit :: uninit ( ) ) ;
726+ ptr:: copy_nonoverlapping ( ptr, self . data . inline_mut ( ) , len) ;
722727 deallocate ( ptr, self . capacity ) ;
723728 self . capacity = len;
724729 }
@@ -883,7 +888,7 @@ impl<A: Array> SmallVec<A> {
883888 unsafe {
884889 let data = ptr:: read ( & self . data ) ;
885890 mem:: forget ( self ) ;
886- Ok ( data. into_inline ( ) )
891+ Ok ( data. into_inline ( ) . assume_init ( ) )
887892 }
888893 }
889894 }
@@ -1041,8 +1046,8 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
10411046 SmallVec {
10421047 capacity : len,
10431048 data : SmallVecData :: from_inline ( unsafe {
1044- let mut data: A = mem :: uninitialized ( ) ;
1045- ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. ptr_mut ( ) , len) ;
1049+ let mut data: MaybeUninit < A > = MaybeUninit :: uninit ( ) ;
1050+ ptr:: copy_nonoverlapping ( slice. as_ptr ( ) , data. as_mut_ptr ( ) as * mut A :: Item , len) ;
10461051 data
10471052 } )
10481053 }
@@ -1543,10 +1548,6 @@ pub unsafe trait Array {
15431548 type Item ;
15441549 /// Returns the number of items the array can hold.
15451550 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 ;
15501551}
15511552
15521553/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1587,8 +1588,6 @@ macro_rules! impl_array(
15871588 unsafe impl <T > Array for [ T ; $size] {
15881589 type Item = T ;
15891590 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( ) }
15921591 }
15931592 ) +
15941593 }
@@ -1889,7 +1888,7 @@ mod tests {
18891888 assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
18901889 }
18911890
1892- #[ cfg( feature = "std" ) ]
1891+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
18931892 #[ test]
18941893 // https://github.com/servo/rust-smallvec/issues/96
18951894 fn test_insert_many_panic ( ) {
0 commit comments