diff --git a/src/alloc/abort.rs b/src/alloc/abort.rs new file mode 100644 index 0000000..d7aed1b --- /dev/null +++ b/src/alloc/abort.rs @@ -0,0 +1,106 @@ +#![allow(clippy::use_self)] + +use crate::alloc::{ + handle_alloc_error, + AllocRef, + BuildAllocRef, + DeallocRef, + NonZeroLayout, + NonZeroUsize, + ReallocRef, +}; +use core::ptr::NonNull; + +/// An allocator adapter that blows up by calling `handle_alloc_error` on OOM. +/// +/// On one hand, concrete allocator implementations should always be written +/// without panicking on user error and OOM to give users maximum +/// flexibility. On the other hand, code that depends on allocation succeeding +/// should depend on `Alloc` to avoid repetitively handling errors from +/// which it cannot recover. +/// +/// This adapter bridges the gap, effectively allowing `Alloc` to be +/// implemented by any allocator. +#[derive(Copy, Clone, Debug, Default)] +pub struct AbortAlloc(pub Alloc); + +/// A synonym used to indicate the impossible case will be a panic instead. +/// +/// `!` in rust really does mean "never" / "impossible", but nothing in the type +/// system tracks panicking. +pub type Panic = !; + +impl BuildAllocRef for AbortAlloc { + type Ref = AbortAlloc; + + unsafe fn build_alloc_ref( + &mut self, + ptr: NonNull, + layout: Option, + ) -> Self::Ref { + Self(self.0.build_alloc_ref(ptr, layout)) + } +} + +impl DeallocRef for AbortAlloc { + type BuildAlloc = AbortAlloc; + + fn get_build_alloc(&mut self) -> Self::BuildAlloc { + Self(self.0.get_build_alloc()) + } + + unsafe fn dealloc(&mut self, ptr: NonNull, layout: NonZeroLayout) { + self.0.dealloc(ptr, layout) + } +} + +impl AllocRef for AbortAlloc { + type Error = Panic; + + fn alloc(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + self.0 + .alloc(layout) + .map_err(|_| handle_alloc_error(layout.into())) + } + + fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result, Self::Error> { + self.0 + .alloc_zeroed(layout) + .map_err(|_| handle_alloc_error(layout.into())) + } + + fn usable_size(&self, layout: NonZeroLayout) -> (usize, usize) { + self.0.usable_size(layout) + } + + unsafe fn grow_in_place( + &mut self, + ptr: NonNull, + layout: NonZeroLayout, + new_size: NonZeroUsize, + ) -> bool { + self.0.grow_in_place(ptr, layout, new_size) + } + + unsafe fn shrink_in_place( + &mut self, + ptr: NonNull, + layout: NonZeroLayout, + new_size: NonZeroUsize, + ) -> bool { + self.0.shrink_in_place(ptr, layout, new_size) + } +} + +impl ReallocRef for AbortAlloc { + unsafe fn realloc( + &mut self, + ptr: NonNull, + old_layout: NonZeroLayout, + new_layout: NonZeroLayout, + ) -> Result, Self::Error> { + self.0 + .realloc(ptr, old_layout, new_layout) + .map_err(|_| handle_alloc_error(new_layout.into())) + } +} diff --git a/src/alloc/mod.rs b/src/alloc/mod.rs index 0502890..5882151 100644 --- a/src/alloc/mod.rs +++ b/src/alloc/mod.rs @@ -1,6 +1,10 @@ +mod abort; mod layout; -pub use self::layout::{LayoutErr, NonZeroLayout}; +pub use self::{ + abort::{AbortAlloc, Panic}, + layout::{LayoutErr, NonZeroLayout}, +}; pub use core::alloc::GlobalAlloc; use core::{ cmp, diff --git a/src/boxed.rs b/src/boxed.rs index 074c91d..2a4ed93 100644 --- a/src/boxed.rs +++ b/src/boxed.rs @@ -79,11 +79,10 @@ //! [`NonZeroLayout::for_value(&*value)`]: crate::alloc::NonZeroLayout::for_value use crate::{ - alloc::{AllocRef, BuildAllocRef, DeallocRef, Global, NonZeroLayout}, + alloc::{AbortAlloc, AllocRef, BuildAllocRef, DeallocRef, Global, NonZeroLayout, Panic}, clone::CloneIn, collections::CollectionAllocErr, raw_vec::RawVec, - UncheckedResultExt, }; use core::{ any::Any, @@ -105,7 +104,7 @@ use core::{ /// A pointer type for heap allocation. /// /// See the [module-level documentation](index.html) for more. -pub struct Box { +pub struct Box> { ptr: Unique, build_alloc: A::BuildAlloc, } @@ -131,7 +130,7 @@ impl Box { #[inline(always)] #[must_use] pub fn new(x: T) -> Self { - Self::new_in(x, Global) + Self::new_in(x, AbortAlloc(Global)) } /// Constructs a new box with uninitialized contents. @@ -156,7 +155,7 @@ impl Box { #[inline(always)] #[must_use] pub fn new_uninit() -> Box> { - Self::new_uninit_in(Global) + Self::new_uninit_in(AbortAlloc(Global)) } /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then @@ -177,15 +176,22 @@ impl Box { /// # Example /// /// ``` - /// use alloc_wg::{alloc::Global, boxed::Box}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// boxed::Box, + /// }; /// /// # #[allow(unused_variables)] - /// let five = Box::new_in(5, Global); + /// let five = Box::new_in(5, AbortAlloc(Global)); /// ``` #[allow(clippy::inline_always)] #[inline(always)] - pub fn new_in(x: T, a: A) -> Self { - unsafe { Self::try_new_in(x, a).unwrap_unchecked() } + pub fn new_in(x: T, a: A) -> Self + where + A: AllocRef, + { + let Ok(b) = Self::try_new_in(x, a); + b } /// Tries to allocate memory with the given allocator and then places `x` into it. @@ -219,9 +225,12 @@ impl Box { /// # Example /// /// ``` - /// use alloc_wg::{alloc::Global, boxed::Box}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// boxed::Box, + /// }; /// - /// let mut five = Box::::new_uninit_in(Global); + /// let mut five = Box::::new_uninit_in(AbortAlloc(Global)); /// /// let five = unsafe { /// // Deferred initialization: @@ -234,8 +243,12 @@ impl Box { /// ``` #[allow(clippy::inline_always)] #[inline(always)] - pub fn new_uninit_in(a: A) -> Box, A> { - unsafe { Self::try_new_uninit_in(a).unwrap_unchecked() } + pub fn new_uninit_in(a: A) -> Box, A> + where + A: AllocRef, + { + let Ok(b) = Self::try_new_uninit_in(a); + b } /// Tries to construct a new box with uninitialized contents in a specified allocator. @@ -271,8 +284,12 @@ impl Box { /// `Unpin`, then `x` will be pinned in memory and unable to be moved. #[allow(clippy::inline_always)] #[inline(always)] - pub fn pin_in(x: T, a: A) -> Pin { - unsafe { Self::try_pin_in(x, a).unwrap_unchecked() } + pub fn pin_in(x: T, a: A) -> Pin + where + A: AllocRef, + { + let Ok(b) = Self::try_pin_in(x, a); + b } /// Constructs a new `Pin>` with the specified allocator. If `T` does not implement @@ -309,20 +326,23 @@ impl Box<[T]> { #[inline(always)] #[must_use] pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> { - Self::new_uninit_slice_in(len, Global) + Self::new_uninit_slice_in(len, AbortAlloc(Global)) } } #[allow(clippy::use_self)] -impl Box<[T], A> { +impl> Box<[T], A> { /// Construct a new boxed slice with uninitialized contents with the spoecified allocator. /// /// # Example /// /// ``` - /// use alloc_wg::{alloc::Global, boxed::Box}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// boxed::Box, + /// }; /// - /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, Global); + /// let mut values = Box::<[u32], AbortAlloc>::new_uninit_slice_in(3, AbortAlloc(Global)); /// /// let values = unsafe { /// // Deferred initialization: @@ -338,9 +358,17 @@ impl Box<[T], A> { #[allow(clippy::inline_always)] #[inline(always)] pub fn new_uninit_slice_in(len: usize, a: A) -> Box<[mem::MaybeUninit], A> { - unsafe { Self::try_new_uninit_slice_in(len, a).unwrap_unchecked() } + match Self::try_new_uninit_slice_in(len, a) { + Ok(b) => b, + Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, + } } +} +#[allow(clippy::use_self)] +impl Box<[T], A> { /// Tries to construct a new boxed slice with uninitialized contents with the spoecified /// allocator. /// @@ -503,7 +531,7 @@ impl Box { #[allow(clippy::inline_always)] #[inline(always)] pub unsafe fn from_raw(raw: *mut T) -> Self { - Self::from_raw_in(raw, Global) + Self::from_raw_in(raw, AbortAlloc(Global)) } } @@ -747,7 +775,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: DeallocRef> Drop for Box { impl Default for Box where T: Default, - A: Default + AllocRef, + A: Default + AllocRef, { #[must_use] fn default() -> Self { @@ -756,9 +784,9 @@ where } #[allow(clippy::use_self)] -impl Default for Box<[T], A> +impl> Default for Box<[T], A> where - A: Default + AllocRef, + A: Default + AllocRef, { #[must_use] fn default() -> Self { @@ -773,9 +801,9 @@ unsafe fn from_boxed_utf8_unchecked(v: Box<[u8], A>) -> Box Default for Box +impl> Default for Box where - A: Default + AllocRef, + A: Default + AllocRef, { #[must_use] fn default() -> Self { @@ -783,9 +811,9 @@ where } } -impl Clone for Box +impl> Clone for Box where - A: AllocRef, + A: AllocRef, A::BuildAlloc: Clone, { /// Returns a new box with a `clone()` of this box's contents. @@ -846,7 +874,10 @@ where impl CloneIn for Box { type Cloned = Box; - fn clone_in(&self, a: B) -> Self::Cloned { + fn clone_in(&self, a: B) -> Self::Cloned + where + B: AllocRef, + { Box::new_in(self.as_ref().clone(), a) } @@ -947,9 +978,9 @@ impl Hasher for Box { } } -impl From for Box +impl> From for Box where - A: Default + AllocRef, + A: Default + AllocRef, { /// Converts a generic type `T` into a `Box` /// @@ -983,7 +1014,7 @@ impl From> for Pin> { #[allow(clippy::use_self)] impl From<&[T]> for Box<[T], A> where - A: Default + AllocRef, + A: Default + AllocRef, { /// Converts a `&[T]` into a `Box<[T], B>` /// @@ -1012,7 +1043,7 @@ where #[allow(clippy::use_self)] impl From<&str> for Box where - A: Default + AllocRef, + A: Default + AllocRef, { /// Converts a `&str` into a `Box` /// @@ -1266,13 +1297,16 @@ macro_rules! impl_dispatch_from_dyn { } impl_dispatch_from_dyn!(Global); +impl_dispatch_from_dyn!(AbortAlloc); #[cfg(feature = "std")] impl_dispatch_from_dyn!(std::alloc::System); +#[cfg(feature = "std")] +impl_dispatch_from_dyn!(AbortAlloc); #[allow(clippy::items_after_statements)] impl Clone for Box<[T], A> where - A: AllocRef, + A: AllocRef, A::BuildAlloc: Clone, { fn clone(&self) -> Self { @@ -1383,3 +1417,10 @@ impl Future for Box { F::poll(Pin::new(&mut *self), cx) } } + +// One central function responsible for reporting capacity overflows. This'll +// ensure that the code generation related to these panics is minimal as there's +// only one location which panics rather than a bunch throughout the module. +fn capacity_overflow() -> ! { + panic!("capacity overflow"); +} diff --git a/src/clone.rs b/src/clone.rs index 1fbe118..ee4a970 100644 --- a/src/clone.rs +++ b/src/clone.rs @@ -1,9 +1,11 @@ -use crate::alloc::AllocRef; +use crate::alloc::{AllocRef, Panic}; pub trait CloneIn: Sized { type Cloned; - fn clone_in(&self, a: A) -> Self::Cloned; + fn clone_in(&self, a: A) -> Self::Cloned + where + A: AllocRef; fn try_clone_in(&self, a: A) -> Result; } diff --git a/src/iter.rs b/src/iter.rs index 591701f..4e44bc1 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,4 +1,7 @@ -use crate::{alloc::AllocRef, collections::CollectionAllocErr}; +use crate::{ + alloc::{AllocRef, Panic}, + collections::CollectionAllocErr, +}; /// Extend a collection "fallibly" with the contents of an iterator. pub trait TryExtend { @@ -19,13 +22,15 @@ pub trait TryExtend { /// message.try_extend(['d', 'e', 'f'].iter())?; /// /// assert_eq!(vec!['a', 'b', 'c', 'd', 'e', 'f'], message); - /// # Ok::<(), alloc_wg::collections::CollectionAllocErr>(()) + /// # Ok::<(), alloc_wg::collections::CollectionAllocErr>>(()) /// ``` fn try_extend>(&mut self, iter: T) -> Result<(), Self::Err>; } pub trait FromIteratorIn { - fn from_iter_in>(iter: I, allocator: A) -> Self; + fn from_iter_in>(iter: I, allocator: A) -> Self + where + A: AllocRef; fn try_from_iter_in>( iter: I, @@ -38,7 +43,10 @@ pub trait FromIteratorIn { pub trait IteratorExt: Iterator + Sized { #[inline] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] - fn collect_in, A: AllocRef>(self, allocator: A) -> T { + fn collect_in, A: AllocRef>(self, allocator: A) -> T + where + A: AllocRef, + { FromIteratorIn::from_iter_in(self, allocator) } diff --git a/src/lib.rs b/src/lib.rs index 0f49cd4..a3b5762 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,7 +67,8 @@ specialization, trusted_len, unsized_locals, - fn_traits + fn_traits, + exhaustive_patterns )] #![cfg_attr(not(feature = "std"), no_std)] #![doc(test(attr( @@ -115,8 +116,6 @@ pub mod vec; extern crate alloc as liballoc; -mod unchecked_unwrap; -use self::unchecked_unwrap::*; pub use liballoc::{borrow, fmt, rc, slice, sync}; #[macro_export] diff --git a/src/raw_vec.rs b/src/raw_vec.rs index 3cc236c..4cbd037 100644 --- a/src/raw_vec.rs +++ b/src/raw_vec.rs @@ -1,12 +1,13 @@ use crate::{ alloc::{ - handle_alloc_error, + AbortAlloc, AllocRef, BuildAllocRef, CapacityOverflow, DeallocRef, Global, NonZeroLayout, + Panic, ReallocRef, }, boxed::Box, @@ -33,7 +34,6 @@ use core::{ /// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics) /// * Guards against 32-bit systems allocating more than `isize::MAX` bytes /// * Guards against overflowing your length -/// * Aborts on OOM or calls `handle_alloc_error` as applicable /// * Avoids freeing `Unique::empty()` /// * Contains a `ptr::Unique` and thus endows the user with all related benefits /// @@ -51,7 +51,7 @@ use core::{ /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. // Using `NonNull` + `PhantomData` instead of `Unique` to stay on stable as long as possible -pub struct RawVec { +pub struct RawVec> { ptr: Unique, capacity: usize, build_alloc: A::BuildAlloc, @@ -89,7 +89,7 @@ impl RawVec { ptr: Unique::empty(), // FIXME(mark-i-m): use `cap` when ifs are allowed in const capacity: [0, !0][(mem::size_of::() == 0) as usize], - build_alloc: Global, + build_alloc: AbortAlloc(Global), } } @@ -110,7 +110,7 @@ impl RawVec { #[inline] #[must_use] pub fn with_capacity(capacity: usize) -> Self { - Self::with_capacity_in(capacity, Global) + Self::with_capacity_in(capacity, AbortAlloc(Global)) } /// Like `with_capacity`, but guarantees the buffer is zeroed. @@ -126,7 +126,7 @@ impl RawVec { #[inline] #[must_use] pub fn with_capacity_zeroed(capacity: usize) -> Self { - Self::with_capacity_zeroed_in(capacity, Global) + Self::with_capacity_zeroed_in(capacity, AbortAlloc(Global)) } /// Reconstitutes a `RawVec` from a pointer, and capacity. @@ -138,7 +138,7 @@ impl RawVec { /// If the ptr and capacity come from a `RawVec` created with `Global`, then this is guaranteed. #[inline] pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self { - Self::from_raw_parts_in(ptr, capacity, Global) + Self::from_raw_parts_in(ptr, capacity, AbortAlloc(Global)) } } @@ -163,12 +163,13 @@ impl RawVec { /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. pub fn with_capacity_in(capacity: usize, a: A) -> Self where - A: AllocRef, + A: AllocRef, { match Self::try_with_capacity_in(capacity, a) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -198,12 +199,13 @@ impl RawVec { /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self where - A: AllocRef, + A: AllocRef, { match Self::try_with_capacity_zeroed_in(capacity, a) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -418,12 +420,13 @@ impl RawVec { /// ``` pub fn double(&mut self) where - A: ReallocRef, + A: ReallocRef, { match self.try_double() { Ok(_) => (), Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -588,12 +591,13 @@ impl RawVec { /// ``` pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) where - A: ReallocRef, + A: ReallocRef, { match self.try_reserve(used_capacity, needed_extra_capacity) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -631,7 +635,7 @@ impl RawVec { /// * on 32-bit platforms if the requested capacity exceeds `isize::MAX` bytes. pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) where - A: ReallocRef, + A: ReallocRef, { match self.try_reserve_exact(used_capacity, needed_extra_capacity) { Ok(_) => (), @@ -733,7 +737,7 @@ impl RawVec { /// Panics if the given amount is *larger* than the current capacity. pub fn shrink_to_fit(&mut self, amount: usize) where - A: ReallocRef, + A: ReallocRef, { match self.try_shrink_to_fit(amount) { Ok(_) => (), diff --git a/src/string.rs b/src/string.rs index 980f798..e2001fc 100644 --- a/src/string.rs +++ b/src/string.rs @@ -52,7 +52,7 @@ //! ``` use crate::{ - alloc::{AllocRef, DeallocRef, Global, ReallocRef}, + alloc::{AbortAlloc, AllocRef, DeallocRef, Global, Panic, ReallocRef}, boxed::Box, collections::CollectionAllocErr, iter::TryExtend, @@ -80,7 +80,7 @@ use core::{ #[cfg(feature = "std")] use std::borrow::Cow; -use crate::{alloc::handle_alloc_error, clone::CloneIn}; +use crate::clone::CloneIn; pub use liballoc::string::{ParseError, ToString}; /// A UTF-8 encoded, growable string. @@ -312,7 +312,7 @@ pub use liballoc::string::{ParseError, ToString}; /// [`Deref`]: ../../std/ops/trait.Deref.html /// [`as_str()`]: struct.String.html#method.as_str #[derive(PartialOrd, Eq, Ord)] -pub struct String { +pub struct String> { vec: Vec, } @@ -354,7 +354,7 @@ pub struct String { /// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes()); /// ``` #[derive(Debug)] -pub struct FromUtf8Error { +pub struct FromUtf8Error> { bytes: Vec, error: Utf8Error, } @@ -451,7 +451,7 @@ impl String { #[inline] #[must_use] pub fn with_capacity(capacity: usize) -> Self { - Self::with_capacity_in(capacity, Global) + Self::with_capacity_in(capacity, AbortAlloc(Global)) } /// Decode a UTF-16 encoded vector `v` into a `String`, returning [`Err`] @@ -475,7 +475,7 @@ impl String { /// assert!(String::from_utf16(v).is_err()); /// ``` pub fn from_utf16(v: &[u16]) -> Result { - Self::from_utf16_in(v, Global) + Self::from_utf16_in(v, AbortAlloc(Global)) } /// Decode a UTF-16 encoded slice `v` into a `String`, replacing @@ -560,7 +560,7 @@ impl String { /// ``` #[inline] pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> Self { - Self::from_raw_parts_in(buf, length, capacity, Global) + Self::from_raw_parts_in(buf, length, capacity, AbortAlloc(Global)) } } @@ -580,10 +580,13 @@ impl String { #[inline] pub fn with_capacity_in(capacity: usize, a: A) -> Self where - A: AllocRef, + A: AllocRef, { - Self { - vec: Vec::with_capacity_in(capacity, a), + match Self::try_with_capacity_in(capacity, a) { + Ok(vec) => vec, + Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -605,7 +608,7 @@ impl String { #[inline] pub fn from_str_in(s: &str, a: A) -> Self where - A: ReallocRef, + A: ReallocRef, { let mut v = Self::with_capacity_in(s.len(), a); v.push_str(s); @@ -705,12 +708,13 @@ impl String { /// Panics if allocation fails. pub fn from_utf8_lossy_in(v: &[u8], a: A) -> Self where - A: ReallocRef, + A: ReallocRef, { match Self::try_from_utf8_lossy_in(v, a) { Ok(s) => s, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -753,7 +757,7 @@ impl String { /// Like `from_utf16` but parameterized over the choice of allocator for the returned `String`. pub fn from_utf16_in(v: &[u16], a: A) -> Result where - A: ReallocRef, + A: ReallocRef, { // This isn't done via collect::>() for performance reasons. // FIXME: the function can be simplified again when #48994 is closed. @@ -928,7 +932,7 @@ impl String { #[inline] pub fn push_str(&mut self, string: &str) where - A: ReallocRef, + A: ReallocRef, { self.vec.extend_from_slice(string.as_bytes()) } @@ -1012,7 +1016,7 @@ impl String { #[inline] pub fn reserve(&mut self, additional: usize) where - A: ReallocRef, + A: ReallocRef, { self.vec.reserve(additional) } @@ -1065,7 +1069,7 @@ impl String { #[inline] pub fn reserve_exact(&mut self, additional: usize) where - A: ReallocRef, + A: ReallocRef, { self.vec.reserve_exact(additional) } @@ -1084,9 +1088,13 @@ impl String { /// # Examples /// /// ``` - /// use alloc_wg::{alloc::Global, collections::CollectionAllocErr, string::String}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// collections::CollectionAllocErr, + /// string::String, + /// }; /// - /// fn process_data(data: &str) -> Result> { + /// fn process_data(data: &str) -> Result>> { /// let mut output = String::new(); /// /// // Pre-reserve the memory, exiting if we can't @@ -1123,9 +1131,13 @@ impl String { /// # Examples /// /// ``` - /// use alloc_wg::{alloc::Global, collections::CollectionAllocErr, string::String}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// collections::CollectionAllocErr, + /// string::String, + /// }; /// - /// fn process_data(data: &str) -> Result> { + /// fn process_data(data: &str) -> Result>> { /// let mut output = String::new(); /// /// // Pre-reserve the memory, exiting if we can't @@ -1168,7 +1180,7 @@ impl String { #[inline] pub fn shrink_to_fit(&mut self) where - A: ReallocRef, + A: ReallocRef, { self.vec.shrink_to_fit() } @@ -1212,7 +1224,7 @@ impl String { #[inline] pub fn shrink_to(&mut self, min_capacity: usize) where - A: ReallocRef, + A: ReallocRef, { self.vec.shrink_to(min_capacity) } @@ -1251,12 +1263,13 @@ impl String { #[inline] pub fn push(&mut self, ch: char) where - A: ReallocRef, + A: ReallocRef, { match self.try_push(ch) { Ok(s) => s, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1503,12 +1516,13 @@ impl String { #[inline] pub fn insert(&mut self, idx: usize, ch: char) where - A: ReallocRef, + A: ReallocRef, { match self.try_insert(idx, ch) { Ok(s) => s, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1578,12 +1592,13 @@ impl String { #[inline] pub fn insert_str(&mut self, idx: usize, string: &str) where - A: ReallocRef, + A: ReallocRef, { match self.try_insert_str(idx, string) { Ok(s) => s, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1591,7 +1606,7 @@ impl String { #[inline] pub fn try_insert_str(&mut self, idx: usize, string: &str) -> Result<(), CollectionAllocErr> where - A: ReallocRef, + A: ReallocRef, { assert!(self.is_char_boundary(idx)); @@ -1701,12 +1716,13 @@ impl String { #[inline] pub fn split_off(&mut self, at: usize) -> Self where - A: AllocRef, + A: AllocRef, { match self.try_split_off(at) { Ok(s) => s, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1819,7 +1835,7 @@ impl String { /// # Panics /// /// Panics if the starting point or end point do not lie on a [`char`] - /// boundary, or if they're out of bounds. + /// boundary, or if they're out of bounds, or if there is an allocation failure /// /// [`char`]: ../../std/primitive.char.html /// [`Vec::splice`]: ../../std/vec/struct.Vec.html#method.splice @@ -1840,7 +1856,7 @@ impl String { pub fn replace_range(&mut self, range: R, replace_with: &str) where R: RangeBounds, - A: ReallocRef, + A: ReallocRef, { // Memory safety // @@ -1885,7 +1901,7 @@ impl String { #[inline] pub fn into_boxed_str(self) -> Box where - A: ReallocRef, + A: ReallocRef, { let slice = self.vec.into_boxed_slice(); unsafe { from_boxed_utf8_unchecked(slice) } @@ -1991,7 +2007,7 @@ impl fmt::Display for FromUtf16Error { } } -impl Clone for String +impl> Clone for String where A: AllocRef, A::BuildAlloc: Clone, @@ -2015,7 +2031,10 @@ impl CloneIn for String { #[inline] #[must_use = "Cloning is expected to be expensive"] - fn clone_in(&self, a: B) -> Self::Cloned { + fn clone_in(&self, a: B) -> Self::Cloned + where + B: AllocRef, + { String { vec: self.vec.clone_in(a), } @@ -2091,7 +2110,7 @@ impl<'a> FromIterator> for String { impl Extend for String where - A: ReallocRef, + A: ReallocRef, { fn extend>(&mut self, iter: I) { let iterator = iter.into_iter(); @@ -2115,7 +2134,7 @@ impl TryExtend for String { impl<'a, A> Extend<&'a char> for String where - A: ReallocRef, + A: ReallocRef, { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); @@ -2132,7 +2151,7 @@ impl<'a, A: ReallocRef> TryExtend<&'a char> for String { impl<'a, A> Extend<&'a str> for String where - A: ReallocRef, + A: ReallocRef, { fn extend>(&mut self, iter: I) { iter.into_iter().for_each(move |s| self.push_str(s)); @@ -2149,7 +2168,7 @@ impl<'a, A: ReallocRef> TryExtend<&'a str> for String { impl Extend> for String where - A: ReallocRef, + A: ReallocRef, B: DeallocRef, { fn extend>>(&mut self, iter: I) { @@ -2169,7 +2188,7 @@ impl TryExtend> for String { #[cfg(feature = "std")] impl<'a, A> Extend> for String where - A: ReallocRef, + A: ReallocRef, { fn extend>>(&mut self, iter: I) { iter.into_iter().for_each(move |s| self.push_str(&s)); @@ -2305,7 +2324,7 @@ impl hash::Hash for String { /// ``` impl Add<&str> for String where - A: ReallocRef, + A: ReallocRef, { type Output = Self; @@ -2321,7 +2340,7 @@ where /// This has the same behavior as the [`push_str`][`String::push_str`] method. impl AddAssign<&str> for String where - A: ReallocRef, + A: ReallocRef, { #[inline] fn add_assign(&mut self, other: &str) { @@ -2497,7 +2516,7 @@ impl From> for String { impl From> for Box where - A: ReallocRef, + A: ReallocRef, { /// Converts the given `String` to a boxed `str` slice that is owned. /// diff --git a/src/unchecked_unwrap.rs b/src/unchecked_unwrap.rs deleted file mode 100644 index f9f75a0..0000000 --- a/src/unchecked_unwrap.rs +++ /dev/null @@ -1,62 +0,0 @@ -use core::hint::unreachable_unchecked; - -/// An extension trait for `Option` providing unchecked unwrapping. -pub trait UncheckedOptionExt { - /// Unwraps an `Option`, yielding the content of a [`Some`][]. - /// - /// # Safety - /// - /// The `Option` has to be `Some` - unsafe fn unwrap_unchecked(self) -> T; - - /// Unwraps an `Option`, expecting [`None`][] and returning nothing. - /// - /// # Safety - /// - /// The `Option` has to be `None`. - unsafe fn unwrap_none_unchecked(self); -} - -/// An extension trait for `Result` providing unchecked unwrapping. -pub trait UncheckedResultExt { - /// Unwraps a `Result`, yielding the content of an [`Ok`][]. - /// - /// # Safety - /// - /// The `Result` has to be `Ok` - unsafe fn unwrap_unchecked(self) -> T; - - /// Unwraps a `Result`, yielding the content of an [`Err`][]. - /// - /// # Safety - /// - /// The `Result` has to be `Err`. - unsafe fn unwrap_err_unchecked(self) -> E; -} - -unsafe fn unreachable() -> ! { - debug_assert!(false); - unreachable_unchecked() -} - -impl UncheckedOptionExt for Option { - unsafe fn unwrap_unchecked(self) -> T { - if let Some(t) = self { t } else { unreachable() } - } - - unsafe fn unwrap_none_unchecked(self) { - if self.is_some() { - unreachable() - } - } -} - -impl UncheckedResultExt for Result { - unsafe fn unwrap_unchecked(self) -> T { - if let Ok(t) = self { t } else { unreachable() } - } - - unsafe fn unwrap_err_unchecked(self) -> E { - if let Err(t) = self { t } else { unreachable() } - } -} diff --git a/src/vec.rs b/src/vec.rs index 50b7b45..e8e262b 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -69,7 +69,7 @@ //! [`vec!`]: ../macro.vec.html use crate::{ - alloc::{handle_alloc_error, AllocRef, BuildAllocRef, DeallocRef, Global, ReallocRef}, + alloc::{AbortAlloc, AllocRef, BuildAllocRef, DeallocRef, Global, Panic, ReallocRef}, boxed::Box, clone::CloneIn, collections::CollectionAllocErr, @@ -328,7 +328,7 @@ use core::{ /// [`insert`]: Self::insert() /// [`reserve`]: Self::reserve /// [owned slice]: crate::boxed::Box -pub struct Vec { +pub struct Vec> { buf: RawVec, len: usize, } @@ -401,7 +401,7 @@ impl Vec { #[inline] #[must_use] pub fn with_capacity(capacity: usize) -> Self { - Self::with_capacity_in(capacity, Global) + Self::with_capacity_in(capacity, AbortAlloc(Global)) } /// Creates a `Vec` directly from the raw components of another vector. @@ -490,7 +490,7 @@ impl Vec { #[inline] pub fn with_capacity_in(capacity: usize, a: A) -> Self where - A: AllocRef, + A: AllocRef, { Self { buf: RawVec::with_capacity_in(capacity, a), @@ -612,7 +612,7 @@ impl Vec { /// Panics if the reallocation fails. pub fn reserve(&mut self, additional: usize) where - A: ReallocRef, + A: ReallocRef, { self.buf.reserve(self.len, additional); } @@ -645,7 +645,7 @@ impl Vec { /// Panics if the reallocation fails. pub fn reserve_exact(&mut self, additional: usize) where - A: ReallocRef, + A: ReallocRef, { self.buf.reserve_exact(self.len, additional); } @@ -664,9 +664,13 @@ impl Vec { /// # Examples /// /// ``` - /// use alloc_wg::{alloc::Global, collections::CollectionAllocErr, vec::Vec}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// collections::CollectionAllocErr, + /// vec::Vec, + /// }; /// - /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr>> { /// let mut output = Vec::new(); /// /// // Pre-reserve the memory, exiting if we can't @@ -705,9 +709,13 @@ impl Vec { /// # Examples /// /// ``` - /// use alloc_wg::{alloc::Global, collections::CollectionAllocErr, vec::Vec}; + /// use alloc_wg::{ + /// alloc::{AbortAlloc, Global}, + /// collections::CollectionAllocErr, + /// vec::Vec, + /// }; /// - /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr>> { /// let mut output = Vec::new(); /// /// // Pre-reserve the memory, exiting if we can't @@ -751,7 +759,7 @@ impl Vec { /// Panics if the reallocation fails. pub fn shrink_to_fit(&mut self) where - A: ReallocRef, + A: ReallocRef, { if self.capacity() != self.len { self.buf.shrink_to_fit(self.len); @@ -797,7 +805,7 @@ impl Vec { /// * Panics if the reallocation fails. pub fn shrink_to(&mut self, min_capacity: usize) where - A: ReallocRef, + A: ReallocRef, { self.buf.shrink_to_fit(cmp::max(self.len, min_capacity)); } @@ -844,12 +852,13 @@ impl Vec { /// Panics if the reallocation fails. pub fn into_boxed_slice(self) -> Box<[T], A> where - A: ReallocRef, + A: ReallocRef, { match self.try_into_boxed_slice() { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1188,12 +1197,13 @@ impl Vec { /// ``` pub fn insert(&mut self, index: usize, element: T) where - A: ReallocRef, + A: ReallocRef, { match self.try_insert(index, element) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1294,7 +1304,7 @@ impl Vec { pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool, - A: ReallocRef, + A: ReallocRef, { self.drain_filter(|x| !f(x)); } @@ -1377,12 +1387,13 @@ impl Vec { #[inline] pub fn push(&mut self, value: T) where - A: ReallocRef, + A: ReallocRef, { match self.try_push(value) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1462,12 +1473,13 @@ impl Vec { #[inline] pub fn append(&mut self, other: &mut Self) where - A: ReallocRef, + A: ReallocRef, { match self.try_append(other) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1647,12 +1659,13 @@ impl Vec { #[inline] pub fn split_off(&mut self, at: usize) -> Self where - A: AllocRef, + A: AllocRef, { match self.try_split_off(at) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1717,12 +1730,13 @@ impl Vec { pub fn resize_with(&mut self, new_len: usize, f: F) where F: FnMut() -> T, - A: ReallocRef, + A: ReallocRef, { match self.try_resize_with(new_len, f) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1771,7 +1785,7 @@ impl Vec { pub fn leak<'a>(vec: Self) -> &'a mut [T] where T: 'a, // Technically not needed, but kept to be explicit. - A: ReallocRef, + A: ReallocRef, { Box::leak(vec.into_boxed_slice()) } @@ -1818,11 +1832,15 @@ impl Vec { /// # Panics /// /// Panics if the reallocation fails. - pub fn resize(&mut self, new_len: usize, value: T) { + pub fn resize(&mut self, new_len: usize, value: T) + where + A: ReallocRef, + { match self.try_resize(new_len, value) { Ok(_) => (), Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -1862,8 +1880,11 @@ impl Vec { /// # Panics /// /// Panics if the reallocation fails. - pub fn extend_from_slice(&mut self, other: &[T]) { - self.spec_extend(other.iter()) + pub fn extend_from_slice(&mut self, other: &[T]) + where + A: ReallocRef, + { + self.spec_extend(other.iter().cloned()) } /// Same as `extend_from_slice` but returns errors instead of panicking @@ -2024,18 +2045,19 @@ impl Vec { #[doc(hidden)] pub fn from_elem(elem: T, n: usize) -> Vec { - from_elem_in(elem, n, Global) + from_elem_in(elem, n, AbortAlloc(Global)) } #[doc(hidden)] pub fn from_elem_in(elem: T, n: usize, a: A) -> Vec where - A: ReallocRef, + A: ReallocRef, { match try_from_elem_in(elem, n, a) { Ok(vec) => vec, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -2177,7 +2199,7 @@ unsafe impl IsZero for Option> { // Common trait implementations for Vec //////////////////////////////////////////////////////////////////////////////// -impl Clone for Vec +impl> Clone for Vec where A: AllocRef, A::BuildAlloc: Clone, @@ -2200,12 +2222,11 @@ where impl CloneIn for Vec { type Cloned = Vec; - fn clone_in(&self, a: B) -> Self::Cloned { - let mut v = Vec::with_capacity_in(self.len(), a); - - self.iter() - .cloned() - .for_each(|element| unsafe { v.push_unchecked(element) }); + fn clone_in(&self, a: B) -> Self::Cloned + where + B: AllocRef, + { + let Ok(v) = self.try_clone_in(a); v } @@ -2267,14 +2288,20 @@ impl FromIterator for Vec { #[inline] #[must_use] fn from_iter>(iter: I) -> Self { - >::from_iter_in(iter.into_iter(), Global) + >>::from_iter_in( + iter.into_iter(), + AbortAlloc(Global), + ) } } impl FromIteratorIn for Vec { #[inline] #[must_use] - fn from_iter_in>(iter: I, a: A) -> Self { + fn from_iter_in>(iter: I, a: A) -> Self + where + A: AllocRef, + { >::from_iter_in(iter.into_iter(), a) } @@ -2349,7 +2376,7 @@ impl<'a, T, A: DeallocRef> IntoIterator for &'a mut Vec { impl Extend for Vec where - A: ReallocRef, + A: ReallocRef, { #[inline] fn extend>(&mut self, iter: I) { @@ -2368,22 +2395,30 @@ impl TryExtend for Vec { trait SpecExtend: Sized { #[inline] - fn from_iter_in(iter: I, a: A) -> Self { + fn from_iter_in(iter: I, a: A) -> Self + where + A: AllocRef, + { match Self::try_from_iter_in(iter, a) { Ok(v) => v, Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } fn try_from_iter_in(iter: I, a: A) -> Result>; #[inline] - fn spec_extend(&mut self, iter: I) { + fn spec_extend(&mut self, iter: I) + where + A: AllocRef, + { match self.try_spec_extend(iter) { Ok(_) => (), Err(CollectionAllocErr::CapacityOverflow) => capacity_overflow(), - Err(CollectionAllocErr::AllocError { layout, .. }) => handle_alloc_error(layout.into()), + #[allow(unreachable_patterns)] // TODO rustc bug? + Err(CollectionAllocErr::AllocError { inner: e, .. }) => e, } } @@ -2590,7 +2625,7 @@ impl Vec { #[inline] pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A> where - A: ReallocRef, + A: ReallocRef, R: RangeBounds, I: IntoIterator, { @@ -2649,7 +2684,7 @@ impl Vec { /// ``` pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> where - A: ReallocRef, + A: ReallocRef, F: FnMut(&mut T) -> bool, { let old_len = self.len(); @@ -2678,7 +2713,7 @@ impl Vec { /// [`copy_from_slice`]: ../../std/primitive.slice.html#method.copy_from_slice impl<'a, T: 'a + Copy, A> Extend<&'a T> for Vec where - A: ReallocRef, + A: ReallocRef, { fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()) @@ -2896,7 +2931,7 @@ impl From<&str> for Vec { /// /// [`Vec`]: struct.Vec.html /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html -pub struct IntoIter { +pub struct IntoIter> { buf: RawVec, ptr: *const T, end: *const T, @@ -3042,7 +3077,7 @@ impl Drop for IntoIter { /// /// [`drain`]: struct.Vec.html#method.drain /// [`Vec`]: struct.Vec.html -pub struct Drain<'a, T, A: DeallocRef = Global> { +pub struct Drain<'a, T, A: DeallocRef = AbortAlloc> { /// Index of tail to preserve tail_start: usize, /// Length of tail @@ -3135,9 +3170,9 @@ impl FusedIterator for Drain<'_, T, A> {} /// [`splice()`]: struct.Vec.html#method.splice /// [`Vec`]: struct.Vec.html #[derive(Debug)] -pub struct Splice<'a, I: Iterator + 'a, A = Global> +pub struct Splice<'a, I: Iterator + 'a, A = AbortAlloc> where - A: ReallocRef, + A: ReallocRef, // Because Drop can allocate { drain: Drain<'a, I::Item, A>, replace_with: I, @@ -3145,7 +3180,7 @@ where impl Iterator for Splice<'_, I, A> where - A: ReallocRef, + A: ReallocRef, { type Item = I::Item; @@ -3160,18 +3195,18 @@ where impl DoubleEndedIterator for Splice<'_, I, A> where - A: ReallocRef, + A: ReallocRef, { fn next_back(&mut self) -> Option { self.drain.next_back() } } -impl ExactSizeIterator for Splice<'_, I, A> where A: ReallocRef {} +impl ExactSizeIterator for Splice<'_, I, A> where A: ReallocRef {} impl Drop for Splice<'_, I, A> where - A: ReallocRef, + A: ReallocRef, { fn drop(&mut self) { self.drain.by_ref().for_each(drop); @@ -3217,7 +3252,7 @@ where /// Private helper methods for `Splice::drop` impl Drain<'_, T, A> where - A: ReallocRef, + A: ReallocRef, { /// The range from `self.vec.len` to `self.tail_start` contains elements /// that have been moved out. @@ -3257,7 +3292,7 @@ where /// An iterator produced by calling `drain_filter` on Vec. // #[derive(Debug)] -pub struct DrainFilter<'a, T, F, A: DeallocRef = Global> +pub struct DrainFilter<'a, T, F, A: DeallocRef = AbortAlloc> where F: FnMut(&mut T) -> bool, { @@ -3320,7 +3355,7 @@ where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - struct BackshiftOnDrop<'a, 'b, T, F, A: DeallocRef = Global> + struct BackshiftOnDrop<'a, 'b, T, F, A: DeallocRef = AbortAlloc> where F: FnMut(&mut T) -> bool, { diff --git a/tests/string.rs b/tests/string.rs index d43ac4e..7fc5731 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -1,4 +1,11 @@ -use alloc_wg::{borrow::Cow, collections::CollectionAllocErr::*, string::String, vec, vec::Vec}; +use alloc_wg::{ + alloc::Global, + borrow::Cow, + collections::CollectionAllocErr::*, + string::String, + vec, + vec::Vec, +}; use core::{isize, mem::size_of, usize}; pub trait IntoCow<'a, B: ?Sized> @@ -576,7 +583,7 @@ fn test_try_reserve() { { // Note: basic stuff is checked by test_reserve - let mut empty_string = String::new(); + let mut empty_string = String::new_in(Global); // Check isize::MAX doesn't count as an overflow if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) { @@ -616,7 +623,10 @@ fn test_try_reserve() { { // Same basic idea, but with non-zero len - let mut ten_bytes = String::from("0123456789"); + let mut ten_bytes = String::new_in(Global); + ten_bytes + .try_push_str("0123456789") + .expect("Could not create string with 10 bytes"); if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -655,7 +665,7 @@ fn test_try_reserve_exact() { let guards_against_isize = size_of::() < 8; { - let mut empty_string = String::new(); + let mut empty_string = String::new_in(Global); if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -688,7 +698,10 @@ fn test_try_reserve_exact() { } { - let mut ten_bytes = String::from("0123456789"); + let mut ten_bytes = String::new_in(Global); + ten_bytes + .try_push_str("0123456789") + .expect("Could not create string with 10 bytes"); if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); diff --git a/tests/vec.rs b/tests/vec.rs index 0cb43b6..ec4d189 100644 --- a/tests/vec.rs +++ b/tests/vec.rs @@ -1,4 +1,5 @@ use alloc_wg::{ + alloc::Global, boxed::Box, collections::CollectionAllocErr::*, vec, @@ -1125,7 +1126,7 @@ fn test_try_reserve() { { // Note: basic stuff is checked by test_reserve - let mut empty_bytes: Vec = Vec::new(); + let mut empty_bytes: Vec = Vec::new_in(Global); // Check isize::MAX doesn't count as an overflow if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) { @@ -1163,7 +1164,8 @@ fn test_try_reserve() { { // Same basic idea, but with non-zero len - let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let mut ten_bytes: Vec = vec![try in Global; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .expect("Unable to allocate ten bytes"); if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -1188,7 +1190,8 @@ fn test_try_reserve() { { // Same basic idea, but with interesting type size - let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let mut ten_u32s: Vec = vec![try in Global; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .expect("Unable to allocate 40 bytes"); if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -1225,7 +1228,7 @@ fn test_try_reserve_exact() { let guards_against_isize = size_of::() < 8; { - let mut empty_bytes: Vec = Vec::new(); + let mut empty_bytes: Vec = Vec::new_in(Global); if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -1256,7 +1259,8 @@ fn test_try_reserve_exact() { } { - let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let mut ten_bytes: Vec = vec![try in Global; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .expect("Unable to allocate ten bytes"); if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); @@ -1279,7 +1283,8 @@ fn test_try_reserve_exact() { } { - let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let mut ten_u32s: Vec = vec![try in Global; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .expect("Unable to allocate 40 bytes"); if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!");