@@ -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,35 +180,40 @@ 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 { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap(capacity) }, alloc }
216
+ Ok( Self { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap(capacity) }, alloc })
211
217
}
212
218
}
213
219
@@ -537,11 +543,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
537
543
// Central function for reserve error handling.
538
544
#[cfg(not(no_global_oom_handling))]
539
545
#[inline]
540
- fn handle_reserve(result: Result<() , TryReserveError>) {
546
+ fn handle_reserve<T> (result: Result<T , TryReserveError>) -> T {
541
547
match result.map_err(|e| e.kind()) {
548
+ Ok(res) => res,
542
549
Err(CapacityOverflow) => capacity_overflow(),
543
550
Err(AllocError { layout, .. }) => handle_alloc_error(layout),
544
- Ok(()) => { /* yay */ }
545
551
}
546
552
}
547
553
0 commit comments