Skip to content
This repository was archived by the owner on Nov 27, 2020. It is now read-only.

Commit 005f1b5

Browse files
committed
Require Error = ! for "infallible allocation
1 parent 8aec886 commit 005f1b5

File tree

8 files changed

+179
-177
lines changed

8 files changed

+179
-177
lines changed

src/boxed.rs

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ use crate::{
8383
clone::CloneIn,
8484
collections::CollectionAllocErr,
8585
raw_vec::RawVec,
86-
UncheckedResultExt,
8786
};
8887
use core::{
8988
any::Any,
@@ -184,8 +183,12 @@ impl<T, A: AllocRef> Box<T, A> {
184183
/// ```
185184
#[allow(clippy::inline_always)]
186185
#[inline(always)]
187-
pub fn new_in(x: T, a: A) -> Self {
188-
unsafe { Self::try_new_in(x, a).unwrap_unchecked() }
186+
pub fn new_in(x: T, a: A) -> Self
187+
where
188+
A: AllocRef<Error = !>,
189+
{
190+
let Ok(b) = Self::try_new_in(x, a);
191+
b
189192
}
190193

191194
/// Tries to allocate memory with the given allocator and then places `x` into it.
@@ -234,8 +237,12 @@ impl<T, A: AllocRef> Box<T, A> {
234237
/// ```
235238
#[allow(clippy::inline_always)]
236239
#[inline(always)]
237-
pub fn new_uninit_in(a: A) -> Box<mem::MaybeUninit<T>, A> {
238-
unsafe { Self::try_new_uninit_in(a).unwrap_unchecked() }
240+
pub fn new_uninit_in(a: A) -> Box<mem::MaybeUninit<T>, A>
241+
where
242+
A: AllocRef<Error = !>,
243+
{
244+
let Ok(b) = Self::try_new_uninit_in(a);
245+
b
239246
}
240247

241248
/// Tries to construct a new box with uninitialized contents in a specified allocator.
@@ -271,8 +278,12 @@ impl<T, A: AllocRef> Box<T, A> {
271278
/// `Unpin`, then `x` will be pinned in memory and unable to be moved.
272279
#[allow(clippy::inline_always)]
273280
#[inline(always)]
274-
pub fn pin_in(x: T, a: A) -> Pin<Self> {
275-
unsafe { Self::try_pin_in(x, a).unwrap_unchecked() }
281+
pub fn pin_in(x: T, a: A) -> Pin<Self>
282+
where
283+
A: AllocRef<Error = !>,
284+
{
285+
let Ok(b) = Self::try_pin_in(x, a);
286+
b
276287
}
277288

278289
/// Constructs a new `Pin<Box<T, A>>` with the specified allocator. If `T` does not implement
@@ -314,7 +325,7 @@ impl<T> Box<[T]> {
314325
}
315326

316327
#[allow(clippy::use_self)]
317-
impl<T, A: AllocRef> Box<[T], A> {
328+
impl<T, A: AllocRef<Error = !>> Box<[T], A> {
318329
/// Construct a new boxed slice with uninitialized contents with the spoecified allocator.
319330
///
320331
/// # Example
@@ -338,9 +349,17 @@ impl<T, A: AllocRef> Box<[T], A> {
338349
#[allow(clippy::inline_always)]
339350
#[inline(always)]
340351
pub fn new_uninit_slice_in(len: usize, a: A) -> Box<[mem::MaybeUninit<T>], A> {
341-
unsafe { Self::try_new_uninit_slice_in(len, a).unwrap_unchecked() }
352+
match Self::try_new_uninit_slice_in(len, a) {
353+
Ok(b) => b,
354+
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
355+
#[allow(unreachable_patterns)] // TODO rustc bug?
356+
Err(CollectionAllocErr::AllocError { inner: e, .. }) => e,
357+
}
342358
}
359+
}
343360

361+
#[allow(clippy::use_self)]
362+
impl<T, A: AllocRef> Box<[T], A> {
344363
/// Tries to construct a new boxed slice with uninitialized contents with the spoecified
345364
/// allocator.
346365
///
@@ -747,7 +766,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: DeallocRef> Drop for Box<T, A> {
747766
impl<T, A> Default for Box<T, A>
748767
where
749768
T: Default,
750-
A: Default + AllocRef,
769+
A: Default + AllocRef<Error = !>,
751770
{
752771
#[must_use]
753772
fn default() -> Self {
@@ -756,7 +775,7 @@ where
756775
}
757776

758777
#[allow(clippy::use_self)]
759-
impl<T, A> Default for Box<[T], A>
778+
impl<T, A: AllocRef<Error = !>> Default for Box<[T], A>
760779
where
761780
A: Default + AllocRef,
762781
{
@@ -773,7 +792,7 @@ unsafe fn from_boxed_utf8_unchecked<A: DeallocRef>(v: Box<[u8], A>) -> Box<str,
773792
}
774793

775794
#[allow(clippy::use_self)]
776-
impl<A> Default for Box<str, A>
795+
impl<A: AllocRef<Error = !>> Default for Box<str, A>
777796
where
778797
A: Default + AllocRef,
779798
{
@@ -783,7 +802,7 @@ where
783802
}
784803
}
785804

786-
impl<T: Clone, A> Clone for Box<T, A>
805+
impl<T: Clone, A: AllocRef<Error = !>> Clone for Box<T, A>
787806
where
788807
A: AllocRef,
789808
A::BuildAlloc: Clone,
@@ -846,7 +865,10 @@ where
846865
impl<T: Clone, A: AllocRef, B: AllocRef> CloneIn<B> for Box<T, A> {
847866
type Cloned = Box<T, B>;
848867

849-
fn clone_in(&self, a: B) -> Self::Cloned {
868+
fn clone_in(&self, a: B) -> Self::Cloned
869+
where
870+
B: AllocRef<Error = !>,
871+
{
850872
Box::new_in(self.as_ref().clone(), a)
851873
}
852874

@@ -947,7 +969,7 @@ impl<T: ?Sized + Hasher, A: DeallocRef> Hasher for Box<T, A> {
947969
}
948970
}
949971

950-
impl<T, A> From<T> for Box<T, A>
972+
impl<T, A: AllocRef<Error = !>> From<T> for Box<T, A>
951973
where
952974
A: Default + AllocRef,
953975
{
@@ -983,7 +1005,7 @@ impl<T: ?Sized, A: DeallocRef> From<Box<T, A>> for Pin<Box<T, A>> {
9831005
#[allow(clippy::use_self)]
9841006
impl<T: Copy, A> From<&[T]> for Box<[T], A>
9851007
where
986-
A: Default + AllocRef,
1008+
A: Default + AllocRef<Error = !>,
9871009
{
9881010
/// Converts a `&[T]` into a `Box<[T], B>`
9891011
///
@@ -1012,7 +1034,7 @@ where
10121034
#[allow(clippy::use_self)]
10131035
impl<A> From<&str> for Box<str, A>
10141036
where
1015-
A: Default + AllocRef,
1037+
A: Default + AllocRef<Error = !>,
10161038
{
10171039
/// Converts a `&str` into a `Box<str>`
10181040
///
@@ -1272,7 +1294,7 @@ impl_dispatch_from_dyn!(std::alloc::System);
12721294
#[allow(clippy::items_after_statements)]
12731295
impl<T: Clone, A: Clone> Clone for Box<[T], A>
12741296
where
1275-
A: AllocRef,
1297+
A: AllocRef<Error = !>,
12761298
A::BuildAlloc: Clone,
12771299
{
12781300
fn clone(&self) -> Self {
@@ -1383,3 +1405,10 @@ impl<F: ?Sized + Future + Unpin, A: DeallocRef> Future for Box<F, A> {
13831405
F::poll(Pin::new(&mut *self), cx)
13841406
}
13851407
}
1408+
1409+
// One central function responsible for reporting capacity overflows. This'll
1410+
// ensure that the code generation related to these panics is minimal as there's
1411+
// only one location which panics rather than a bunch throughout the module.
1412+
fn capacity_overflow() -> ! {
1413+
panic!("capacity overflow");
1414+
}

src/clone.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::alloc::AllocRef;
33
pub trait CloneIn<A: AllocRef>: Sized {
44
type Cloned;
55

6-
fn clone_in(&self, a: A) -> Self::Cloned;
6+
fn clone_in(&self, a: A) -> Self::Cloned
7+
where
8+
A: AllocRef<Error = !>;
79

810
fn try_clone_in(&self, a: A) -> Result<Self::Cloned, A::Error>;
911
}

src/iter.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ pub trait TryExtend<A> {
2525
}
2626

2727
pub trait FromIteratorIn<T, A: AllocRef> {
28-
fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, allocator: A) -> Self;
28+
fn from_iter_in<I: IntoIterator<Item = T>>(iter: I, allocator: A) -> Self
29+
where
30+
A: AllocRef<Error = !>;
2931

3032
fn try_from_iter_in<I: IntoIterator<Item = T>>(
3133
iter: I,
@@ -38,7 +40,10 @@ pub trait FromIteratorIn<T, A: AllocRef> {
3840
pub trait IteratorExt: Iterator + Sized {
3941
#[inline]
4042
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
41-
fn collect_in<T: FromIteratorIn<Self::Item, A>, A: AllocRef>(self, allocator: A) -> T {
43+
fn collect_in<T: FromIteratorIn<Self::Item, A>, A: AllocRef>(self, allocator: A) -> T
44+
where
45+
A: AllocRef<Error = !>,
46+
{
4247
FromIteratorIn::from_iter_in(self, allocator)
4348
}
4449

src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
specialization,
6868
trusted_len,
6969
unsized_locals,
70-
fn_traits
70+
fn_traits,
71+
exhaustive_patterns
7172
)]
7273
#![cfg_attr(not(feature = "std"), no_std)]
7374
#![doc(test(attr(
@@ -115,8 +116,6 @@ pub mod vec;
115116

116117
extern crate alloc as liballoc;
117118

118-
mod unchecked_unwrap;
119-
use self::unchecked_unwrap::*;
120119
pub use liballoc::{borrow, fmt, rc, slice, sync};
121120

122121
#[macro_export]

src/raw_vec.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::{
22
alloc::{
3-
handle_alloc_error,
43
AllocRef,
54
BuildAllocRef,
65
CapacityOverflow,
@@ -34,7 +33,6 @@ use core::{
3433
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
3534
/// * Guards against 32-bit systems allocating more than `isize::MAX` bytes
3635
/// * Guards against overflowing your length
37-
/// * Aborts on OOM or calls `handle_alloc_error` as applicable
3836
/// * Avoids freeing `Unique::empty()`
3937
/// * Contains a `ptr::Unique` and thus endows the user with all related benefits
4038
///
@@ -164,12 +162,13 @@ impl<T, A: DeallocRef> RawVec<T, A> {
164162
/// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes.
165163
pub fn with_capacity_in(capacity: usize, a: A) -> Self
166164
where
167-
A: AllocRef,
165+
A: AllocRef<Error = !>,
168166
{
169167
match Self::try_with_capacity_in(capacity, a) {
170168
Ok(vec) => vec,
171169
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
172-
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
170+
#[allow(unreachable_patterns)] // TODO rustc bug?
171+
Err(CollectionAllocErr::AllocError { inner: e, .. }) => e,
173172
}
174173
}
175174

@@ -199,12 +198,13 @@ impl<T, A: DeallocRef> RawVec<T, A> {
199198
/// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes.
200199
pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self
201200
where
202-
A: AllocRef,
201+
A: AllocRef<Error = !>,
203202
{
204203
match Self::try_with_capacity_zeroed_in(capacity, a) {
205204
Ok(vec) => vec,
206205
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
207-
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
206+
#[allow(unreachable_patterns)] // TODO rustc bug?
207+
Err(CollectionAllocErr::AllocError { inner: e, .. }) => e,
208208
}
209209
}
210210

@@ -419,12 +419,13 @@ impl<T, A: DeallocRef> RawVec<T, A> {
419419
/// ```
420420
pub fn double(&mut self)
421421
where
422-
A: ReallocRef,
422+
A: ReallocRef<Error = !>,
423423
{
424424
match self.try_double() {
425425
Ok(_) => (),
426426
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
427-
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
427+
#[allow(unreachable_patterns)] // TODO rustc bug?
428+
Err(CollectionAllocErr::AllocError { inner: e, .. }) => e,
428429
}
429430
}
430431

@@ -589,12 +590,13 @@ impl<T, A: DeallocRef> RawVec<T, A> {
589590
/// ```
590591
pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize)
591592
where
592-
A: ReallocRef,
593+
A: ReallocRef<Error = !>,
593594
{
594595
match self.try_reserve(used_capacity, needed_extra_capacity) {
595596
Ok(vec) => vec,
596597
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
597-
Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()),
598+
#[allow(unreachable_patterns)] // TODO rustc bug?
599+
Err(CollectionAllocErr::AllocError { inner: e, .. }) => e,
598600
}
599601
}
600602

0 commit comments

Comments
 (0)