fallacy_alloc/
lib.rs

1//! Fallible allocation.
2
3#![cfg_attr(nightly, feature(try_reserve_kind))]
4
5use std::alloc::Layout;
6use std::collections::TryReserveError;
7use std::error::Error;
8use std::fmt;
9
10/// The error type for allocation failure.
11#[derive(Debug, Copy, Clone)]
12#[repr(transparent)]
13pub struct AllocError(Layout);
14
15impl AllocError {
16    /// Creates a new `AllocError`.
17    ///
18    /// If the size of `layout` is zero, it means we do not know what the size is.
19    #[must_use]
20    #[inline]
21    pub const fn new(layout: Layout) -> Self {
22        AllocError(layout)
23    }
24
25    /// Returns the memory layout of the `AllocError`.
26    #[must_use]
27    #[inline]
28    pub const fn layout(self) -> Layout {
29        self.0
30    }
31}
32
33impl Error for AllocError {}
34
35impl fmt::Display for AllocError {
36    #[inline]
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        if self.layout().size() != 0 {
39            write!(
40                f,
41                "failed to allocate memory by required layout {{size: {}, align: {}}}",
42                self.0.size(),
43                self.0.align()
44            )
45        } else {
46            write!(f, "failed to allocate memory")
47        }
48    }
49}
50
51#[cfg(not(nightly))]
52impl From<TryReserveError> for AllocError {
53    #[inline]
54    fn from(_e: TryReserveError) -> Self {
55        AllocError::new(unsafe { Layout::from_size_align_unchecked(0, 1) })
56    }
57}
58
59#[cfg(nightly)]
60impl From<TryReserveError> for AllocError {
61    #[inline]
62    fn from(e: TryReserveError) -> Self {
63        use std::collections::TryReserveErrorKind;
64        match e.kind() {
65            TryReserveErrorKind::AllocError { layout, .. } => AllocError::new(layout),
66            TryReserveErrorKind::CapacityOverflow => {
67                unreachable!("unexpected capacity overflow")
68            }
69        }
70    }
71}