4747//! Tracking issue: [rust-lang/rust#34761](https://github.com/rust-lang/rust/issues/34761)
4848
4949#![ no_std]
50+ #![ cfg_attr( docsrs, feature( doc_cfg) ) ]
51+ #![ cfg_attr( feature = "specialization" , allow( incomplete_features) ) ]
52+ #![ cfg_attr( feature = "specialization" , feature( specialization) ) ]
53+ #![ cfg_attr( feature = "may_dangle" , feature( dropck_eyepatch) ) ]
5054
5155#[ doc( hidden) ]
5256pub extern crate alloc;
@@ -73,8 +77,8 @@ use core::ptr::addr_of;
7377use core:: ptr:: addr_of_mut;
7478use core:: ptr:: copy_nonoverlapping;
7579
76- #[ cfg( feature = "serde" ) ]
7780use core:: marker:: PhantomData ;
81+
7882#[ cfg( feature = "serde" ) ]
7983use serde:: {
8084 de:: { Deserialize , Deserializer , SeqAccess , Visitor } ,
@@ -279,6 +283,7 @@ impl TaggedLen {
279283pub struct SmallVec < T , const N : usize > {
280284 len : TaggedLen ,
281285 raw : RawSmallVec < T , N > ,
286+ _marker : PhantomData < T > ,
282287}
283288
284289/// An iterator that removes the items from a `SmallVec` and yields them by value.
@@ -361,6 +366,7 @@ pub struct IntoIter<T, const N: usize> {
361366 raw : RawSmallVec < T , N > ,
362367 begin : usize ,
363368 end : TaggedLen ,
369+ _marker : PhantomData < T > ,
364370}
365371
366372impl < T , const N : usize > IntoIter < T , N > {
@@ -468,13 +474,16 @@ impl<T, const N: usize> SmallVec<T, N> {
468474 Self {
469475 len : TaggedLen :: new ( 0 , false , Self :: is_zst ( ) ) ,
470476 raw : RawSmallVec :: new ( ) ,
477+ _marker : PhantomData ,
471478 }
472479 }
473480
474481 #[ inline]
475482 pub fn with_capacity ( capacity : usize ) -> Self {
476483 let mut this = Self :: new ( ) ;
477- this. reserve_exact ( capacity) ;
484+ if capacity > Self :: inline_size ( ) {
485+ this. grow ( capacity) ;
486+ }
478487 this
479488 }
480489
@@ -494,6 +503,7 @@ impl<T, const N: usize> SmallVec<T, N> {
494503 Self {
495504 len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
496505 raw : RawSmallVec :: new ( ) ,
506+ _marker : PhantomData ,
497507 }
498508 } else {
499509 let mut vec = ManuallyDrop :: new ( vec) ;
@@ -504,6 +514,7 @@ impl<T, const N: usize> SmallVec<T, N> {
504514 Self {
505515 len : TaggedLen :: new ( len, true , Self :: is_zst ( ) ) ,
506516 raw : RawSmallVec :: new_heap ( ptr, cap) ,
517+ _marker : PhantomData ,
507518 }
508519 }
509520 }
@@ -513,6 +524,7 @@ impl<T, const N: usize> SmallVec<T, N> {
513524 Self {
514525 len : TaggedLen :: new ( N , false , Self :: is_zst ( ) ) ,
515526 raw : RawSmallVec :: new_inline ( MaybeUninit :: new ( buf) ) ,
527+ _marker : PhantomData ,
516528 }
517529 }
518530
@@ -522,6 +534,7 @@ impl<T, const N: usize> SmallVec<T, N> {
522534 let mut vec = Self {
523535 len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
524536 raw : RawSmallVec :: new_inline ( MaybeUninit :: new ( buf) ) ,
537+ _marker : PhantomData ,
525538 } ;
526539 // Deallocate the remaining elements so no memory is leaked.
527540 unsafe {
@@ -545,6 +558,7 @@ impl<T, const N: usize> SmallVec<T, N> {
545558 Self {
546559 len : TaggedLen :: new ( len, false , Self :: is_zst ( ) ) ,
547560 raw : RawSmallVec :: new_inline ( buf) ,
561+ _marker : PhantomData ,
548562 }
549563 }
550564
@@ -684,7 +698,7 @@ impl<T, const N: usize> SmallVec<T, N> {
684698 infallible ( self . try_grow ( new_capacity) ) ;
685699 }
686700
687- #[ inline ]
701+ #[ cold ]
688702 pub fn try_grow ( & mut self , new_capacity : usize ) -> Result < ( ) , CollectionAllocErr > {
689703 let len = self . len ( ) ;
690704 assert ! ( new_capacity >= len) ;
@@ -1043,6 +1057,7 @@ impl<T, const N: usize> SmallVec<T, N> {
10431057 SmallVec {
10441058 len : TaggedLen :: new ( length, true , Self :: is_zst ( ) ) ,
10451059 raw : RawSmallVec :: new_heap ( ptr, capacity) ,
1060+ _marker : PhantomData ,
10461061 }
10471062 }
10481063
@@ -1070,14 +1085,23 @@ impl<T: Copy, const N: usize> SmallVec<T, N> {
10701085 #[ inline]
10711086 pub fn from_slice ( slice : & [ T ] ) -> Self {
10721087 let len = slice. len ( ) ;
1073-
1074- let mut this = Self :: with_capacity ( len) ;
1075- let ptr = this. as_mut_ptr ( ) ;
1076- unsafe {
1077- copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1078- this. set_len ( len) ;
1088+ if len <= Self :: inline_size ( ) {
1089+ let mut this = Self :: new ( ) ;
1090+ unsafe {
1091+ let ptr = this. raw . as_mut_ptr_inline ( ) ;
1092+ copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1093+ this. set_len ( len) ;
1094+ }
1095+ this
1096+ } else {
1097+ let mut this = Vec :: with_capacity ( len) ;
1098+ unsafe {
1099+ let ptr = this. as_mut_ptr ( ) ;
1100+ copy_nonoverlapping ( slice. as_ptr ( ) , ptr, len) ;
1101+ this. set_len ( len) ;
1102+ }
1103+ Self :: from_vec ( this)
10791104 }
1080- this
10811105 }
10821106
10831107 #[ inline]
@@ -1250,6 +1274,29 @@ impl Drop for DropDealloc {
12501274 }
12511275}
12521276
1277+ #[ cfg( feature = "may_dangle" ) ]
1278+ unsafe impl < #[ may_dangle] T , const N : usize > Drop for SmallVec < T , N > {
1279+ fn drop ( & mut self ) {
1280+ let on_heap = self . spilled ( ) ;
1281+ let len = self . len ( ) ;
1282+ let ptr = self . as_mut_ptr ( ) ;
1283+ unsafe {
1284+ let _drop_dealloc = if on_heap {
1285+ let capacity = self . capacity ( ) ;
1286+ Some ( DropDealloc {
1287+ ptr : ptr as * mut u8 ,
1288+ size_bytes : capacity * size_of :: < T > ( ) ,
1289+ align : align_of :: < T > ( ) ,
1290+ } )
1291+ } else {
1292+ None
1293+ } ;
1294+ core:: ptr:: slice_from_raw_parts_mut ( ptr, len) . drop_in_place ( ) ;
1295+ }
1296+ }
1297+ }
1298+
1299+ #[ cfg( not( feature = "may_dangle" ) ) ]
12531300impl < T , const N : usize > Drop for SmallVec < T , N > {
12541301 fn drop ( & mut self ) {
12551302 let on_heap = self . spilled ( ) ;
@@ -1318,6 +1365,36 @@ impl<T, const N: usize> core::iter::FromIterator<T> for SmallVec<T, N> {
13181365 }
13191366}
13201367
1368+ #[ cfg( feature = "specialization" ) ]
1369+ trait SpecFrom {
1370+ type Element ;
1371+ fn spec_from ( slice : & [ Self :: Element ] ) -> Self ;
1372+ }
1373+
1374+ #[ cfg( feature = "specialization" ) ]
1375+ impl < T : Clone , const N : usize > SpecFrom for SmallVec < T , N > {
1376+ type Element = T ;
1377+
1378+ default fn spec_from ( slice : & [ Self :: Element ] ) -> Self {
1379+ slice. iter ( ) . cloned ( ) . collect ( )
1380+ }
1381+ }
1382+
1383+ #[ cfg( feature = "specialization" ) ]
1384+ impl < T : Copy , const N : usize > SpecFrom for SmallVec < T , N > {
1385+ fn spec_from ( slice : & [ Self :: Element ] ) -> Self {
1386+ Self :: from_slice ( slice)
1387+ }
1388+ }
1389+
1390+ #[ cfg( feature = "specialization" ) ]
1391+ impl < ' a , T : Clone , const N : usize > From < & ' a [ T ] > for SmallVec < T , N > {
1392+ fn from ( slice : & ' a [ T ] ) -> Self {
1393+ <Self as SpecFrom >:: spec_from ( slice)
1394+ }
1395+ }
1396+
1397+ #[ cfg( not( feature = "specialization" ) ) ]
13211398impl < ' a , T : Clone , const N : usize > From < & ' a [ T ] > for SmallVec < T , N > {
13221399 fn from ( slice : & ' a [ T ] ) -> Self {
13231400 slice. iter ( ) . cloned ( ) . collect ( )
@@ -1408,6 +1485,7 @@ impl<T, const N: usize> IntoIterator for SmallVec<T, N> {
14081485 raw : ( & this. raw as * const RawSmallVec < T , N > ) . read ( ) ,
14091486 begin : 0 ,
14101487 end : this. len ,
1488+ _marker : PhantomData ,
14111489 }
14121490 }
14131491 }
0 commit comments