@@ -93,6 +93,8 @@ impl<T> RawVec<T, Global> {
9393 /// zero-sized. Note that if `T` is zero-sized this means you will
9494 /// *not* get a `RawVec` with the requested capacity.
9595 ///
96+ /// Non-fallible version of `try_with_capacity`
97+ ///
9698 /// # Panics
9799 ///
98100 /// Panics if the requested capacity exceeds `isize::MAX` bytes.
@@ -104,7 +106,7 @@ impl<T> RawVec<T, Global> {
104106 #[ must_use]
105107 #[ inline]
106108 pub fn with_capacity ( capacity : usize ) -> Self {
107- Self :: with_capacity_in ( capacity, Global )
109+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Uninitialized , Global ) )
108110 }
109111
110112 /// Like `with_capacity`, but guarantees the buffer is zeroed.
@@ -142,15 +144,15 @@ impl<T, A: Allocator> RawVec<T, A> {
142144 #[ cfg( not( no_global_oom_handling) ) ]
143145 #[ inline]
144146 pub fn with_capacity_in ( capacity : usize , alloc : A ) -> Self {
145- Self :: allocate_in ( capacity, AllocInit :: Uninitialized , alloc)
147+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Uninitialized , alloc) )
146148 }
147149
148150 /// Like `with_capacity_zeroed`, but parameterized over the choice
149151 /// of allocator for the returned `RawVec`.
150152 #[ cfg( not( no_global_oom_handling) ) ]
151153 #[ inline]
152154 pub fn with_capacity_zeroed_in ( capacity : usize , alloc : A ) -> Self {
153- Self :: allocate_in ( capacity, AllocInit :: Zeroed , alloc)
155+ handle_reserve ( Self :: try_allocate_in ( capacity, AllocInit :: Zeroed , alloc) )
154156 }
155157
156158 /// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
@@ -179,39 +181,44 @@ impl<T, A: Allocator> RawVec<T, A> {
179181 }
180182 }
181183
182- #[ cfg( not( no_global_oom_handling) ) ]
183- fn allocate_in ( capacity : usize , init : AllocInit , alloc : A ) -> Self {
184+ fn try_allocate_in (
185+ capacity : usize ,
186+ init : AllocInit ,
187+ alloc : A ,
188+ ) -> Result < Self , TryReserveError > {
184189 // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
190+
185191 if T :: IS_ZST || capacity == 0 {
186- Self :: new_in ( alloc)
192+ Ok ( Self :: new_in ( alloc) )
187193 } else {
188194 // We avoid `unwrap_or_else` here because it bloats the amount of
189195 // LLVM IR generated.
190196 let layout = match Layout :: array :: < T > ( capacity) {
191197 Ok ( layout) => layout,
192- Err ( _) => capacity_overflow ( ) ,
198+ Err ( _) => return Err ( CapacityOverflow . into ( ) ) ,
193199 } ;
194- match alloc_guard ( layout . size ( ) ) {
195- Ok ( _ ) => { }
196- Err ( _ ) => capacity_overflow ( ) ,
200+
201+ if let Err ( err ) = alloc_guard ( layout . size ( ) ) {
202+ return Err ( err ) ;
197203 }
204+
198205 let result = match init {
199206 AllocInit :: Uninitialized => alloc. allocate ( layout) ,
200207 AllocInit :: Zeroed => alloc. allocate_zeroed ( layout) ,
201208 } ;
202209 let ptr = match result {
203210 Ok ( ptr) => ptr,
204- Err ( _) => handle_alloc_error ( layout) ,
211+ Err ( _) => return Err ( AllocError { layout, non_exhaustive : ( ) } . into ( ) ) ,
205212 } ;
206213
207214 // Allocators currently return a `NonNull<[u8]>` whose length
208215 // matches the size requested. If that ever changes, the capacity
209216 // here should change to `ptr.len() / mem::size_of::<T>()`.
210- Self {
217+ Ok ( Self {
211218 ptr : unsafe { Unique :: new_unchecked ( ptr. cast ( ) . as_ptr ( ) ) } ,
212219 cap : unsafe { Cap ( capacity) } ,
213220 alloc,
214- }
221+ } )
215222 }
216223 }
217224
@@ -536,11 +543,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
536543// Central function for reserve error handling.
537544#[ cfg( not( no_global_oom_handling) ) ]
538545#[ inline]
539- fn handle_reserve ( result : Result < ( ) , TryReserveError > ) {
546+ fn handle_reserve < T > ( result : Result < T , TryReserveError > ) -> T {
540547 match result. map_err ( |e| e. kind ( ) ) {
548+ Ok ( res) => res,
541549 Err ( CapacityOverflow ) => capacity_overflow ( ) ,
542550 Err ( AllocError { layout, .. } ) => handle_alloc_error ( layout) ,
543- Ok ( ( ) ) => { /* yay */ }
544551 }
545552}
546553
0 commit comments