@@ -56,7 +56,7 @@ use std::fmt;
56
56
use std:: hash:: { Hash , Hasher } ;
57
57
use std:: iter:: { IntoIterator , FromIterator , repeat} ;
58
58
use std:: mem;
59
- use std:: mem:: ManuallyDrop ;
59
+ use std:: mem:: MaybeUninit ;
60
60
use std:: ops;
61
61
use std:: ptr;
62
62
use std:: slice;
@@ -275,26 +275,26 @@ impl<'a, T: 'a> Drop for Drain<'a,T> {
275
275
276
276
#[ cfg( feature = "union" ) ]
277
277
union SmallVecData < A : Array > {
278
- inline : ManuallyDrop < A > ,
278
+ inline : MaybeUninit < A > ,
279
279
heap : ( * mut A :: Item , usize ) ,
280
280
}
281
281
282
282
#[ cfg( feature = "union" ) ]
283
283
impl < A : Array > SmallVecData < A > {
284
284
#[ 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
287
287
}
288
288
#[ 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
291
291
}
292
292
#[ 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 }
295
295
}
296
296
#[ inline]
297
- unsafe fn into_inline ( self ) -> A { ManuallyDrop :: into_inner ( self . inline ) }
297
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > { self . inline }
298
298
#[ inline]
299
299
unsafe fn heap ( & self ) -> ( * mut A :: Item , usize ) {
300
300
self . heap
@@ -311,34 +311,34 @@ impl<A: Array> SmallVecData<A> {
311
311
312
312
#[ cfg( not( feature = "union" ) ) ]
313
313
enum SmallVecData < A : Array > {
314
- Inline ( ManuallyDrop < A > ) ,
314
+ Inline ( MaybeUninit < A > ) ,
315
315
Heap ( ( * mut A :: Item , usize ) ) ,
316
316
}
317
317
318
318
#[ cfg( not( feature = "union" ) ) ]
319
319
impl < A : Array > SmallVecData < A > {
320
320
#[ inline]
321
- unsafe fn inline ( & self ) -> & A {
321
+ unsafe fn inline ( & self ) -> * const A :: Item {
322
322
match * self {
323
- SmallVecData :: Inline ( ref a) => a,
323
+ SmallVecData :: Inline ( ref a) => a. as_ptr ( ) as * const A :: Item ,
324
324
_ => debug_unreachable ! ( ) ,
325
325
}
326
326
}
327
327
#[ inline]
328
- unsafe fn inline_mut ( & mut self ) -> & mut A {
328
+ unsafe fn inline_mut ( & mut self ) -> * mut A :: Item {
329
329
match * self {
330
- SmallVecData :: Inline ( ref mut a) => a,
330
+ SmallVecData :: Inline ( ref mut a) => a. as_mut_ptr ( ) as * mut A :: Item ,
331
331
_ => debug_unreachable ! ( ) ,
332
332
}
333
333
}
334
334
#[ 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)
337
337
}
338
338
#[ inline]
339
- unsafe fn into_inline ( self ) -> A {
339
+ unsafe fn into_inline ( self ) -> MaybeUninit < A > {
340
340
match self {
341
- SmallVecData :: Inline ( a) => ManuallyDrop :: into_inner ( a ) ,
341
+ SmallVecData :: Inline ( a) => a ,
342
342
_ => debug_unreachable ! ( ) ,
343
343
}
344
344
}
@@ -403,11 +403,13 @@ impl<A: Array> SmallVec<A> {
403
403
/// Construct an empty vector
404
404
#[ inline]
405
405
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 ( ) ) ,
411
413
}
412
414
}
413
415
@@ -447,10 +449,10 @@ impl<A: Array> SmallVec<A> {
447
449
pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448
450
if vec. capacity ( ) <= A :: size ( ) {
449
451
unsafe {
450
- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
452
+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451
453
let len = vec. len ( ) ;
452
454
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) ;
454
456
455
457
SmallVec {
456
458
capacity : len,
@@ -483,7 +485,7 @@ impl<A: Array> SmallVec<A> {
483
485
pub fn from_buf ( buf : A ) -> SmallVec < A > {
484
486
SmallVec {
485
487
capacity : A :: size ( ) ,
486
- data : SmallVecData :: from_inline ( buf) ,
488
+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487
489
}
488
490
}
489
491
@@ -502,7 +504,7 @@ impl<A: Array> SmallVec<A> {
502
504
#[ inline]
503
505
pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
504
506
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) }
506
508
}
507
509
508
510
/// Constructs a new `SmallVec` on the stack from an `A` without
@@ -511,16 +513,17 @@ impl<A: Array> SmallVec<A> {
511
513
///
512
514
/// ```rust
513
515
/// use smallvec::SmallVec;
516
+ /// use std::mem::MaybeUninit;
514
517
///
515
518
/// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
516
519
/// 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)
518
521
/// };
519
522
///
520
523
/// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
521
524
/// ```
522
525
#[ 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 > {
524
527
SmallVec {
525
528
capacity : len,
526
529
data : SmallVecData :: from_inline ( buf) ,
@@ -571,7 +574,7 @@ impl<A: Array> SmallVec<A> {
571
574
let ( ptr, len) = self . data . heap ( ) ;
572
575
( ptr, len, self . capacity )
573
576
} else {
574
- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
577
+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575
578
}
576
579
}
577
580
}
@@ -584,7 +587,7 @@ impl<A: Array> SmallVec<A> {
584
587
let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585
588
( ptr, len_ptr, self . capacity )
586
589
} else {
587
- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
590
+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588
591
}
589
592
}
590
593
}
@@ -651,8 +654,8 @@ impl<A: Array> SmallVec<A> {
651
654
if unspilled {
652
655
return ;
653
656
}
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) ;
656
659
self . capacity = len;
657
660
} else if new_cap != cap {
658
661
let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +720,8 @@ impl<A: Array> SmallVec<A> {
717
720
if self . inline_size ( ) >= len {
718
721
unsafe {
719
722
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) ;
722
725
deallocate ( ptr, self . capacity ) ;
723
726
self . capacity = len;
724
727
}
@@ -883,7 +886,7 @@ impl<A: Array> SmallVec<A> {
883
886
unsafe {
884
887
let data = ptr:: read ( & self . data ) ;
885
888
mem:: forget ( self ) ;
886
- Ok ( data. into_inline ( ) )
889
+ Ok ( data. into_inline ( ) . assume_init ( ) )
887
890
}
888
891
}
889
892
}
@@ -1041,8 +1044,8 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
1041
1044
SmallVec {
1042
1045
capacity : len,
1043
1046
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) ;
1046
1049
data
1047
1050
} )
1048
1051
}
@@ -1543,10 +1546,6 @@ pub unsafe trait Array {
1543
1546
type Item ;
1544
1547
/// Returns the number of items the array can hold.
1545
1548
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 ;
1550
1549
}
1551
1550
1552
1551
/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1587,8 +1586,6 @@ macro_rules! impl_array(
1587
1586
unsafe impl <T > Array for [ T ; $size] {
1588
1587
type Item = T ;
1589
1588
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( ) }
1592
1589
}
1593
1590
) +
1594
1591
}
@@ -1889,7 +1886,7 @@ mod tests {
1889
1886
assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
1890
1887
}
1891
1888
1892
- #[ cfg( feature = "std" ) ]
1889
+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
1893
1890
#[ test]
1894
1891
// https://github.com/servo/rust-smallvec/issues/96
1895
1892
fn test_insert_many_panic ( ) {
0 commit comments