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

Commit 6eaa40f

Browse files
committed
Require Error = ! for "infallible allocation
1 parent 921ee59 commit 6eaa40f

File tree

9 files changed

+195
-185
lines changed

9 files changed

+195
-185
lines changed

src/alloc/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub use liballoc::alloc::{handle_alloc_error, Layout};
1414
use std::alloc::System;
1515

1616
mod panic_adaptor;
17+
pub use self::panic_adaptor::PanicAdapter;
1718

1819
/// Allocate memory with the global allocator.
1920
///

src/boxed.rs

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,10 @@
7979
//! [`NonZeroLayout::for_value(&*value)`]: crate::alloc::NonZeroLayout::for_value
8080
8181
use crate::{
82-
alloc::{AllocRef, BuildAllocRef, DeallocRef, Global, NonZeroLayout},
82+
alloc::{AllocRef, BuildAllocRef, DeallocRef, Global, NonZeroLayout, PanicAdapter},
8383
clone::CloneIn,
8484
collections::CollectionAllocErr,
8585
raw_vec::RawVec,
86-
UncheckedResultExt,
8786
};
8887
use core::{
8988
any::Any,
@@ -105,7 +104,7 @@ use core::{
105104
/// A pointer type for heap allocation.
106105
///
107106
/// See the [module-level documentation](index.html) for more.
108-
pub struct Box<T: ?Sized, A: DeallocRef = Global> {
107+
pub struct Box<T: ?Sized, A: DeallocRef = PanicAdapter<Global>> {
109108
ptr: Unique<T>,
110109
build_alloc: A::BuildAlloc,
111110
}
@@ -131,7 +130,7 @@ impl<T> Box<T> {
131130
#[inline(always)]
132131
#[must_use]
133132
pub fn new(x: T) -> Self {
134-
Self::new_in(x, Global)
133+
Self::new_in(x, PanicAdapter(Global))
135134
}
136135

137136
/// Constructs a new box with uninitialized contents.
@@ -156,7 +155,7 @@ impl<T> Box<T> {
156155
#[inline(always)]
157156
#[must_use]
158157
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
159-
Self::new_uninit_in(Global)
158+
Self::new_uninit_in(PanicAdapter(Global))
160159
}
161160

162161
/// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
@@ -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
@@ -309,12 +320,12 @@ impl<T> Box<[T]> {
309320
#[inline(always)]
310321
#[must_use]
311322
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
312-
Self::new_uninit_slice_in(len, Global)
323+
Self::new_uninit_slice_in(len, PanicAdapter(Global))
313324
}
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
///
@@ -503,7 +522,7 @@ impl<T: ?Sized> Box<T> {
503522
#[allow(clippy::inline_always)]
504523
#[inline(always)]
505524
pub unsafe fn from_raw(raw: *mut T) -> Self {
506-
Self::from_raw_in(raw, Global)
525+
Self::from_raw_in(raw, PanicAdapter(Global))
507526
}
508527
}
509528

@@ -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
@@ -68,7 +68,8 @@
6868
specialization,
6969
trusted_len,
7070
unsized_locals,
71-
fn_traits
71+
fn_traits,
72+
exhaustive_patterns
7273
)]
7374
#![cfg_attr(not(feature = "std"), no_std)]
7475
#![doc(test(attr(
@@ -116,8 +117,6 @@ pub mod vec;
116117

117118
extern crate alloc as liballoc;
118119

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

123122
#[macro_export]

0 commit comments

Comments
 (0)