@@ -109,12 +109,13 @@ impl core::fmt::Display for CollectionAllocErr {
109109/// Either a stack array with `length <= N` or a heap array 
110110/// whose pointer and capacity are stored here. 
111111/// 
112- /// We store a `*const T` instead of a `*mut T` so that the type is covariant 
112+ /// We store a `NonNull<T>` instead of a `*mut T`, so that 
113+ /// niche-optimization can be performed and the type is covariant 
113114/// with respect to `T`. 
114115#[ repr( C ) ]  
115116pub  union  RawSmallVec < T ,  const  N :  usize >  { 
116117    inline :  ManuallyDrop < MaybeUninit < [ T ;  N ] > > , 
117-     heap :  ( * const   T ,  usize ) ,   // this pointer is never null 
118+     heap :  ( NonNull < T > ,  usize ) , 
118119} 
119120
120121#[ inline]  
@@ -143,7 +144,7 @@ impl<T, const N: usize> RawSmallVec<T, N> {
143144        } 
144145    } 
145146    #[ inline]  
146-     const  fn  new_heap ( ptr :  * mut   T ,  capacity :  usize )  -> Self  { 
147+     const  fn  new_heap ( ptr :  NonNull < T > ,  capacity :  usize )  -> Self  { 
147148        Self  { 
148149            heap :  ( ptr,  capacity) , 
149150        } 
@@ -168,15 +169,15 @@ impl<T, const N: usize> RawSmallVec<T, N> {
168169     /// The vector must be on the heap 
169170     #[ inline]  
170171    const  unsafe  fn  as_ptr_heap ( & self )  -> * const  T  { 
171-         self . heap . 0 
172+         self . heap . 0 . as_ptr ( ) 
172173    } 
173174
174175    /// # Safety 
175176     /// 
176177     /// The vector must be on the heap 
177178     #[ inline]  
178179    unsafe  fn  as_mut_ptr_heap ( & mut  self )  -> * mut  T  { 
179-         self . heap . 0   as   * mut   T 
180+         self . heap . 0 . as_ptr ( ) 
180181    } 
181182
182183    /// # Safety 
@@ -216,7 +217,7 @@ impl<T, const N: usize> RawSmallVec<T, N> {
216217                Err ( CollectionAllocErr :: AllocErr  {  layout :  new_layout } ) 
217218            }  else  { 
218219                copy_nonoverlapping ( ptr,  new_ptr,  len) ; 
219-                 * self  = Self :: new_heap ( new_ptr,  new_capacity) ; 
220+                 * self  = Self :: new_heap ( NonNull :: new_unchecked ( new_ptr) ,  new_capacity) ; 
220221                Ok ( ( ) ) 
221222            } 
222223        }  else  { 
@@ -236,7 +237,7 @@ impl<T, const N: usize> RawSmallVec<T, N> {
236237            if  new_ptr. is_null ( )  { 
237238                Err ( CollectionAllocErr :: AllocErr  {  layout :  new_layout } ) 
238239            }  else  { 
239-                 * self  = Self :: new_heap ( new_ptr,  new_capacity) ; 
240+                 * self  = Self :: new_heap ( NonNull :: new_unchecked ( new_ptr) ,  new_capacity) ; 
240241                Ok ( ( ) ) 
241242            } 
242243        } 
@@ -733,7 +734,9 @@ impl<T, const N: usize> SmallVec<T, N> {
733734            let  mut  vec = ManuallyDrop :: new ( vec) ; 
734735            let  len = vec. len ( ) ; 
735736            let  cap = vec. capacity ( ) ; 
736-             let  ptr = vec. as_mut_ptr ( ) ; 
737+             // SAFETY: vec.capacity is not `0` (checked above), so the pointer 
738+             // can not dangle and thus specifically cannot be null. 
739+             let  ptr = unsafe  {  NonNull :: new_unchecked ( vec. as_mut_ptr ( ) )  } ; 
737740
738741            Self  { 
739742                len :  TaggedLen :: new ( len,  true ,  Self :: is_zst ( ) ) , 
@@ -1002,11 +1005,10 @@ impl<T, const N: usize> SmallVec<T, N> {
10021005        debug_assert ! ( self . spilled( ) ) ; 
10031006        let  len = self . len ( ) ; 
10041007        let  ( ptr,  cap)  = self . raw . heap ; 
1005-         let  ptr = ptr as  * mut  T ; 
10061008        if  len == cap { 
10071009            self . reserve ( 1 ) ; 
10081010        } 
1009-         ptr. add ( len) . write ( value) ; 
1011+         ptr. as_ptr ( ) . add ( len) . write ( value) ; 
10101012        self . set_len ( len + 1 ) 
10111013    } 
10121014
@@ -1076,9 +1078,9 @@ impl<T, const N: usize> SmallVec<T, N> {
10761078
10771079                    // SAFETY: len <= new_capacity <= Self::inline_size() 
10781080                    // so the copy is within bounds of the inline member 
1079-                     copy_nonoverlapping ( ptr,  self . raw . as_mut_ptr_inline ( ) ,  len) ; 
1081+                     copy_nonoverlapping ( ptr. as_ptr ( ) ,  self . raw . as_mut_ptr_inline ( ) ,  len) ; 
10801082                    drop ( DropDealloc  { 
1081-                         ptr :  NonNull :: new_unchecked ( ptr as  * mut  u8 ) , 
1083+                         ptr :  NonNull :: new_unchecked ( ptr. as_ptr ( )  as  * mut  u8 ) , 
10821084                        size_bytes :  old_cap *  size_of :: < T > ( ) , 
10831085                        align :  align_of :: < T > ( ) , 
10841086                    } ) ; 
@@ -1154,10 +1156,10 @@ impl<T, const N: usize> SmallVec<T, N> {
11541156            unsafe  { 
11551157                let  ( ptr,  capacity)  = self . raw . heap ; 
11561158                self . raw  = RawSmallVec :: new_inline ( MaybeUninit :: uninit ( ) ) ; 
1157-                 copy_nonoverlapping ( ptr,  self . raw . as_mut_ptr_inline ( ) ,  len) ; 
1159+                 copy_nonoverlapping ( ptr. as_ptr ( ) ,  self . raw . as_mut_ptr_inline ( ) ,  len) ; 
11581160                self . set_inline ( ) ; 
11591161                alloc:: alloc:: dealloc ( 
1160-                     ptr  as   * mut   T  as  * mut  u8 , 
1162+                     ptr. as_ptr ( )  as  * mut  u8 , 
11611163                    Layout :: from_size_align_unchecked ( capacity *  size_of :: < T > ( ) ,  align_of :: < T > ( ) ) , 
11621164                ) ; 
11631165            } 
@@ -1333,10 +1335,16 @@ impl<T, const N: usize> SmallVec<T, N> {
13331335            vec
13341336        }  else  { 
13351337            let  this = ManuallyDrop :: new ( self ) ; 
1336-             // SAFETY: ptr was created with the global allocator 
1338+             // SAFETY: 
1339+             // - `ptr` was created with the global allocator 
1340+             // - `ptr` was created with the appropriate alignment for `T` 
1341+             // - the allocation pointed to by ptr is exactly cap * sizeof(T) 
1342+             // - `len` is less than or equal to `cap` 
1343+             // - the first `len` entries are proper `T`-values 
1344+             // - the allocation is not larger than `isize::MAX` 
13371345            unsafe  { 
13381346                let  ( ptr,  cap)  = this. raw . heap ; 
1339-                 Vec :: from_raw_parts ( ptr  as   * mut   T ,  len,  cap) 
1347+                 Vec :: from_raw_parts ( ptr. as_ptr ( ) ,  len,  cap) 
13401348            } 
13411349        } 
13421350    } 
@@ -1510,6 +1518,14 @@ impl<T, const N: usize> SmallVec<T, N> {
15101518     #[ inline]  
15111519    pub  unsafe  fn  from_raw_parts ( ptr :  * mut  T ,  length :  usize ,  capacity :  usize )  -> SmallVec < T ,  N >  { 
15121520        assert ! ( !Self :: is_zst( ) ) ; 
1521+ 
1522+         // SAFETY: We require caller to provide same ptr as we alloc 
1523+         // and we never alloc null pointer. 
1524+         let  ptr = unsafe  { 
1525+             debug_assert ! ( !ptr. is_null( ) ,  "Called `from_raw_parts` with null pointer." ) ; 
1526+             NonNull :: new_unchecked ( ptr) 
1527+         } ; 
1528+ 
15131529        SmallVec  { 
15141530            len :  TaggedLen :: new ( length,  true ,  Self :: is_zst ( ) ) , 
15151531            raw :  RawSmallVec :: new_heap ( ptr,  capacity) , 
@@ -1548,7 +1564,7 @@ impl<T, const N: usize> SmallVec<T, N> {
15481564                } 
15491565                let  len = self . len ( ) ; 
15501566                let  ( ptr,  capacity)  = self . raw . heap ; 
1551-                 let  ptr = ptr  as   * mut   T ; 
1567+                 let  ptr = ptr. as_ptr ( ) ; 
15521568                // SAFETY: ptr is valid for `capacity - len` writes 
15531569                let  count = extend_batch ( ptr,  capacity - len,  len,  & mut  iter) ; 
15541570                self . set_len ( len + count) ; 
0 commit comments