Skip to content

Commit afa5677

Browse files
committed
box, RawVec: Generalize to not neccessary abort on OOM
1 parent 4454093 commit afa5677

File tree

11 files changed

+230
-186
lines changed

11 files changed

+230
-186
lines changed

src/liballoc/abort_adapter.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ unsafe impl<A: Alloc> Alloc for AbortAdapter<A> {
4848
ptr: NonNull<u8>,
4949
layout: Layout,
5050
new_size: usize) -> Result<NonNull<u8>, Self::Err> {
51-
self.0.realloc(ptr, layout, new_size).or_else(|_| handle_alloc_error(layout))
51+
self.0.realloc(ptr, layout, new_size).or_else(|_| {
52+
let layout = Layout::from_size_align_unchecked(new_size, layout.align());
53+
handle_alloc_error(layout)
54+
})
5255
}
5356

5457
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, Self::Err> {

src/liballoc/boxed.rs

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

91-
use crate::alloc::{Alloc, AllocErr, Global, Layout, handle_alloc_error};
91+
use crate::abort_adapter::AbortAdapter;
92+
use crate::alloc::{Alloc, Global, Layout};
9293
use crate::vec::Vec;
9394
use crate::raw_vec::RawVec;
9495
use crate::str::from_boxed_utf8_unchecked;
@@ -99,7 +100,7 @@ use crate::str::from_boxed_utf8_unchecked;
99100
#[lang = "owned_box"]
100101
#[fundamental]
101102
#[stable(feature = "rust1", since = "1.0.0")]
102-
pub struct Box<T: ?Sized, A = Global>(Unique<T>, pub(crate) A);
103+
pub struct Box<T: ?Sized, A = AbortAdapter<Global>>(Unique<T>, pub(crate) A);
103104

104105
impl<T> Box<T> {
105106
/// Allocates memory on the heap and then places `x` into it.
@@ -126,7 +127,7 @@ impl<T> Box<T> {
126127
}
127128
}
128129

129-
impl<T, A: Alloc<Err = AllocErr>> Box<T, A> {
130+
impl<T, A: Alloc> Box<T, A> {
130131
/// Allocates memory in the given allocator and then places `x` into it.
131132
///
132133
/// This doesn't actually allocate if `T` is zero-sized.
@@ -140,15 +141,15 @@ impl<T, A: Alloc<Err = AllocErr>> Box<T, A> {
140141
/// ```
141142
#[unstable(feature = "allocator_api", issue = "32838")]
142143
#[inline(always)]
143-
pub fn new_in(x: T, a: A) -> Box<T, A> {
144+
pub fn new_in(x: T, a: A) -> Result<Box<T, A>, A::Err> {
144145
let mut a = a;
145146
let layout = Layout::for_value(&x);
146147
let size = layout.size();
147148
let ptr = if size == 0 {
148149
Unique::empty()
149150
} else {
150151
unsafe {
151-
let ptr = a.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout));
152+
let ptr = a.alloc(layout)?;
152153
ptr.cast().into()
153154
}
154155
};
@@ -157,15 +158,15 @@ impl<T, A: Alloc<Err = AllocErr>> Box<T, A> {
157158
unsafe {
158159
ptr::write(ptr.as_ptr() as *mut T, x);
159160
}
160-
Box(ptr, a)
161+
Ok(Box(ptr, a))
161162
}
162163

163164
/// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
164165
/// `x` will be pinned in memory and unable to be moved.
165166
#[unstable(feature = "allocator_api", issue = "32838")]
166167
#[inline(always)]
167-
pub fn pin_in(x: T, a: A) -> Pin<Box<T, A>> {
168-
Box::new_in(x, a).into()
168+
pub fn pin_in(x: T, a: A) -> Result<Pin<Box<T, A>>, A::Err> {
169+
Box::new_in(x, a).map(Into::into)
169170
}
170171
}
171172

@@ -209,7 +210,7 @@ impl<T: ?Sized> Box<T> {
209210
#[stable(feature = "box_raw", since = "1.4.0")]
210211
#[inline]
211212
pub unsafe fn from_raw(raw: *mut T) -> Self {
212-
Box(Unique::new_unchecked(raw), Global)
213+
Box(Unique::new_unchecked(raw), AbortAdapter(Global))
213214
}
214215
}
215216

@@ -293,7 +294,7 @@ impl<T: ?Sized, A> Box<T, A> {
293294
/// [`Box::from_raw`]: struct.Box.html#method.from_raw
294295
#[stable(feature = "box_raw", since = "1.4.0")]
295296
#[inline]
296-
pub fn into_raw(b: Box<T, A>) -> *mut T {
297+
pub fn into_raw(b: Self) -> *mut T {
297298
Box::into_raw_non_null(b).as_ptr()
298299
}
299300

@@ -333,10 +334,20 @@ impl<T: ?Sized, A> Box<T, A> {
333334
Box::into_unique(b).into()
334335
}
335336

337+
/// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>` along
338+
/// with the allocator.
339+
// Also feature = "box_into_raw_non_null", issue = "47336", FIXME how to write?
340+
#[unstable(feature = "allocator_api", issue = "32838")]
341+
#[inline]
342+
pub fn into_both_non_null(b: Self) -> (NonNull<T>, A) {
343+
let (unique, alloc) = Box::into_both_unique(b).into();
344+
(unique.into(), alloc)
345+
}
346+
336347
#[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")]
337348
#[inline]
338349
#[doc(hidden)]
339-
pub fn into_unique(b: Box<T, A>) -> Unique<T> {
350+
pub fn into_unique(b: Self) -> Unique<T> {
340351
let mut unique = b.0;
341352
mem::forget(b);
342353
// Box is kind-of a library type, but recognized as a "unique pointer" by
@@ -348,6 +359,22 @@ impl<T: ?Sized, A> Box<T, A> {
348359
unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
349360
}
350361

362+
/// Consumes the `Box`, returning the wrapped pointer as `Unique<T>` along
363+
/// with the allocator.
364+
#[unstable(feature = "allocator_api", issue = "32838")]
365+
#[inline]
366+
#[doc(hidden)]
367+
pub fn into_both_unique(mut b: Self) -> (Unique<T>, A) {
368+
let unique = b.0.into();
369+
let alloc = unsafe {
370+
let mut a = mem::MaybeUninit::uninit();
371+
ptr::swap(a.as_mut_ptr(), &mut b.1 as *mut _);
372+
mem::forget(b);
373+
a.assume_init()
374+
};
375+
(unique, alloc)
376+
}
377+
351378
/// Consumes and leaks the `Box`, returning a mutable reference,
352379
/// `&'a mut T`. Note that the type `T` must outlive the chosen lifetime
353380
/// `'a`. If the type has only static references, or none at all, then this
@@ -391,7 +418,7 @@ impl<T: ?Sized, A> Box<T, A> {
391418
/// ```
392419
#[stable(feature = "box_leak", since = "1.26.0")]
393420
#[inline]
394-
pub fn leak<'a>(b: Box<T, A>) -> &'a mut T
421+
pub fn leak<'a>(b: Self) -> &'a mut T
395422
where
396423
T: 'a // Technically not needed, but kept to be explicit.
397424
{
@@ -412,6 +439,7 @@ impl<T: ?Sized, A> Box<T, A> {
412439
}
413440
}
414441

442+
415443
#[stable(feature = "rust1", since = "1.0.0")]
416444
unsafe impl<#[may_dangle] T: ?Sized, A> Drop for Box<T, A> {
417445
fn drop(&mut self) {
@@ -420,29 +448,31 @@ unsafe impl<#[may_dangle] T: ?Sized, A> Drop for Box<T, A> {
420448
}
421449

422450
#[stable(feature = "rust1", since = "1.0.0")]
423-
impl<T: Default, A: Alloc<Err = AllocErr> + Default> Default for Box<T, A> {
451+
impl<T: Default, A: Alloc<Err = !> + Default> Default for Box<T, A> {
424452
/// Creates a `Box<T, A>`, with the `Default` value for T.
425453
fn default() -> Box<T, A> {
426-
Box::new_in(Default::default(), A::default())
454+
let Ok(b) = Box::new_in(Default::default(), A::default());
455+
b
427456
}
428457
}
429458

430459
#[stable(feature = "rust1", since = "1.0.0")]
431-
impl<T, A: Alloc<Err = AllocErr> + Default> Default for Box<[T], A> {
460+
impl<T, A: Alloc<Err=!> + Default> Default for Box<[T], A> {
432461
fn default() -> Box<[T], A> {
433-
Box::<[T; 0], A>::new_in([], A::default())
462+
let Ok(b) = Box::<[T; 0], A>::new_in([], Default::default());
463+
b
434464
}
435465
}
436466

437467
#[stable(feature = "default_box_extra", since = "1.17.0")]
438-
impl<A: Alloc<Err = AllocErr> + Default> Default for Box<str, A> {
468+
impl<A: Alloc<Err = !> + Default> Default for Box<str, A> {
439469
fn default() -> Box<str, A> {
440470
unsafe { from_boxed_utf8_unchecked(Default::default()) }
441471
}
442472
}
443473

444474
#[stable(feature = "rust1", since = "1.0.0")]
445-
impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<T, A> {
475+
impl<T: Clone, A: Alloc<Err = !> + Clone> Clone for Box<T, A> {
446476
/// Returns a new box with a `clone()` of this box's contents.
447477
///
448478
/// # Examples
@@ -453,8 +483,9 @@ impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<T, A> {
453483
/// ```
454484
#[rustfmt::skip]
455485
#[inline]
456-
fn clone(&self) -> Box<T, A> {
457-
Box::new_in((**self).clone(), self.1.clone())
486+
fn clone(&self) -> Self {
487+
let Ok(b) = Box::new_in((**self).clone(), self.1.clone());
488+
b
458489
}
459490
/// Copies `source`'s contents into `self` without creating a new allocation.
460491
///
@@ -469,13 +500,13 @@ impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<T, A> {
469500
/// assert_eq!(*y, 5);
470501
/// ```
471502
#[inline]
472-
fn clone_from(&mut self, source: &Box<T, A>) {
503+
fn clone_from(&mut self, source: &Self) {
473504
(**self).clone_from(&(**source));
474505
}
475506
}
476507

477508
#[stable(feature = "box_slice_clone", since = "1.3.0")]
478-
impl<A: Alloc<Err = AllocErr> + Clone> Clone for Box<str, A> {
509+
impl<A: Alloc<Err = !> + Clone> Clone for Box<str, A> {
479510
fn clone(&self) -> Self {
480511
// this makes a copy of the data
481512
let buf = Box::<[u8], A>::from_slice_in(self.as_bytes(), self.1.clone());
@@ -485,6 +516,7 @@ impl<A: Alloc<Err = AllocErr> + Clone> Clone for Box<str, A> {
485516
}
486517
}
487518

519+
/// Just the contents are compared, the allocator is ignored
488520
#[stable(feature = "rust1", since = "1.0.0")]
489521
impl<T: ?Sized + PartialEq, A> PartialEq for Box<T, A> {
490522
#[inline]
@@ -496,6 +528,7 @@ impl<T: ?Sized + PartialEq, A> PartialEq for Box<T, A> {
496528
PartialEq::ne(&**self, &**other)
497529
}
498530
}
531+
/// Just the contents are compared, the allocator is ignored
499532
#[stable(feature = "rust1", since = "1.0.0")]
500533
impl<T: ?Sized + PartialOrd, A> PartialOrd for Box<T, A> {
501534
#[inline]
@@ -519,23 +552,27 @@ impl<T: ?Sized + PartialOrd, A> PartialOrd for Box<T, A> {
519552
PartialOrd::gt(&**self, &**other)
520553
}
521554
}
555+
/// Just the contents are compared, the allocator is ignored
522556
#[stable(feature = "rust1", since = "1.0.0")]
523557
impl<T: ?Sized + Ord, A> Ord for Box<T, A> {
524558
#[inline]
525559
fn cmp(&self, other: &Box<T, A>) -> Ordering {
526560
Ord::cmp(&**self, &**other)
527561
}
528562
}
563+
/// Just the contents are compared, the allocator is ignored
529564
#[stable(feature = "rust1", since = "1.0.0")]
530565
impl<T: ?Sized + Eq, A> Eq for Box<T, A> {}
531566

567+
/// Just the contents are compared, the allocator is ignored
532568
#[stable(feature = "rust1", since = "1.0.0")]
533569
impl<T: ?Sized + Hash, A> Hash for Box<T, A> {
534570
fn hash<H: Hasher>(&self, state: &mut H) {
535571
(**self).hash(state);
536572
}
537573
}
538574

575+
/// Just the contents are compared, the allocator is ignored
539576
#[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
540577
impl<T: ?Sized + Hasher, A> Hasher for Box<T, A> {
541578
fn finish(&self) -> u64 {
@@ -583,7 +620,7 @@ impl<T: ?Sized + Hasher, A> Hasher for Box<T, A> {
583620
}
584621

585622
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
586-
impl<T, A: Alloc<Err = AllocErr> + Default> From<T> for Box<T, A> {
623+
impl<T, A: Alloc<Err = !> + Default> From<T> for Box<T, A> {
587624
/// Converts a generic type `T` into a `Box<T>`
588625
///
589626
/// The conversion allocates on the heap and moves `t`
@@ -597,7 +634,8 @@ impl<T, A: Alloc<Err = AllocErr> + Default> From<T> for Box<T, A> {
597634
/// assert_eq!(Box::from(x), boxed);
598635
/// ```
599636
fn from(t: T) -> Self {
600-
Box::new_in(t, A::default())
637+
let Ok(b) = Box::new_in(t, Default::default());
638+
b
601639
}
602640
}
603641

@@ -611,10 +649,10 @@ impl<T: ?Sized, A> From<Box<T, A>> for Pin<Box<T, A>> {
611649
}
612650
}
613651

614-
impl<T: Copy, A: Alloc<Err = AllocErr>> Box<[T], A> {
652+
impl<T: Copy, A: Alloc<Err = !>> Box<[T], A> {
615653
fn from_slice_in(slice: &[T], a: A) -> Box<[T], A> {
616654
let len = slice.len();
617-
let buf = RawVec::with_capacity_in(len, a);
655+
let Ok(buf) = RawVec::with_capacity_in(len, a);
618656
unsafe {
619657
ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
620658
buf.into_box()
@@ -623,7 +661,7 @@ impl<T: Copy, A: Alloc<Err = AllocErr>> Box<[T], A> {
623661
}
624662

625663
#[stable(feature = "box_from_slice", since = "1.17.0")]
626-
impl<T: Copy, A: Alloc<Err = AllocErr> + Default> From<&[T]> for Box<[T], A> {
664+
impl<T: Copy, A: Alloc<Err = !> + Default> From<&[T]> for Box<[T], A> {
627665
/// Converts a `&[T]` into a `Box<[T]>`
628666
///
629667
/// This conversion allocates on the heap
@@ -643,7 +681,7 @@ impl<T: Copy, A: Alloc<Err = AllocErr> + Default> From<&[T]> for Box<[T], A> {
643681
}
644682

645683
#[stable(feature = "box_from_slice", since = "1.17.0")]
646-
impl<A: Alloc<Err = AllocErr> + Default> From<&str> for Box<str, A> {
684+
impl<A: Alloc<Err = !> + Default> From<&str> for Box<str, A> {
647685
/// Converts a `&str` into a `Box<str>`
648686
///
649687
/// This conversion allocates on the heap
@@ -715,7 +753,7 @@ impl<A> Box<dyn Any, A> {
715753
}
716754
}
717755

718-
impl<A: Alloc<Err=AllocErr>> Box<dyn Any + Send, A> {
756+
impl<A: Alloc<Err=!>> Box<dyn Any + Send, A> {
719757
#[inline]
720758
#[stable(feature = "rust1", since = "1.0.0")]
721759
/// Attempt to downcast the box to a concrete type.
@@ -909,9 +947,9 @@ impl<A, F: Fn<A> + ?Sized, Alloc> Fn<A> for Box<F, Alloc> {
909947
#[rustc_paren_sugar]
910948
#[unstable(feature = "fnbox", issue = "28796")]
911949
#[rustc_deprecated(reason = "use `FnOnce`, `FnMut`, or `Fn` instead", since = "1.37.0")]
912-
pub trait FnBox<A>: FnOnce<A> {
950+
pub trait FnBox<Args, A: Alloc = AbortAdapter<Global>>: FnOnce<Args> {
913951
/// Performs the call operation.
914-
fn call_box(self: Box<Self>, args: A) -> Self::Output;
952+
fn call_box(self: Box<Self, A>, args: Args) -> Self::Output;
915953
}
916954

917955
#[unstable(feature = "fnbox", issue = "28796")]
@@ -940,10 +978,12 @@ impl<A> FromIterator<A> for Box<[A]> {
940978
}
941979

942980
#[stable(feature = "box_slice_clone", since = "1.3.0")]
943-
impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<[T], A> {
981+
impl<T: Clone, A: Alloc<Err = !> + Clone> Clone for Box<[T], A> {
944982
fn clone(&self) -> Self {
983+
let Ok(b) = RawVec::with_capacity_in(self.len(), self.1.clone());
984+
945985
let mut new = BoxBuilder {
946-
data: RawVec::with_capacity_in(self.len(), self.1.clone()),
986+
data: b,
947987
len: 0,
948988
};
949989

@@ -961,20 +1001,20 @@ impl<T: Clone, A: Alloc<Err = AllocErr> + Clone> Clone for Box<[T], A> {
9611001
return unsafe { new.into_box() };
9621002

9631003
// Helper type for responding to panics correctly.
964-
struct BoxBuilder<T, A: Alloc<Err = AllocErr>> {
1004+
struct BoxBuilder<T, A: Alloc> {
9651005
data: RawVec<T, A>,
9661006
len: usize,
9671007
}
9681008

969-
impl<T, A: Alloc<Err = AllocErr>> BoxBuilder<T, A> {
1009+
impl<T, A: Alloc> BoxBuilder<T, A> {
9701010
unsafe fn into_box(self) -> Box<[T], A> {
9711011
let raw = ptr::read(&self.data);
9721012
mem::forget(self);
9731013
raw.into_box()
9741014
}
9751015
}
9761016

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

0 commit comments

Comments
 (0)