1use {
2 crate::{Layout, data::type_props::SizedProps},
3 core::fmt::{Debug, Display, Formatter, Result as FmtResult}
4};
5
6macro_rules! impl_error {
9 ($ty:ident) => {
10 #[cfg(feature = "std")]
11 impl std::error::Error for $ty {}
12 #[cfg(not(feature = "std"))]
13 #[rustversion::since(1.81)]
15 impl core::error::Error for $ty {}
16 };
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21#[repr(u8)]
22pub enum Error {
23 AllocFailed(Layout, Cause),
27 InvalidLayout(usize, usize, LayoutErr),
29 ZeroSizedLayout,
35 DanglingDeallocation,
37 GrowSmallerNewLayout(usize, usize),
39 ShrinkLargerNewLayout(usize, usize),
41 ArithmeticError(ArithErr),
43 #[allow(unused_qualifications)]
45 CaughtUnwind,
46 Other(&'static str)
48}
49
50impl Display for Error {
51 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
52 use Error::{
53 AllocFailed,
54 ArithmeticError,
55 CaughtUnwind,
56 DanglingDeallocation,
57 GrowSmallerNewLayout,
58 InvalidLayout,
59 Other,
60 ShrinkLargerNewLayout,
61 ZeroSizedLayout
62 };
63
64 match self {
65 AllocFailed(l, cause) => write!(
66 f,
67 "allocation failed:\n\tlayout:\n\t\tsize: {}\n\t\talign: {}\n\tcause: {}",
68 l.size(),
69 l.align(),
70 cause
71 ),
72 InvalidLayout(sz, aln, e) => write!(
73 f,
74 "computed invalid layout:\n\tsize: {}\n\talign: {}\n\treason: {}",
75 sz, aln, e
76 ),
77 ZeroSizedLayout => {
78 write!(f, "received a zero-sized layout")
79 }
80 DanglingDeallocation => write!(f, "attempted to deallocate a dangling pointer"),
81 GrowSmallerNewLayout(old, new) => {
82 write!(f, "attempted to grow from a size of {} to a smaller size of {}", old, new)
83 }
84 ShrinkLargerNewLayout(old, new) => {
85 write!(f, "attempted to shrink from a size of {} to a larger size of {}", old, new)
86 }
87 ArithmeticError(overflow) => write!(f, "{}", overflow),
88 CaughtUnwind => {
89 write!(f, "unwind caught in unsupported function")
90 }
91 Other(other) => write!(f, "{}", other)
92 }
93 }
94}
95
96impl_error! { Error }
97
98#[derive(Debug, Copy, Clone, PartialEq, Eq)]
100#[repr(u8)]
101pub enum Cause {
102 Unknown,
107 OutOfMemory,
112 Other(&'static str),
114 #[cfg(feature = "os_err_reporting")]
115 OSErr(i32)
119}
120
121impl Display for Cause {
122 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
123 match self {
124 Cause::Unknown => write!(f, "unknown"),
125 Cause::OutOfMemory => write!(f, "out of memory"),
126 Cause::Other(other) => write!(f, "{}", other),
127 #[cfg(feature = "os_err_reporting")]
128 Cause::OSErr(e) => write!(f, "os error:\n\t{}", std::io::Error::from_raw_os_error(*e))
129 }
130 }
131}
132
133impl_error! { Cause }
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137#[repr(u8)]
138pub enum LayoutErr {
139 ZeroAlign,
141 NonPowerOfTwoAlign,
143 ExceedsMax,
147 ArithErr(ArithErr),
149 CRoundUp
152}
153
154impl Display for LayoutErr {
155 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
156 match self {
157 LayoutErr::ZeroAlign => write!(f, "alignment is zero"),
158 LayoutErr::NonPowerOfTwoAlign => {
159 write!(f, "alignment isn't a power of two")
160 }
161 LayoutErr::ExceedsMax => write!(f, "size would overflow when rounded up to alignment"),
162 LayoutErr::ArithErr(overflow) => write!(f, "layout err: {}", overflow),
163 LayoutErr::CRoundUp => {
164 write!(f, "failed to round layout alignment up to a multiple of {}", usize::SZ)
165 }
166 }
167 }
168}
169
170impl_error! { LayoutErr }
171
172#[derive(Debug, Copy, Clone, PartialEq, Eq)]
177pub struct ArithErr(pub usize, pub ArithOp, pub usize);
178
179impl Display for ArithErr {
180 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
181 write!(f, "arithmetic operation would overflow: {} {} {}", self.0, self.1, self.2)
182 }
183}
184
185impl_error! { ArithErr }
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
189#[repr(u8)]
190pub enum ArithOp {
191 Add,
193 Sub,
195 Mul,
197 Div,
199 Rem,
201 Pow
203}
204
205impl Display for ArithOp {
206 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
207 match self {
208 ArithOp::Add => write!(f, "+"),
209 ArithOp::Sub => write!(f, "-"),
210 ArithOp::Mul => write!(f, "*"),
211 ArithOp::Div => write!(f, "/"),
212 ArithOp::Rem => write!(f, "%"),
213 ArithOp::Pow => write!(f, "**")
214 }
215 }
216}