@@ -17,7 +17,6 @@ use crate::collections::TryReserveErrorKind::*;
1717#[ cfg( test) ]
1818mod tests;
1919
20- #[ cfg( not( no_global_oom_handling) ) ]
2120enum AllocInit {
2221 /// The contents of the new memory are uninitialized.
2322 Uninitialized ,
@@ -93,6 +92,8 @@ impl<T> RawVec<T, Global> {
9392 /// zero-sized. Note that if `T` is zero-sized this means you will
9493 /// *not* get a `RawVec` with the requested capacity.
9594 ///
95+ /// Non-fallible version of `try_with_capacity`
96+ ///
9697 /// # Panics
9798 ///
9899 /// Panics if the requested capacity exceeds `isize::MAX` bytes.
@@ -104,7 +105,7 @@ impl<T> RawVec<T, Global> {
104105 #[ must_use]
105106 #[ inline]
106107 pub fn with_capacity ( capacity : usize ) -> Self {
107- Self :: with_capacity_in ( capacity, Global )
108+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Uninitialized , Global ) )
108109 }
109110
110111 /// Like `with_capacity`, but guarantees the buffer is zeroed.
@@ -142,15 +143,15 @@ impl<T, A: Allocator> RawVec<T, A> {
142143 #[ cfg( not( no_global_oom_handling) ) ]
143144 #[ inline]
144145 pub fn with_capacity_in ( capacity : usize , alloc : A ) -> Self {
145- Self :: allocate_in ( capacity, AllocInit :: Uninitialized , alloc)
146+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Uninitialized , alloc) )
146147 }
147148
148149 /// Like `with_capacity_zeroed`, but parameterized over the choice
149150 /// of allocator for the returned `RawVec`.
150151 #[ cfg( not( no_global_oom_handling) ) ]
151152 #[ inline]
152153 pub fn with_capacity_zeroed_in ( capacity : usize , alloc : A ) -> Self {
153- Self :: allocate_in ( capacity, AllocInit :: Zeroed , alloc)
154+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Zeroed , alloc) )
154155 }
155156
156157 /// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
@@ -179,39 +180,44 @@ impl<T, A: Allocator> RawVec<T, A> {
179180 }
180181 }
181182
182- #[ cfg( not( no_global_oom_handling) ) ]
183- fn allocate_in ( capacity : usize , init : AllocInit , alloc : A ) -> Self {
183+ fn try_allocate_in (
184+ capacity : usize ,
185+ init : AllocInit ,
186+ alloc : A ,
187+ ) -> Result < Self , TryReserveError > {
184188 // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
189+
185190 if T :: IS_ZST || capacity == 0 {
186- Self :: new_in ( alloc)
191+ Ok ( Self :: new_in ( alloc) )
187192 } else {
188193 // We avoid `unwrap_or_else` here because it bloats the amount of
189194 // LLVM IR generated.
190195 let layout = match Layout :: array :: < T > ( capacity) {
191196 Ok ( layout) => layout,
192- Err ( _) => capacity_overflow ( ) ,
197+ Err ( _) => return Err ( CapacityOverflow . into ( ) ) ,
193198 } ;
194- match alloc_guard ( layout . size ( ) ) {
195- Ok ( _ ) => { }
196- Err ( _ ) => capacity_overflow ( ) ,
199+
200+ if let Err ( err ) = alloc_guard ( layout . size ( ) ) {
201+ return Err ( err ) ;
197202 }
203+
198204 let result = match init {
199205 AllocInit :: Uninitialized => alloc. allocate ( layout) ,
200206 AllocInit :: Zeroed => alloc. allocate_zeroed ( layout) ,
201207 } ;
202208 let ptr = match result {
203209 Ok ( ptr) => ptr,
204- Err ( _) => handle_alloc_error ( layout) ,
210+ Err ( _) => return Err ( AllocError { layout, non_exhaustive : ( ) } . into ( ) ) ,
205211 } ;
206212
207213 // Allocators currently return a `NonNull<[u8]>` whose length
208214 // matches the size requested. If that ever changes, the capacity
209215 // here should change to `ptr.len() / mem::size_of::<T>()`.
210- Self {
216+ Ok ( Self {
211217 ptr : unsafe { Unique :: new_unchecked ( ptr. cast ( ) . as_ptr ( ) ) } ,
212218 cap : unsafe { Cap ( capacity) } ,
213219 alloc,
214- }
220+ } )
215221 }
216222 }
217223
@@ -536,11 +542,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
536542// Central function for reserve error handling.
537543#[ cfg( not( no_global_oom_handling) ) ]
538544#[ inline]
539- fn handle_reserve ( result : Result < ( ) , TryReserveError > ) {
545+ fn handle_reserve < T > ( result : Result < T , TryReserveError > ) -> T {
540546 match result. map_err ( |e| e. kind ( ) ) {
547+ Ok ( res) => res,
541548 Err ( CapacityOverflow ) => capacity_overflow ( ) ,
542549 Err ( AllocError { layout, .. } ) => handle_alloc_error ( layout) ,
543- Ok ( ( ) ) => { /* yay */ }
544550 }
545551}
546552
0 commit comments