@@ -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,15 @@ 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
+ // 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 ( ) ) ,
411
415
}
412
416
}
413
417
@@ -447,10 +451,10 @@ impl<A: Array> SmallVec<A> {
447
451
pub fn from_vec ( mut vec : Vec < A :: Item > ) -> SmallVec < A > {
448
452
if vec. capacity ( ) <= A :: size ( ) {
449
453
unsafe {
450
- let mut data = SmallVecData :: < A > :: from_inline ( mem :: uninitialized ( ) ) ;
454
+ let mut data = SmallVecData :: < A > :: from_inline ( MaybeUninit :: uninit ( ) ) ;
451
455
let len = vec. len ( ) ;
452
456
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) ;
454
458
455
459
SmallVec {
456
460
capacity : len,
@@ -483,7 +487,7 @@ impl<A: Array> SmallVec<A> {
483
487
pub fn from_buf ( buf : A ) -> SmallVec < A > {
484
488
SmallVec {
485
489
capacity : A :: size ( ) ,
486
- data : SmallVecData :: from_inline ( buf) ,
490
+ data : SmallVecData :: from_inline ( MaybeUninit :: new ( buf) ) ,
487
491
}
488
492
}
489
493
@@ -502,7 +506,7 @@ impl<A: Array> SmallVec<A> {
502
506
#[ inline]
503
507
pub fn from_buf_and_len ( buf : A , len : usize ) -> SmallVec < A > {
504
508
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) }
506
510
}
507
511
508
512
/// Constructs a new `SmallVec` on the stack from an `A` without
@@ -511,16 +515,17 @@ impl<A: Array> SmallVec<A> {
511
515
///
512
516
/// ```rust
513
517
/// use smallvec::SmallVec;
518
+ /// use std::mem::MaybeUninit;
514
519
///
515
520
/// let buf = [1, 2, 3, 4, 5, 0, 0, 0];
516
521
/// 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)
518
523
/// };
519
524
///
520
525
/// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
521
526
/// ```
522
527
#[ 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 > {
524
529
SmallVec {
525
530
capacity : len,
526
531
data : SmallVecData :: from_inline ( buf) ,
@@ -571,7 +576,7 @@ impl<A: Array> SmallVec<A> {
571
576
let ( ptr, len) = self . data . heap ( ) ;
572
577
( ptr, len, self . capacity )
573
578
} else {
574
- ( self . data . inline ( ) . ptr ( ) , self . capacity , A :: size ( ) )
579
+ ( self . data . inline ( ) , self . capacity , A :: size ( ) )
575
580
}
576
581
}
577
582
}
@@ -584,7 +589,7 @@ impl<A: Array> SmallVec<A> {
584
589
let & mut ( ptr, ref mut len_ptr) = self . data . heap_mut ( ) ;
585
590
( ptr, len_ptr, self . capacity )
586
591
} else {
587
- ( self . data . inline_mut ( ) . ptr_mut ( ) , & mut self . capacity , A :: size ( ) )
592
+ ( self . data . inline_mut ( ) , & mut self . capacity , A :: size ( ) )
588
593
}
589
594
}
590
595
}
@@ -651,8 +656,8 @@ impl<A: Array> SmallVec<A> {
651
656
if unspilled {
652
657
return ;
653
658
}
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) ;
656
661
self . capacity = len;
657
662
} else if new_cap != cap {
658
663
let mut vec = Vec :: with_capacity ( new_cap) ;
@@ -717,8 +722,8 @@ impl<A: Array> SmallVec<A> {
717
722
if self . inline_size ( ) >= len {
718
723
unsafe {
719
724
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) ;
722
727
deallocate ( ptr, self . capacity ) ;
723
728
self . capacity = len;
724
729
}
@@ -883,7 +888,7 @@ impl<A: Array> SmallVec<A> {
883
888
unsafe {
884
889
let data = ptr:: read ( & self . data ) ;
885
890
mem:: forget ( self ) ;
886
- Ok ( data. into_inline ( ) )
891
+ Ok ( data. into_inline ( ) . assume_init ( ) )
887
892
}
888
893
}
889
894
}
@@ -1041,8 +1046,8 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
1041
1046
SmallVec {
1042
1047
capacity : len,
1043
1048
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) ;
1046
1051
data
1047
1052
} )
1048
1053
}
@@ -1543,10 +1548,6 @@ pub unsafe trait Array {
1543
1548
type Item ;
1544
1549
/// Returns the number of items the array can hold.
1545
1550
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
1551
}
1551
1552
1552
1553
/// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1587,8 +1588,6 @@ macro_rules! impl_array(
1587
1588
unsafe impl <T > Array for [ T ; $size] {
1588
1589
type Item = T ;
1589
1590
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
1591
}
1593
1592
) +
1594
1593
}
@@ -1889,7 +1888,7 @@ mod tests {
1889
1888
assert_eq ! ( & v. iter( ) . map( |v| * v) . collect:: <Vec <_>>( ) , & [ 0 , 5 , 6 , 1 , 2 , 3 ] ) ;
1890
1889
}
1891
1890
1892
- #[ cfg( feature = "std" ) ]
1891
+ #[ cfg( all ( feature = "std" , not ( miri ) ) ) ] // Miri currently does not support unwinding
1893
1892
#[ test]
1894
1893
// https://github.com/servo/rust-smallvec/issues/96
1895
1894
fn test_insert_many_panic ( ) {
0 commit comments