Skip to content

Commit 53538de

Browse files
committed
Add associated error type to allocators
We will use this for fallibility polymorphism
1 parent 3cbdf18 commit 53538de

File tree

6 files changed

+118
-86
lines changed

6 files changed

+118
-86
lines changed

src/liballoc/alloc.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
167167
__rust_alloc_zeroed(layout.size(), layout.align())
168168
}
169169

170+
#[cfg(not(test))]
171+
#[unstable(feature = "allocator_api", issue = "32838")]
172+
impl AllocHelper for Global {
173+
type Err = AllocErr;
174+
}
175+
170176
#[cfg(not(test))]
171177
#[unstable(feature = "allocator_api", issue = "32838")]
172178
unsafe impl Alloc for Global {

src/liballoc/boxed.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ use core::ops::{
8888
use core::ptr::{self, NonNull, Unique};
8989
use core::task::{Context, Poll};
9090

91-
use crate::alloc::{Alloc, Global, Layout, handle_alloc_error};
91+
use crate::alloc::{Alloc, AllocErr, Global, Layout, handle_alloc_error};
9292
use crate::vec::Vec;
9393
use crate::raw_vec::RawVec;
9494
use crate::str::from_boxed_utf8_unchecked;
@@ -126,7 +126,7 @@ impl<T> Box<T> {
126126
}
127127
}
128128

129-
impl<T, A: Alloc> Box<T, A> {
129+
impl<T, A: Alloc<Err = AllocErr>> Box<T, A> {
130130
/// Allocates memory in the given allocator and then places `x` into it.
131131
///
132132
/// This doesn't actually allocate if `T` is zero-sized.
@@ -213,7 +213,7 @@ impl<T: ?Sized> Box<T> {
213213
}
214214
}
215215

216-
impl<T: ?Sized, A: Alloc> Box<T, A> {
216+
impl<T: ?Sized, A> Box<T, A> {
217217
/// Constructs a box from a raw pointer in the given allocator.
218218
///
219219
/// This is similar to the [`Box::from_raw`] function, but assumes
@@ -420,29 +420,29 @@ unsafe impl<#[may_dangle] T: ?Sized, A> Drop for Box<T, A> {
420420
}
421421

422422
#[stable(feature = "rust1", since = "1.0.0")]
423-
impl<T: Default, A: Alloc + Default> Default for Box<T, A> {
423+
impl<T: Default, A: Alloc<Err = AllocErr> + Default> Default for Box<T, A> {
424424
/// Creates a `Box<T, A>`, with the `Default` value for T.
425425
fn default() -> Box<T, A> {
426426
Box::new_in(Default::default(), A::default())
427427
}
428428
}
429429

430430
#[stable(feature = "rust1", since = "1.0.0")]
431-
impl<T, A: Alloc + Default> Default for Box<[T], A> {
431+
impl<T, A: Alloc<Err = AllocErr> + Default> Default for Box<[T], A> {
432432
fn default() -> Box<[T], A> {
433433
Box::<[T; 0], A>::new_in([], A::default())
434434
}
435435
}
436436

437437
#[stable(feature = "default_box_extra", since = "1.17.0")]
438-
impl<A: Alloc + Default> Default for Box<str, A> {
438+
impl<A: Alloc<Err = AllocErr> + Default> Default for Box<str, A> {
439439
fn default() -> Box<str, A> {
440440
unsafe { from_boxed_utf8_unchecked(Default::default()) }
441441
}
442442
}
443443

444444
#[stable(feature = "rust1", since = "1.0.0")]
445-
impl<T: Clone, A: Alloc + Clone> Clone for Box<T, A> {
445+
impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<T, A> {
446446
/// Returns a new box with a `clone()` of this box's contents.
447447
///
448448
/// # Examples
@@ -474,9 +474,8 @@ impl<T: Clone, A: Alloc + Clone> Clone for Box<T, A> {
474474
}
475475
}
476476

477-
478477
#[stable(feature = "box_slice_clone", since = "1.3.0")]
479-
impl<A: Alloc + Clone> Clone for Box<str, A> {
478+
impl<A: Alloc<Err = AllocErr> + Clone> Clone for Box<str, A> {
480479
fn clone(&self) -> Self {
481480
// this makes a copy of the data
482481
let buf = Box::<[u8], A>::from_slice_in(self.as_bytes(), self.1.clone());
@@ -584,7 +583,7 @@ impl<T: ?Sized + Hasher, A> Hasher for Box<T, A> {
584583
}
585584

586585
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
587-
impl<T, A: Alloc + Default> From<T> for Box<T, A> {
586+
impl<T, A: Alloc<Err = AllocErr> + Default> From<T> for Box<T, A> {
588587
/// Converts a generic type `T` into a `Box<T>`
589588
///
590589
/// The conversion allocates on the heap and moves `t`
@@ -612,7 +611,7 @@ impl<T: ?Sized, A> From<Box<T, A>> for Pin<Box<T, A>> {
612611
}
613612
}
614613

615-
impl<T: Copy, A: Alloc> Box<[T], A> {
614+
impl<T: Copy, A: Alloc<Err = AllocErr>> Box<[T], A> {
616615
fn from_slice_in(slice: &[T], a: A) -> Box<[T], A> {
617616
let len = slice.len();
618617
let buf = RawVec::with_capacity_in(len, a);
@@ -624,7 +623,7 @@ impl<T: Copy, A: Alloc> Box<[T], A> {
624623
}
625624

626625
#[stable(feature = "box_from_slice", since = "1.17.0")]
627-
impl<T: Copy, A: Alloc + Default> From<&[T]> for Box<[T], A> {
626+
impl<T: Copy, A: Alloc<Err = AllocErr> + Default> From<&[T]> for Box<[T], A> {
628627
/// Converts a `&[T]` into a `Box<[T]>`
629628
///
630629
/// This conversion allocates on the heap
@@ -644,7 +643,7 @@ impl<T: Copy, A: Alloc + Default> From<&[T]> for Box<[T], A> {
644643
}
645644

646645
#[stable(feature = "box_from_slice", since = "1.17.0")]
647-
impl<A: Alloc + Default> From<&str> for Box<str, A> {
646+
impl<A: Alloc<Err = AllocErr> + Default> From<&str> for Box<str, A> {
648647
/// Converts a `&str` into a `Box<str>`
649648
///
650649
/// This conversion allocates on the heap
@@ -662,7 +661,7 @@ impl<A: Alloc + Default> From<&str> for Box<str, A> {
662661
}
663662

664663
#[stable(feature = "boxed_str_conv", since = "1.19.0")]
665-
impl<A: Alloc> From<Box<str, A>> for Box<[u8], A> {
664+
impl<A> From<Box<str, A>> for Box<[u8], A> {
666665
/// Converts a `Box<str>>` into a `Box<[u8]>`
667666
///
668667
/// This conversion does not allocate on the heap and happens in place.
@@ -685,7 +684,7 @@ impl<A: Alloc> From<Box<str, A>> for Box<[u8], A> {
685684
}
686685
}
687686

688-
impl<A: Alloc> Box<dyn Any, A> {
687+
impl<A> Box<dyn Any, A> {
689688
#[inline]
690689
#[stable(feature = "rust1", since = "1.0.0")]
691690
/// Attempt to downcast the box to a concrete type.
@@ -716,7 +715,7 @@ impl<A: Alloc> Box<dyn Any, A> {
716715
}
717716
}
718717

719-
impl<A: Alloc> Box<dyn Any + Send, A> {
718+
impl<A: Alloc<Err=AllocErr>> Box<dyn Any + Send, A> {
720719
#[inline]
721720
#[stable(feature = "rust1", since = "1.0.0")]
722721
/// Attempt to downcast the box to a concrete type.
@@ -941,7 +940,7 @@ impl<A> FromIterator<A> for Box<[A]> {
941940
}
942941

943942
#[stable(feature = "box_slice_clone", since = "1.3.0")]
944-
impl<T: Clone, A: Alloc + Clone> Clone for Box<[T], A> {
943+
impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<[T], A> {
945944
fn clone(&self) -> Self {
946945
let mut new = BoxBuilder {
947946
data: RawVec::with_capacity_in(self.len(), self.1.clone()),
@@ -962,20 +961,20 @@ impl<T: Clone, A: Alloc + Clone> Clone for Box<[T], A> {
962961
return unsafe { new.into_box() };
963962

964963
// Helper type for responding to panics correctly.
965-
struct BoxBuilder<T, A: Alloc> {
964+
struct BoxBuilder<T, A: Alloc<Err = AllocErr>> {
966965
data: RawVec<T, A>,
967966
len: usize,
968967
}
969968

970-
impl<T, A: Alloc> BoxBuilder<T, A> {
969+
impl<T, A: Alloc<Err = AllocErr>> BoxBuilder<T, A> {
971970
unsafe fn into_box(self) -> Box<[T], A> {
972971
let raw = ptr::read(&self.data);
973972
mem::forget(self);
974973
raw.into_box()
975974
}
976975
}
977976

978-
impl<T, A: Alloc> Drop for BoxBuilder<T, A> {
977+
impl<T, A: Alloc<Err = AllocErr>> Drop for BoxBuilder<T, A> {
979978
fn drop(&mut self) {
980979
let mut data = self.data.ptr();
981980
let max = unsafe { data.add(self.len) };

src/liballoc/raw_vec.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use core::ops::Drop;
77
use core::ptr::{self, NonNull, Unique};
88
use core::slice;
99

10-
use crate::alloc::{Alloc, Layout, Global, handle_alloc_error};
11-
use crate::collections::CollectionAllocErr::{self, *};
10+
use crate::alloc::{Alloc, AllocErr, Layout, Global, handle_alloc_error};
11+
use crate::collections::CollectionAllocErr;
1212
use crate::boxed::Box;
1313

1414
/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
@@ -39,13 +39,13 @@ use crate::boxed::Box;
3939
/// field. This allows zero-sized types to not be special-cased by consumers of
4040
/// this type.
4141
#[allow(missing_debug_implementations)]
42-
pub struct RawVec<T, A: Alloc = Global> {
42+
pub struct RawVec<T, A: Alloc<Err = AllocErr> = Global> {
4343
ptr: Unique<T>,
4444
cap: usize,
4545
a: A,
4646
}
4747

48-
impl<T, A: Alloc> RawVec<T, A> {
48+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
4949
/// Like `new` but parameterized over the choice of allocator for
5050
/// the returned RawVec.
5151
pub const fn new_in(a: A) -> Self {
@@ -146,7 +146,7 @@ impl<T> RawVec<T, Global> {
146146
}
147147
}
148148

149-
impl<T, A: Alloc> RawVec<T, A> {
149+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
150150
/// Reconstitutes a RawVec from a pointer, capacity, and allocator.
151151
///
152152
/// # Undefined Behavior
@@ -189,7 +189,7 @@ impl<T> RawVec<T, Global> {
189189
}
190190
}
191191

192-
impl<T, A: Alloc> RawVec<T, A> {
192+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
193193
/// Gets a raw pointer to the start of the allocation. Note that this is
194194
/// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must
195195
/// be careful.
@@ -409,8 +409,8 @@ impl<T, A: Alloc> RawVec<T, A> {
409409
/// Aborts on OOM
410410
pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
411411
match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Exact) {
412-
Err(CapacityOverflow) => capacity_overflow(),
413-
Err(AllocErr) => unreachable!(),
412+
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
413+
Err(CollectionAllocErr::AllocErr) => unreachable!(),
414414
Ok(()) => { /* yay */ }
415415
}
416416
}
@@ -422,7 +422,7 @@ impl<T, A: Alloc> RawVec<T, A> {
422422
-> Result<usize, CollectionAllocErr> {
423423

424424
// Nothing we can really do about these checks :(
425-
let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?;
425+
let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CollectionAllocErr::CapacityOverflow)?;
426426
// Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
427427
let double_cap = self.cap * 2;
428428
// `double_cap` guarantees exponential growth.
@@ -489,8 +489,8 @@ impl<T, A: Alloc> RawVec<T, A> {
489489
/// ```
490490
pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
491491
match self.reserve_internal(used_cap, needed_extra_cap, Infallible, Amortized) {
492-
Err(CapacityOverflow) => capacity_overflow(),
493-
Err(AllocErr) => unreachable!(),
492+
Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(),
493+
Err(CollectionAllocErr::AllocErr) => unreachable!(),
494494
Ok(()) => { /* yay */ }
495495
}
496496
}
@@ -629,7 +629,7 @@ enum ReserveStrategy {
629629

630630
use ReserveStrategy::*;
631631

632-
impl<T, A: Alloc> RawVec<T, A> {
632+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
633633
fn reserve_internal(
634634
&mut self,
635635
used_cap: usize,
@@ -638,8 +638,6 @@ impl<T, A: Alloc> RawVec<T, A> {
638638
strategy: ReserveStrategy,
639639
) -> Result<(), CollectionAllocErr> {
640640
unsafe {
641-
use crate::alloc::AllocErr;
642-
643641
// NOTE: we don't early branch on ZSTs here because we want this
644642
// to actually catch "asking for more than usize::MAX" in that case.
645643
// If we make it past the first branch then we are guaranteed to
@@ -653,10 +651,10 @@ impl<T, A: Alloc> RawVec<T, A> {
653651

654652
// Nothing we can really do about these checks :(
655653
let new_cap = match strategy {
656-
Exact => used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?,
654+
Exact => used_cap.checked_add(needed_extra_cap).ok_or(CollectionAllocErr::CapacityOverflow)?,
657655
Amortized => self.amortized_new_size(used_cap, needed_extra_cap)?,
658656
};
659-
let new_layout = Layout::array::<T>(new_cap).map_err(|_| CapacityOverflow)?;
657+
let new_layout = Layout::array::<T>(new_cap).map_err(|_| CollectionAllocErr::CapacityOverflow)?;
660658

661659
alloc_guard(new_layout.size())?;
662660

@@ -682,7 +680,7 @@ impl<T, A: Alloc> RawVec<T, A> {
682680

683681
}
684682

685-
impl<T, A: Alloc> RawVec<T, A> {
683+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
686684
/// Converts the entire buffer into `Box<[T], A>`.
687685
///
688686
/// Note that this will correctly reconstitute any `cap` changes
@@ -703,7 +701,7 @@ impl<T, A: Alloc> RawVec<T, A> {
703701
}
704702
}
705703

706-
impl<T, A: Alloc> RawVec<T, A> {
704+
impl<T, A: Alloc<Err = AllocErr>> RawVec<T, A> {
707705
/// Frees the memory owned by the RawVec *without* trying to Drop its contents.
708706
pub unsafe fn dealloc_buffer(&mut self) {
709707
let elem_size = mem::size_of::<T>();
@@ -715,7 +713,7 @@ impl<T, A: Alloc> RawVec<T, A> {
715713
}
716714
}
717715

718-
unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
716+
unsafe impl<#[may_dangle] T, A: Alloc<Err = AllocErr>> Drop for RawVec<T, A> {
719717
/// Frees the memory owned by the RawVec *without* trying to Drop its contents.
720718
fn drop(&mut self) {
721719
unsafe { self.dealloc_buffer(); }
@@ -736,7 +734,7 @@ unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
736734
#[inline]
737735
fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
738736
if mem::size_of::<usize>() < 8 && alloc_size > core::isize::MAX as usize {
739-
Err(CapacityOverflow)
737+
Err(CollectionAllocErr::CapacityOverflow)
740738
} else {
741739
Ok(())
742740
}

src/liballoc/str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use core::ptr;
3535
use core::iter::FusedIterator;
3636
use core::unicode::conversions;
3737

38-
use crate::alloc::Alloc;
38+
use crate::alloc::{Alloc, AllocErr};
3939
use crate::borrow::ToOwned;
4040
use crate::boxed::Box;
4141
use crate::slice::{SliceConcatExt, SliceIndex};
@@ -586,6 +586,6 @@ impl str {
586586
/// ```
587587
#[stable(feature = "str_box_extras", since = "1.20.0")]
588588
#[inline]
589-
pub unsafe fn from_boxed_utf8_unchecked<A: Alloc>(v: Box<[u8], A>) -> Box<str, A> {
589+
pub unsafe fn from_boxed_utf8_unchecked<A: Alloc<Err=AllocErr>>(v: Box<[u8], A>) -> Box<str, A> {
590590
Box::map_raw(v, |p| p as *mut str)
591591
}

src/liballoc/string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ impl String {
991991
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
992992
/// ```
993993
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
994-
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
994+
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
995995
self.vec.try_reserve_exact(additional)
996996
}
997997

0 commit comments

Comments
 (0)