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