1 //! Low-level allocation and OOM-handling utilities. 2 3 mod arc; 4 mod boxed; 5 mod try_new; 6 mod vec; 7 8 pub use boxed::{ 9 BoxedSliceFromFallibleIterError, TooFewItemsOrOom, boxed_slice_write_iter, 10 new_boxed_slice_from_fallible_iter, new_boxed_slice_from_iter, 11 new_boxed_slice_from_iter_with_len, new_uninit_boxed_slice, 12 }; 13 pub use try_new::{TryNew, try_new}; 14 pub use vec::Vec; 15 16 use crate::error::OutOfMemory; 17 use core::{alloc::Layout, ptr::NonNull}; 18 19 /// Try to allocate a block of memory that fits the given layout, or return an 20 /// `OutOfMemory` error. 21 /// 22 /// # Safety 23 /// 24 /// Same as `alloc::alloc::alloc`: layout must have non-zero size. 25 #[inline] 26 unsafe fn try_alloc(layout: Layout) -> Result<NonNull<u8>, OutOfMemory> { 27 // Safety: same as our safety conditions. 28 debug_assert!(layout.size() > 0); 29 let ptr = unsafe { std_alloc::alloc::alloc(layout) }; 30 31 if let Some(ptr) = NonNull::new(ptr) { 32 Ok(ptr) 33 } else { 34 Err(OutOfMemory::new(layout.size())) 35 } 36 } 37 38 /// An extension trait for ignoring `OutOfMemory` errors. 39 /// 40 /// Use this to unwrap a `Result<T, OutOfMemory>` into its inner `T` or 41 /// otherwise panic, leveraging the type system to be sure that you aren't ever 42 /// accidentally unwrapping non-`OutOfMemory` errors. 43 pub trait PanicOnOom { 44 /// The non-`OutOfMemory` result of calling `panic_on_oom`. 45 type Result; 46 47 /// Panic on `OutOfMemory` errors, returning the non-`OutOfMemory` result. 48 fn panic_on_oom(self) -> Self::Result; 49 } 50 51 impl<T> PanicOnOom for Result<T, OutOfMemory> { 52 type Result = T; 53 54 #[track_caller] 55 fn panic_on_oom(self) -> Self::Result { 56 match self { 57 Ok(x) => x, 58 Err(oom) => panic!("unhandled out-of-memory error: {oom}"), 59 } 60 } 61 } 62