@@ -93,6 +93,8 @@ impl<T> RawVec<T, Global> {
93
93
/// zero-sized. Note that if `T` is zero-sized this means you will
94
94
/// *not* get a `RawVec` with the requested capacity.
95
95
///
96
+ /// Non-fallible version of `try_with_capacity`
97
+ ///
96
98
/// # Panics
97
99
///
98
100
/// Panics if the requested capacity exceeds `isize::MAX` bytes.
@@ -104,7 +106,7 @@ impl<T> RawVec<T, Global> {
104
106
#[ must_use]
105
107
#[ inline]
106
108
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 ) )
108
110
}
109
111
110
112
/// Like `with_capacity`, but guarantees the buffer is zeroed.
@@ -142,15 +144,15 @@ impl<T, A: Allocator> RawVec<T, A> {
142
144
#[ cfg( not( no_global_oom_handling) ) ]
143
145
#[ inline]
144
146
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) )
146
148
}
147
149
148
150
/// Like `with_capacity_zeroed`, but parameterized over the choice
149
151
/// of allocator for the returned `RawVec`.
150
152
#[ cfg( not( no_global_oom_handling) ) ]
151
153
#[ inline]
152
154
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) )
154
156
}
155
157
156
158
/// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
@@ -179,39 +181,44 @@ impl<T, A: Allocator> RawVec<T, A> {
179
181
}
180
182
}
181
183
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 > {
184
189
// Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
190
+
185
191
if T :: IS_ZST || capacity == 0 {
186
- Self :: new_in ( alloc)
192
+ Ok ( Self :: new_in ( alloc) )
187
193
} else {
188
194
// We avoid `unwrap_or_else` here because it bloats the amount of
189
195
// LLVM IR generated.
190
196
let layout = match Layout :: array :: < T > ( capacity) {
191
197
Ok ( layout) => layout,
192
- Err ( _) => capacity_overflow ( ) ,
198
+ Err ( _) => return Err ( CapacityOverflow . into ( ) ) ,
193
199
} ;
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 ) ;
197
203
}
204
+
198
205
let result = match init {
199
206
AllocInit :: Uninitialized => alloc. allocate ( layout) ,
200
207
AllocInit :: Zeroed => alloc. allocate_zeroed ( layout) ,
201
208
} ;
202
209
let ptr = match result {
203
210
Ok ( ptr) => ptr,
204
- Err ( _) => handle_alloc_error ( layout) ,
211
+ Err ( _) => return Err ( AllocError { layout, non_exhaustive : ( ) } . into ( ) ) ,
205
212
} ;
206
213
207
214
// Allocators currently return a `NonNull<[u8]>` whose length
208
215
// matches the size requested. If that ever changes, the capacity
209
216
// here should change to `ptr.len() / mem::size_of::<T>()`.
210
- Self {
217
+ Ok ( Self {
211
218
ptr : unsafe { Unique :: new_unchecked ( ptr. cast ( ) . as_ptr ( ) ) } ,
212
219
cap : unsafe { Cap ( capacity) } ,
213
220
alloc,
214
- }
221
+ } )
215
222
}
216
223
}
217
224
@@ -536,11 +543,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
536
543
// Central function for reserve error handling.
537
544
#[ cfg( not( no_global_oom_handling) ) ]
538
545
#[ inline]
539
- fn handle_reserve ( result : Result < ( ) , TryReserveError > ) {
546
+ fn handle_reserve < T > ( result : Result < T , TryReserveError > ) -> T {
540
547
match result. map_err ( |e| e. kind ( ) ) {
548
+ Ok ( res) => res,
541
549
Err ( CapacityOverflow ) => capacity_overflow ( ) ,
542
550
Err ( AllocError { layout, .. } ) => handle_alloc_error ( layout) ,
543
- Ok ( ( ) ) => { /* yay */ }
544
551
}
545
552
}
546
553
0 commit comments