/rust/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.95/src/error.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::backtrace::Backtrace; |
2 | | use crate::chain::Chain; |
3 | | #[cfg(any(feature = "std", not(anyhow_no_core_error), anyhow_no_ptr_addr_of))] |
4 | | use crate::ptr::Mut; |
5 | | use crate::ptr::{Own, Ref}; |
6 | | use crate::{Error, StdError}; |
7 | | use alloc::boxed::Box; |
8 | | use core::any::TypeId; |
9 | | #[cfg(error_generic_member_access)] |
10 | | use core::error::{self, Request}; |
11 | | use core::fmt::{self, Debug, Display}; |
12 | | use core::mem::ManuallyDrop; |
13 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
14 | | use core::ops::{Deref, DerefMut}; |
15 | | #[cfg(not(anyhow_no_core_unwind_safe))] |
16 | | use core::panic::{RefUnwindSafe, UnwindSafe}; |
17 | | #[cfg(not(anyhow_no_ptr_addr_of))] |
18 | | use core::ptr; |
19 | | use core::ptr::NonNull; |
20 | | #[cfg(all(feature = "std", anyhow_no_core_unwind_safe))] |
21 | | use std::panic::{RefUnwindSafe, UnwindSafe}; |
22 | | |
23 | | impl Error { |
24 | | /// Create a new error object from any error type. |
25 | | /// |
26 | | /// The error type must be threadsafe and `'static`, so that the `Error` |
27 | | /// will be as well. |
28 | | /// |
29 | | /// If the error type does not provide a backtrace, a backtrace will be |
30 | | /// created here to ensure that a backtrace exists. |
31 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
32 | | #[cold] |
33 | | #[must_use] |
34 | 0 | pub fn new<E>(error: E) -> Self |
35 | 0 | where |
36 | 0 | E: StdError + Send + Sync + 'static, |
37 | 0 | { |
38 | 0 | let backtrace = backtrace_if_absent!(&error); |
39 | 0 | Error::construct_from_std(error, backtrace) |
40 | 0 | } |
41 | | |
42 | | /// Create a new error object from a printable error message. |
43 | | /// |
44 | | /// If the argument implements std::error::Error, prefer `Error::new` |
45 | | /// instead which preserves the underlying error's cause chain and |
46 | | /// backtrace. If the argument may or may not implement std::error::Error |
47 | | /// now or in the future, use `anyhow!(err)` which handles either way |
48 | | /// correctly. |
49 | | /// |
50 | | /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally |
51 | | /// convenient in places where a function is preferable over a macro, such |
52 | | /// as iterator or stream combinators: |
53 | | /// |
54 | | /// ``` |
55 | | /// # mod ffi { |
56 | | /// # pub struct Input; |
57 | | /// # pub struct Output; |
58 | | /// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> { |
59 | | /// # unimplemented!() |
60 | | /// # } |
61 | | /// # } |
62 | | /// # |
63 | | /// # use ffi::{Input, Output}; |
64 | | /// # |
65 | | /// use anyhow::{Error, Result}; |
66 | | /// use futures::stream::{Stream, StreamExt, TryStreamExt}; |
67 | | /// |
68 | | /// async fn demo<S>(stream: S) -> Result<Vec<Output>> |
69 | | /// where |
70 | | /// S: Stream<Item = Input>, |
71 | | /// { |
72 | | /// stream |
73 | | /// .then(ffi::do_some_work) // returns Result<Output, &str> |
74 | | /// .map_err(Error::msg) |
75 | | /// .try_collect() |
76 | | /// .await |
77 | | /// } |
78 | | /// ``` |
79 | | #[cold] |
80 | | #[must_use] |
81 | 1.33M | pub fn msg<M>(message: M) -> Self |
82 | 1.33M | where |
83 | 1.33M | M: Display + Debug + Send + Sync + 'static, |
84 | 1.33M | { |
85 | 1.33M | Error::construct_from_adhoc(message, backtrace!()) |
86 | 1.33M | } Unexecuted instantiation: <anyhow::Error>::msg::<alloc::string::String> <anyhow::Error>::msg::<&str> Line | Count | Source | 81 | 1.33M | pub fn msg<M>(message: M) -> Self | 82 | 1.33M | where | 83 | 1.33M | M: Display + Debug + Send + Sync + 'static, | 84 | 1.33M | { | 85 | 1.33M | Error::construct_from_adhoc(message, backtrace!()) | 86 | 1.33M | } |
|
87 | | |
88 | | /// Construct an error object from a type-erased standard library error. |
89 | | /// |
90 | | /// This is mostly useful for interop with other error libraries. |
91 | | /// |
92 | | /// # Example |
93 | | /// |
94 | | /// Here is a skeleton of a library that provides its own error abstraction. |
95 | | /// The pair of `From` impls provide bidirectional support for `?` |
96 | | /// conversion between `Report` and `anyhow::Error`. |
97 | | /// |
98 | | /// ``` |
99 | | /// use std::error::Error as StdError; |
100 | | /// |
101 | | /// pub struct Report {/* ... */} |
102 | | /// |
103 | | /// impl<E> From<E> for Report |
104 | | /// where |
105 | | /// E: Into<anyhow::Error>, |
106 | | /// Result<(), E>: anyhow::Context<(), E>, |
107 | | /// { |
108 | | /// fn from(error: E) -> Self { |
109 | | /// let anyhow_error: anyhow::Error = error.into(); |
110 | | /// let boxed_error: Box<dyn StdError + Send + Sync + 'static> = anyhow_error.into(); |
111 | | /// Report::from_boxed(boxed_error) |
112 | | /// } |
113 | | /// } |
114 | | /// |
115 | | /// impl From<Report> for anyhow::Error { |
116 | | /// fn from(report: Report) -> Self { |
117 | | /// let boxed_error: Box<dyn StdError + Send + Sync + 'static> = report.into_boxed(); |
118 | | /// anyhow::Error::from_boxed(boxed_error) |
119 | | /// } |
120 | | /// } |
121 | | /// |
122 | | /// impl Report { |
123 | | /// fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self { |
124 | | /// todo!() |
125 | | /// } |
126 | | /// fn into_boxed(self) -> Box<dyn StdError + Send + Sync + 'static> { |
127 | | /// todo!() |
128 | | /// } |
129 | | /// } |
130 | | /// |
131 | | /// // Example usage: can use `?` in both directions. |
132 | | /// fn a() -> anyhow::Result<()> { |
133 | | /// b()?; |
134 | | /// Ok(()) |
135 | | /// } |
136 | | /// fn b() -> Result<(), Report> { |
137 | | /// a()?; |
138 | | /// Ok(()) |
139 | | /// } |
140 | | /// ``` |
141 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
142 | | #[cold] |
143 | | #[must_use] |
144 | 0 | pub fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self { |
145 | 0 | let backtrace = backtrace_if_absent!(&*boxed_error); |
146 | 0 | Error::construct_from_boxed(boxed_error, backtrace) |
147 | 0 | } |
148 | | |
149 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
150 | | #[cold] |
151 | 0 | pub(crate) fn construct_from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self |
152 | 0 | where |
153 | 0 | E: StdError + Send + Sync + 'static, |
154 | 0 | { |
155 | 0 | let vtable = &ErrorVTable { |
156 | 0 | object_drop: object_drop::<E>, |
157 | 0 | object_ref: object_ref::<E>, |
158 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
159 | 0 | object_mut: object_mut::<E>, |
160 | 0 | object_boxed: object_boxed::<E>, |
161 | 0 | object_downcast: object_downcast::<E>, |
162 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
163 | 0 | object_downcast_mut: object_downcast_mut::<E>, |
164 | 0 | object_drop_rest: object_drop_front::<E>, |
165 | 0 | #[cfg(all( |
166 | 0 | not(error_generic_member_access), |
167 | 0 | any(std_backtrace, feature = "backtrace") |
168 | 0 | ))] |
169 | 0 | object_backtrace: no_backtrace, |
170 | 0 | }; |
171 | 0 |
|
172 | 0 | // Safety: passing vtable that operates on the right type E. |
173 | 0 | unsafe { Error::construct(error, vtable, backtrace) } |
174 | 0 | } Unexecuted instantiation: <anyhow::Error>::construct_from_std::<quick_xml::errors::Error> Unexecuted instantiation: <anyhow::Error>::construct_from_std::<quick_xml::escapei::EscapeError> Unexecuted instantiation: <anyhow::Error>::construct_from_std::<core::num::error::ParseIntError> Unexecuted instantiation: <anyhow::Error>::construct_from_std::<_> |
175 | | |
176 | | #[cold] |
177 | 1.33M | pub(crate) fn construct_from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self |
178 | 1.33M | where |
179 | 1.33M | M: Display + Debug + Send + Sync + 'static, |
180 | 1.33M | { |
181 | | use crate::wrapper::MessageError; |
182 | 1.33M | let error: MessageError<M> = MessageError(message); |
183 | 1.33M | let vtable = &ErrorVTable { |
184 | 1.33M | object_drop: object_drop::<MessageError<M>>, |
185 | 1.33M | object_ref: object_ref::<MessageError<M>>, |
186 | 1.33M | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
187 | 1.33M | object_mut: object_mut::<MessageError<M>>, |
188 | 1.33M | object_boxed: object_boxed::<MessageError<M>>, |
189 | 1.33M | object_downcast: object_downcast::<M>, |
190 | 1.33M | #[cfg(anyhow_no_ptr_addr_of)] |
191 | 1.33M | object_downcast_mut: object_downcast_mut::<M>, |
192 | 1.33M | object_drop_rest: object_drop_front::<M>, |
193 | 1.33M | #[cfg(all( |
194 | 1.33M | not(error_generic_member_access), |
195 | 1.33M | any(std_backtrace, feature = "backtrace") |
196 | 1.33M | ))] |
197 | 1.33M | object_backtrace: no_backtrace, |
198 | 1.33M | }; |
199 | 1.33M | |
200 | 1.33M | // Safety: MessageError is repr(transparent) so it is okay for the |
201 | 1.33M | // vtable to allow casting the MessageError<M> to M. |
202 | 1.33M | unsafe { Error::construct(error, vtable, backtrace) } |
203 | 1.33M | } Unexecuted instantiation: <anyhow::Error>::construct_from_adhoc::<alloc::string::String> <anyhow::Error>::construct_from_adhoc::<&str> Line | Count | Source | 177 | 1.33M | pub(crate) fn construct_from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self | 178 | 1.33M | where | 179 | 1.33M | M: Display + Debug + Send + Sync + 'static, | 180 | 1.33M | { | 181 | | use crate::wrapper::MessageError; | 182 | 1.33M | let error: MessageError<M> = MessageError(message); | 183 | 1.33M | let vtable = &ErrorVTable { | 184 | 1.33M | object_drop: object_drop::<MessageError<M>>, | 185 | 1.33M | object_ref: object_ref::<MessageError<M>>, | 186 | 1.33M | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] | 187 | 1.33M | object_mut: object_mut::<MessageError<M>>, | 188 | 1.33M | object_boxed: object_boxed::<MessageError<M>>, | 189 | 1.33M | object_downcast: object_downcast::<M>, | 190 | 1.33M | #[cfg(anyhow_no_ptr_addr_of)] | 191 | 1.33M | object_downcast_mut: object_downcast_mut::<M>, | 192 | 1.33M | object_drop_rest: object_drop_front::<M>, | 193 | 1.33M | #[cfg(all( | 194 | 1.33M | not(error_generic_member_access), | 195 | 1.33M | any(std_backtrace, feature = "backtrace") | 196 | 1.33M | ))] | 197 | 1.33M | object_backtrace: no_backtrace, | 198 | 1.33M | }; | 199 | 1.33M | | 200 | 1.33M | // Safety: MessageError is repr(transparent) so it is okay for the | 201 | 1.33M | // vtable to allow casting the MessageError<M> to M. | 202 | 1.33M | unsafe { Error::construct(error, vtable, backtrace) } | 203 | 1.33M | } |
|
204 | | |
205 | | #[cold] |
206 | 0 | pub(crate) fn construct_from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self |
207 | 0 | where |
208 | 0 | M: Display + Send + Sync + 'static, |
209 | 0 | { |
210 | | use crate::wrapper::DisplayError; |
211 | 0 | let error: DisplayError<M> = DisplayError(message); |
212 | 0 | let vtable = &ErrorVTable { |
213 | 0 | object_drop: object_drop::<DisplayError<M>>, |
214 | 0 | object_ref: object_ref::<DisplayError<M>>, |
215 | 0 | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
216 | 0 | object_mut: object_mut::<DisplayError<M>>, |
217 | 0 | object_boxed: object_boxed::<DisplayError<M>>, |
218 | 0 | object_downcast: object_downcast::<M>, |
219 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
220 | 0 | object_downcast_mut: object_downcast_mut::<M>, |
221 | 0 | object_drop_rest: object_drop_front::<M>, |
222 | 0 | #[cfg(all( |
223 | 0 | not(error_generic_member_access), |
224 | 0 | any(std_backtrace, feature = "backtrace") |
225 | 0 | ))] |
226 | 0 | object_backtrace: no_backtrace, |
227 | 0 | }; |
228 | 0 |
|
229 | 0 | // Safety: DisplayError is repr(transparent) so it is okay for the |
230 | 0 | // vtable to allow casting the DisplayError<M> to M. |
231 | 0 | unsafe { Error::construct(error, vtable, backtrace) } |
232 | 0 | } |
233 | | |
234 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
235 | | #[cold] |
236 | 0 | pub(crate) fn construct_from_context<C, E>( |
237 | 0 | context: C, |
238 | 0 | error: E, |
239 | 0 | backtrace: Option<Backtrace>, |
240 | 0 | ) -> Self |
241 | 0 | where |
242 | 0 | C: Display + Send + Sync + 'static, |
243 | 0 | E: StdError + Send + Sync + 'static, |
244 | 0 | { |
245 | 0 | let error: ContextError<C, E> = ContextError { context, error }; |
246 | 0 |
|
247 | 0 | let vtable = &ErrorVTable { |
248 | 0 | object_drop: object_drop::<ContextError<C, E>>, |
249 | 0 | object_ref: object_ref::<ContextError<C, E>>, |
250 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
251 | 0 | object_mut: object_mut::<ContextError<C, E>>, |
252 | 0 | object_boxed: object_boxed::<ContextError<C, E>>, |
253 | 0 | object_downcast: context_downcast::<C, E>, |
254 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
255 | 0 | object_downcast_mut: context_downcast_mut::<C, E>, |
256 | 0 | object_drop_rest: context_drop_rest::<C, E>, |
257 | 0 | #[cfg(all( |
258 | 0 | not(error_generic_member_access), |
259 | 0 | any(std_backtrace, feature = "backtrace") |
260 | 0 | ))] |
261 | 0 | object_backtrace: no_backtrace, |
262 | 0 | }; |
263 | 0 |
|
264 | 0 | // Safety: passing vtable that operates on the right type. |
265 | 0 | unsafe { Error::construct(error, vtable, backtrace) } |
266 | 0 | } |
267 | | |
268 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
269 | | #[cold] |
270 | 0 | pub(crate) fn construct_from_boxed( |
271 | 0 | error: Box<dyn StdError + Send + Sync>, |
272 | 0 | backtrace: Option<Backtrace>, |
273 | 0 | ) -> Self { |
274 | | use crate::wrapper::BoxedError; |
275 | 0 | let error = BoxedError(error); |
276 | 0 | let vtable = &ErrorVTable { |
277 | 0 | object_drop: object_drop::<BoxedError>, |
278 | 0 | object_ref: object_ref::<BoxedError>, |
279 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
280 | 0 | object_mut: object_mut::<BoxedError>, |
281 | 0 | object_boxed: object_boxed::<BoxedError>, |
282 | 0 | object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>, |
283 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
284 | 0 | object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>, |
285 | 0 | object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>, |
286 | 0 | #[cfg(all( |
287 | 0 | not(error_generic_member_access), |
288 | 0 | any(std_backtrace, feature = "backtrace") |
289 | 0 | ))] |
290 | 0 | object_backtrace: no_backtrace, |
291 | 0 | }; |
292 | 0 |
|
293 | 0 | // Safety: BoxedError is repr(transparent) so it is okay for the vtable |
294 | 0 | // to allow casting to Box<dyn StdError + Send + Sync>. |
295 | 0 | unsafe { Error::construct(error, vtable, backtrace) } |
296 | 0 | } |
297 | | |
298 | | // Takes backtrace as argument rather than capturing it here so that the |
299 | | // user sees one fewer layer of wrapping noise in the backtrace. |
300 | | // |
301 | | // Unsafe because the given vtable must have sensible behavior on the error |
302 | | // value of type E. |
303 | | #[cold] |
304 | 1.33M | unsafe fn construct<E>( |
305 | 1.33M | error: E, |
306 | 1.33M | vtable: &'static ErrorVTable, |
307 | 1.33M | backtrace: Option<Backtrace>, |
308 | 1.33M | ) -> Self |
309 | 1.33M | where |
310 | 1.33M | E: StdError + Send + Sync + 'static, |
311 | 1.33M | { |
312 | 1.33M | let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl { |
313 | 1.33M | vtable, |
314 | 1.33M | backtrace, |
315 | 1.33M | _object: error, |
316 | 1.33M | }); |
317 | 1.33M | // Erase the concrete type of E from the compile-time type system. This |
318 | 1.33M | // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to |
319 | 1.33M | // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the |
320 | 1.33M | // result is a thin pointer. The necessary behavior for manipulating the |
321 | 1.33M | // underlying ErrorImpl<E> is preserved in the vtable provided by the |
322 | 1.33M | // caller rather than a builtin fat pointer vtable. |
323 | 1.33M | let inner = Own::new(inner).cast::<ErrorImpl>(); |
324 | 1.33M | Error { inner } |
325 | 1.33M | } Unexecuted instantiation: <anyhow::Error>::construct::<quick_xml::errors::Error> Unexecuted instantiation: <anyhow::Error>::construct::<quick_xml::escapei::EscapeError> Unexecuted instantiation: <anyhow::Error>::construct::<core::num::error::ParseIntError> Unexecuted instantiation: <anyhow::Error>::construct::<anyhow::wrapper::MessageError<alloc::string::String>> <anyhow::Error>::construct::<anyhow::wrapper::MessageError<&str>> Line | Count | Source | 304 | 1.33M | unsafe fn construct<E>( | 305 | 1.33M | error: E, | 306 | 1.33M | vtable: &'static ErrorVTable, | 307 | 1.33M | backtrace: Option<Backtrace>, | 308 | 1.33M | ) -> Self | 309 | 1.33M | where | 310 | 1.33M | E: StdError + Send + Sync + 'static, | 311 | 1.33M | { | 312 | 1.33M | let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl { | 313 | 1.33M | vtable, | 314 | 1.33M | backtrace, | 315 | 1.33M | _object: error, | 316 | 1.33M | }); | 317 | 1.33M | // Erase the concrete type of E from the compile-time type system. This | 318 | 1.33M | // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to | 319 | 1.33M | // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the | 320 | 1.33M | // result is a thin pointer. The necessary behavior for manipulating the | 321 | 1.33M | // underlying ErrorImpl<E> is preserved in the vtable provided by the | 322 | 1.33M | // caller rather than a builtin fat pointer vtable. | 323 | 1.33M | let inner = Own::new(inner).cast::<ErrorImpl>(); | 324 | 1.33M | Error { inner } | 325 | 1.33M | } |
Unexecuted instantiation: <anyhow::Error>::construct::<anyhow::wrapper::BoxedError> |
326 | | |
327 | | /// Wrap the error value with additional context. |
328 | | /// |
329 | | /// For attaching context to a `Result` as it is propagated, the |
330 | | /// [`Context`][crate::Context] extension trait may be more convenient than |
331 | | /// this function. |
332 | | /// |
333 | | /// The primary reason to use `error.context(...)` instead of |
334 | | /// `result.context(...)` via the `Context` trait would be if the context |
335 | | /// needs to depend on some data held by the underlying error: |
336 | | /// |
337 | | /// ``` |
338 | | /// # use std::fmt::{self, Debug, Display}; |
339 | | /// # |
340 | | /// # type T = (); |
341 | | /// # |
342 | | /// # impl std::error::Error for ParseError {} |
343 | | /// # impl Debug for ParseError { |
344 | | /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
345 | | /// # unimplemented!() |
346 | | /// # } |
347 | | /// # } |
348 | | /// # impl Display for ParseError { |
349 | | /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
350 | | /// # unimplemented!() |
351 | | /// # } |
352 | | /// # } |
353 | | /// # |
354 | | /// use anyhow::Result; |
355 | | /// use std::fs::File; |
356 | | /// use std::path::Path; |
357 | | /// |
358 | | /// struct ParseError { |
359 | | /// line: usize, |
360 | | /// column: usize, |
361 | | /// } |
362 | | /// |
363 | | /// fn parse_impl(file: File) -> Result<T, ParseError> { |
364 | | /// # const IGNORE: &str = stringify! { |
365 | | /// ... |
366 | | /// # }; |
367 | | /// # unimplemented!() |
368 | | /// } |
369 | | /// |
370 | | /// pub fn parse(path: impl AsRef<Path>) -> Result<T> { |
371 | | /// let file = File::open(&path)?; |
372 | | /// parse_impl(file).map_err(|error| { |
373 | | /// let context = format!( |
374 | | /// "only the first {} lines of {} are valid", |
375 | | /// error.line, path.as_ref().display(), |
376 | | /// ); |
377 | | /// anyhow::Error::new(error).context(context) |
378 | | /// }) |
379 | | /// } |
380 | | /// ``` |
381 | | #[cold] |
382 | | #[must_use] |
383 | 0 | pub fn context<C>(self, context: C) -> Self |
384 | 0 | where |
385 | 0 | C: Display + Send + Sync + 'static, |
386 | 0 | { |
387 | 0 | let error: ContextError<C, Error> = ContextError { |
388 | 0 | context, |
389 | 0 | error: self, |
390 | 0 | }; |
391 | 0 |
|
392 | 0 | let vtable = &ErrorVTable { |
393 | 0 | object_drop: object_drop::<ContextError<C, Error>>, |
394 | 0 | object_ref: object_ref::<ContextError<C, Error>>, |
395 | 0 | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
396 | 0 | object_mut: object_mut::<ContextError<C, Error>>, |
397 | 0 | object_boxed: object_boxed::<ContextError<C, Error>>, |
398 | 0 | object_downcast: context_chain_downcast::<C>, |
399 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
400 | 0 | object_downcast_mut: context_chain_downcast_mut::<C>, |
401 | 0 | object_drop_rest: context_chain_drop_rest::<C>, |
402 | 0 | #[cfg(all( |
403 | 0 | not(error_generic_member_access), |
404 | 0 | any(std_backtrace, feature = "backtrace") |
405 | 0 | ))] |
406 | 0 | object_backtrace: context_backtrace::<C>, |
407 | 0 | }; |
408 | 0 |
|
409 | 0 | // As the cause is anyhow::Error, we already have a backtrace for it. |
410 | 0 | let backtrace = None; |
411 | 0 |
|
412 | 0 | // Safety: passing vtable that operates on the right type. |
413 | 0 | unsafe { Error::construct(error, vtable, backtrace) } |
414 | 0 | } |
415 | | |
416 | | /// Get the backtrace for this Error. |
417 | | /// |
418 | | /// In order for the backtrace to be meaningful, one of the two environment |
419 | | /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined |
420 | | /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat |
421 | | /// expensive to capture in Rust, so we don't necessarily want to be |
422 | | /// capturing them all over the place all the time. |
423 | | /// |
424 | | /// - If you want panics and errors to both have backtraces, set |
425 | | /// `RUST_BACKTRACE=1`; |
426 | | /// - If you want only errors to have backtraces, set |
427 | | /// `RUST_LIB_BACKTRACE=1`; |
428 | | /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and |
429 | | /// `RUST_LIB_BACKTRACE=0`. |
430 | | /// |
431 | | /// # Stability |
432 | | /// |
433 | | /// Standard library backtraces are only available when using Rust ≥ |
434 | | /// 1.65. On older compilers, this function is only available if the crate's |
435 | | /// "backtrace" feature is enabled, and will use the `backtrace` crate as |
436 | | /// the underlying backtrace implementation. The return type of this |
437 | | /// function on old compilers is `&(impl Debug + Display)`. |
438 | | /// |
439 | | /// ```toml |
440 | | /// [dependencies] |
441 | | /// anyhow = { version = "1.0", features = ["backtrace"] } |
442 | | /// ``` |
443 | | #[cfg(any(std_backtrace, feature = "backtrace"))] |
444 | 0 | pub fn backtrace(&self) -> &impl_backtrace!() { |
445 | 0 | unsafe { ErrorImpl::backtrace(self.inner.by_ref()) } |
446 | 0 | } |
447 | | |
448 | | /// An iterator of the chain of source errors contained by this Error. |
449 | | /// |
450 | | /// This iterator will visit every error in the cause chain of this error |
451 | | /// object, beginning with the error that this error object was created |
452 | | /// from. |
453 | | /// |
454 | | /// # Example |
455 | | /// |
456 | | /// ``` |
457 | | /// use anyhow::Error; |
458 | | /// use std::io; |
459 | | /// |
460 | | /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> { |
461 | | /// for cause in error.chain() { |
462 | | /// if let Some(io_error) = cause.downcast_ref::<io::Error>() { |
463 | | /// return Some(io_error.kind()); |
464 | | /// } |
465 | | /// } |
466 | | /// None |
467 | | /// } |
468 | | /// ``` |
469 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
470 | | #[cold] |
471 | 0 | pub fn chain(&self) -> Chain { |
472 | 0 | unsafe { ErrorImpl::chain(self.inner.by_ref()) } |
473 | 0 | } |
474 | | |
475 | | /// The lowest level cause of this error — this error's cause's |
476 | | /// cause's cause etc. |
477 | | /// |
478 | | /// The root cause is the last error in the iterator produced by |
479 | | /// [`chain()`][Error::chain]. |
480 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
481 | 0 | pub fn root_cause(&self) -> &(dyn StdError + 'static) { |
482 | 0 | self.chain().last().unwrap() |
483 | 0 | } |
484 | | |
485 | | /// Returns true if `E` is the type held by this error object. |
486 | | /// |
487 | | /// For errors with context, this method returns true if `E` matches the |
488 | | /// type of the context `C` **or** the type of the error on which the |
489 | | /// context has been attached. For details about the interaction between |
490 | | /// context and downcasting, [see here]. |
491 | | /// |
492 | | /// [see here]: trait.Context.html#effect-on-downcasting |
493 | 0 | pub fn is<E>(&self) -> bool |
494 | 0 | where |
495 | 0 | E: Display + Debug + Send + Sync + 'static, |
496 | 0 | { |
497 | 0 | self.downcast_ref::<E>().is_some() |
498 | 0 | } |
499 | | |
500 | | /// Attempt to downcast the error object to a concrete type. |
501 | 0 | pub fn downcast<E>(mut self) -> Result<E, Self> |
502 | 0 | where |
503 | 0 | E: Display + Debug + Send + Sync + 'static, |
504 | 0 | { |
505 | 0 | let target = TypeId::of::<E>(); |
506 | 0 | let inner = self.inner.by_mut(); |
507 | | unsafe { |
508 | | // Use vtable to find NonNull<()> which points to a value of type E |
509 | | // somewhere inside the data structure. |
510 | | #[cfg(not(anyhow_no_ptr_addr_of))] |
511 | 0 | let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) { |
512 | 0 | Some(addr) => addr.by_mut().extend(), |
513 | 0 | None => return Err(self), |
514 | | }; |
515 | | #[cfg(anyhow_no_ptr_addr_of)] |
516 | | let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) { |
517 | | Some(addr) => addr.extend(), |
518 | | None => return Err(self), |
519 | | }; |
520 | | |
521 | | // Prepare to read E out of the data structure. We'll drop the rest |
522 | | // of the data structure separately so that E is not dropped. |
523 | 0 | let outer = ManuallyDrop::new(self); |
524 | 0 |
|
525 | 0 | // Read E from where the vtable found it. |
526 | 0 | let error = addr.cast::<E>().read(); |
527 | 0 |
|
528 | 0 | // Drop rest of the data structure outside of E. |
529 | 0 | (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target); |
530 | 0 |
|
531 | 0 | Ok(error) |
532 | | } |
533 | 0 | } |
534 | | |
535 | | /// Downcast this error object by reference. |
536 | | /// |
537 | | /// # Example |
538 | | /// |
539 | | /// ``` |
540 | | /// # use anyhow::anyhow; |
541 | | /// # use std::fmt::{self, Display}; |
542 | | /// # use std::task::Poll; |
543 | | /// # |
544 | | /// # #[derive(Debug)] |
545 | | /// # enum DataStoreError { |
546 | | /// # Censored(()), |
547 | | /// # } |
548 | | /// # |
549 | | /// # impl Display for DataStoreError { |
550 | | /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
551 | | /// # unimplemented!() |
552 | | /// # } |
553 | | /// # } |
554 | | /// # |
555 | | /// # impl std::error::Error for DataStoreError {} |
556 | | /// # |
557 | | /// # const REDACTED_CONTENT: () = (); |
558 | | /// # |
559 | | /// # let error = anyhow!("..."); |
560 | | /// # let root_cause = &error; |
561 | | /// # |
562 | | /// # let ret = |
563 | | /// // If the error was caused by redaction, then return a tombstone instead |
564 | | /// // of the content. |
565 | | /// match root_cause.downcast_ref::<DataStoreError>() { |
566 | | /// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)), |
567 | | /// None => Err(error), |
568 | | /// } |
569 | | /// # ; |
570 | | /// ``` |
571 | 0 | pub fn downcast_ref<E>(&self) -> Option<&E> |
572 | 0 | where |
573 | 0 | E: Display + Debug + Send + Sync + 'static, |
574 | 0 | { |
575 | 0 | let target = TypeId::of::<E>(); |
576 | | unsafe { |
577 | | // Use vtable to find NonNull<()> which points to a value of type E |
578 | | // somewhere inside the data structure. |
579 | 0 | let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?; |
580 | 0 | Some(addr.cast::<E>().deref()) |
581 | | } |
582 | 0 | } |
583 | | |
584 | | /// Downcast this error object by mutable reference. |
585 | 0 | pub fn downcast_mut<E>(&mut self) -> Option<&mut E> |
586 | 0 | where |
587 | 0 | E: Display + Debug + Send + Sync + 'static, |
588 | 0 | { |
589 | 0 | let target = TypeId::of::<E>(); |
590 | | unsafe { |
591 | | // Use vtable to find NonNull<()> which points to a value of type E |
592 | | // somewhere inside the data structure. |
593 | | |
594 | | #[cfg(not(anyhow_no_ptr_addr_of))] |
595 | 0 | let addr = |
596 | 0 | (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut(); |
597 | 0 |
|
598 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
599 | 0 | let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?; |
600 | 0 |
|
601 | 0 | Some(addr.cast::<E>().deref_mut()) |
602 | | } |
603 | 0 | } |
604 | | |
605 | | #[cfg(error_generic_member_access)] |
606 | 0 | pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) { |
607 | 0 | unsafe { ErrorImpl::provide(self.inner.by_ref(), request) } |
608 | 0 | } |
609 | | |
610 | | // Called by thiserror when you have `#[source] anyhow::Error`. This provide |
611 | | // implementation includes the anyhow::Error's Backtrace if any, unlike |
612 | | // deref'ing to dyn Error where the provide implementation would include |
613 | | // only the original error's Backtrace from before it got wrapped into an |
614 | | // anyhow::Error. |
615 | | #[cfg(error_generic_member_access)] |
616 | | #[doc(hidden)] |
617 | 0 | pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) { |
618 | 0 | Self::provide(self, request); |
619 | 0 | } |
620 | | } |
621 | | |
622 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
623 | | impl<E> From<E> for Error |
624 | | where |
625 | | E: StdError + Send + Sync + 'static, |
626 | | { |
627 | | #[cold] |
628 | 0 | fn from(error: E) -> Self { |
629 | 0 | let backtrace = backtrace_if_absent!(&error); |
630 | 0 | Error::construct_from_std(error, backtrace) |
631 | 0 | } Unexecuted instantiation: <anyhow::Error as core::convert::From<quick_xml::errors::Error>>::from Unexecuted instantiation: <anyhow::Error as core::convert::From<quick_xml::escapei::EscapeError>>::from Unexecuted instantiation: <anyhow::Error as core::convert::From<core::num::error::ParseIntError>>::from Unexecuted instantiation: <anyhow::Error as core::convert::From<_>>::from |
632 | | } |
633 | | |
634 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
635 | | impl Deref for Error { |
636 | | type Target = dyn StdError + Send + Sync + 'static; |
637 | | |
638 | 0 | fn deref(&self) -> &Self::Target { |
639 | 0 | unsafe { ErrorImpl::error(self.inner.by_ref()) } |
640 | 0 | } |
641 | | } |
642 | | |
643 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
644 | | impl DerefMut for Error { |
645 | 0 | fn deref_mut(&mut self) -> &mut Self::Target { |
646 | 0 | unsafe { ErrorImpl::error_mut(self.inner.by_mut()) } |
647 | 0 | } |
648 | | } |
649 | | |
650 | | impl Display for Error { |
651 | 0 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
652 | 0 | unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) } |
653 | 0 | } |
654 | | } |
655 | | |
656 | | impl Debug for Error { |
657 | 0 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
658 | 0 | unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) } |
659 | 0 | } |
660 | | } |
661 | | |
662 | | impl Drop for Error { |
663 | 1.33M | fn drop(&mut self) { |
664 | 1.33M | unsafe { |
665 | 1.33M | // Invoke the vtable's drop behavior. |
666 | 1.33M | (vtable(self.inner.ptr).object_drop)(self.inner); |
667 | 1.33M | } |
668 | 1.33M | } |
669 | | } |
670 | | |
671 | | struct ErrorVTable { |
672 | | object_drop: unsafe fn(Own<ErrorImpl>), |
673 | | object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>, |
674 | | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
675 | | object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static), |
676 | | object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>, |
677 | | object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>, |
678 | | #[cfg(anyhow_no_ptr_addr_of)] |
679 | | object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>, |
680 | | object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId), |
681 | | #[cfg(all( |
682 | | not(error_generic_member_access), |
683 | | any(std_backtrace, feature = "backtrace") |
684 | | ))] |
685 | | object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>, |
686 | | } |
687 | | |
688 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
689 | 1.33M | unsafe fn object_drop<E>(e: Own<ErrorImpl>) { |
690 | 1.33M | // Cast back to ErrorImpl<E> so that the allocator receives the correct |
691 | 1.33M | // Layout to deallocate the Box's memory. |
692 | 1.33M | let unerased_own = e.cast::<ErrorImpl<E>>(); |
693 | 1.33M | drop(unsafe { unerased_own.boxed() }); |
694 | 1.33M | } Unexecuted instantiation: anyhow::error::object_drop::<quick_xml::errors::Error> Unexecuted instantiation: anyhow::error::object_drop::<quick_xml::escapei::EscapeError> Unexecuted instantiation: anyhow::error::object_drop::<core::num::error::ParseIntError> Unexecuted instantiation: anyhow::error::object_drop::<anyhow::wrapper::MessageError<alloc::string::String>> anyhow::error::object_drop::<anyhow::wrapper::MessageError<&str>> Line | Count | Source | 689 | 1.33M | unsafe fn object_drop<E>(e: Own<ErrorImpl>) { | 690 | 1.33M | // Cast back to ErrorImpl<E> so that the allocator receives the correct | 691 | 1.33M | // Layout to deallocate the Box's memory. | 692 | 1.33M | let unerased_own = e.cast::<ErrorImpl<E>>(); | 693 | 1.33M | drop(unsafe { unerased_own.boxed() }); | 694 | 1.33M | } |
Unexecuted instantiation: anyhow::error::object_drop::<anyhow::wrapper::BoxedError> |
695 | | |
696 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
697 | 0 | unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) { |
698 | 0 | // Drop the fields of ErrorImpl other than E as well as the Box allocation, |
699 | 0 | // without dropping E itself. This is used by downcast after doing a |
700 | 0 | // ptr::read to take ownership of the E. |
701 | 0 | let _ = target; |
702 | 0 | let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>(); |
703 | 0 | drop(unsafe { unerased_own.boxed() }); |
704 | 0 | } Unexecuted instantiation: anyhow::error::object_drop_front::<quick_xml::errors::Error> Unexecuted instantiation: anyhow::error::object_drop_front::<quick_xml::escapei::EscapeError> Unexecuted instantiation: anyhow::error::object_drop_front::<core::num::error::ParseIntError> Unexecuted instantiation: anyhow::error::object_drop_front::<alloc::boxed::Box<dyn core::error::Error + core::marker::Sync + core::marker::Send>> Unexecuted instantiation: anyhow::error::object_drop_front::<alloc::string::String> Unexecuted instantiation: anyhow::error::object_drop_front::<&str> |
705 | | |
706 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
707 | 0 | unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static> |
708 | 0 | where |
709 | 0 | E: StdError + Send + Sync + 'static, |
710 | 0 | { |
711 | 0 | // Attach E's native StdError vtable onto a pointer to self._object. |
712 | 0 |
|
713 | 0 | let unerased_ref = e.cast::<ErrorImpl<E>>(); |
714 | 0 |
|
715 | 0 | #[cfg(not(anyhow_no_ptr_addr_of))] |
716 | 0 | return Ref::from_raw(unsafe { |
717 | 0 | NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) |
718 | 0 | }); |
719 | 0 |
|
720 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
721 | 0 | return Ref::new(unsafe { &unerased_ref.deref()._object }); |
722 | 0 | } Unexecuted instantiation: anyhow::error::object_ref::<quick_xml::errors::Error> Unexecuted instantiation: anyhow::error::object_ref::<quick_xml::escapei::EscapeError> Unexecuted instantiation: anyhow::error::object_ref::<core::num::error::ParseIntError> Unexecuted instantiation: anyhow::error::object_ref::<anyhow::wrapper::MessageError<alloc::string::String>> Unexecuted instantiation: anyhow::error::object_ref::<anyhow::wrapper::MessageError<&str>> Unexecuted instantiation: anyhow::error::object_ref::<anyhow::wrapper::BoxedError> |
723 | | |
724 | | // Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived |
725 | | // from a `&mut` |
726 | | #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
727 | | unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static) |
728 | | where |
729 | | E: StdError + Send + Sync + 'static, |
730 | | { |
731 | | // Attach E's native StdError vtable onto a pointer to self._object. |
732 | | let unerased_mut = e.cast::<ErrorImpl<E>>(); |
733 | | unsafe { &mut unerased_mut.deref_mut()._object } |
734 | | } |
735 | | |
736 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
737 | 0 | unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static> |
738 | 0 | where |
739 | 0 | E: StdError + Send + Sync + 'static, |
740 | 0 | { |
741 | 0 | // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below. |
742 | 0 | let unerased_own = e.cast::<ErrorImpl<E>>(); |
743 | 0 | unsafe { unerased_own.boxed() } |
744 | 0 | } Unexecuted instantiation: anyhow::error::object_boxed::<quick_xml::errors::Error> Unexecuted instantiation: anyhow::error::object_boxed::<quick_xml::escapei::EscapeError> Unexecuted instantiation: anyhow::error::object_boxed::<core::num::error::ParseIntError> Unexecuted instantiation: anyhow::error::object_boxed::<anyhow::wrapper::MessageError<alloc::string::String>> Unexecuted instantiation: anyhow::error::object_boxed::<anyhow::wrapper::MessageError<&str>> Unexecuted instantiation: anyhow::error::object_boxed::<anyhow::wrapper::BoxedError> |
745 | | |
746 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
747 | 0 | unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
748 | 0 | where |
749 | 0 | E: 'static, |
750 | 0 | { |
751 | 0 | if TypeId::of::<E>() == target { |
752 | | // Caller is looking for an E pointer and e is ErrorImpl<E>, take a |
753 | | // pointer to its E field. |
754 | | |
755 | 0 | let unerased_ref = e.cast::<ErrorImpl<E>>(); |
756 | 0 |
|
757 | 0 | #[cfg(not(anyhow_no_ptr_addr_of))] |
758 | 0 | return Some( |
759 | 0 | Ref::from_raw(unsafe { |
760 | 0 | NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) |
761 | 0 | }) |
762 | 0 | .cast::<()>(), |
763 | 0 | ); |
764 | | |
765 | | #[cfg(anyhow_no_ptr_addr_of)] |
766 | | return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>()); |
767 | | } else { |
768 | 0 | None |
769 | | } |
770 | 0 | } Unexecuted instantiation: anyhow::error::object_downcast::<quick_xml::errors::Error> Unexecuted instantiation: anyhow::error::object_downcast::<quick_xml::escapei::EscapeError> Unexecuted instantiation: anyhow::error::object_downcast::<core::num::error::ParseIntError> Unexecuted instantiation: anyhow::error::object_downcast::<alloc::boxed::Box<dyn core::error::Error + core::marker::Sync + core::marker::Send>> Unexecuted instantiation: anyhow::error::object_downcast::<alloc::string::String> Unexecuted instantiation: anyhow::error::object_downcast::<&str> |
771 | | |
772 | | // Safety: requires layout of *e to match ErrorImpl<E>. |
773 | | #[cfg(anyhow_no_ptr_addr_of)] |
774 | | unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
775 | | where |
776 | | E: 'static, |
777 | | { |
778 | | if TypeId::of::<E>() == target { |
779 | | // Caller is looking for an E pointer and e is ErrorImpl<E>, take a |
780 | | // pointer to its E field. |
781 | | let unerased_mut = e.cast::<ErrorImpl<E>>(); |
782 | | let unerased = unsafe { unerased_mut.deref_mut() }; |
783 | | Some(Mut::new(&mut unerased._object).cast::<()>()) |
784 | | } else { |
785 | | None |
786 | | } |
787 | | } |
788 | | |
789 | | #[cfg(all( |
790 | | not(error_generic_member_access), |
791 | | any(std_backtrace, feature = "backtrace") |
792 | | ))] |
793 | | fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> { |
794 | | let _ = e; |
795 | | None |
796 | | } |
797 | | |
798 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
799 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
800 | 0 | unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
801 | 0 | where |
802 | 0 | C: 'static, |
803 | 0 | E: 'static, |
804 | 0 | { |
805 | 0 | if TypeId::of::<C>() == target { |
806 | 0 | let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
807 | 0 | let unerased = unsafe { unerased_ref.deref() }; |
808 | 0 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
809 | 0 | } else if TypeId::of::<E>() == target { |
810 | 0 | let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
811 | 0 | let unerased = unsafe { unerased_ref.deref() }; |
812 | 0 | Some(Ref::new(&unerased._object.error).cast::<()>()) |
813 | | } else { |
814 | 0 | None |
815 | | } |
816 | 0 | } |
817 | | |
818 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
819 | | #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))] |
820 | | unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
821 | | where |
822 | | C: 'static, |
823 | | E: 'static, |
824 | | { |
825 | | if TypeId::of::<C>() == target { |
826 | | let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
827 | | let unerased = unsafe { unerased_mut.deref_mut() }; |
828 | | Some(Mut::new(&mut unerased._object.context).cast::<()>()) |
829 | | } else if TypeId::of::<E>() == target { |
830 | | let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
831 | | let unerased = unsafe { unerased_mut.deref_mut() }; |
832 | | Some(Mut::new(&mut unerased._object.error).cast::<()>()) |
833 | | } else { |
834 | | None |
835 | | } |
836 | | } |
837 | | |
838 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
839 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
840 | 0 | unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId) |
841 | 0 | where |
842 | 0 | C: 'static, |
843 | 0 | E: 'static, |
844 | 0 | { |
845 | 0 | // Called after downcasting by value to either the C or the E and doing a |
846 | 0 | // ptr::read to take ownership of that value. |
847 | 0 | if TypeId::of::<C>() == target { |
848 | 0 | let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>(); |
849 | 0 | drop(unsafe { unerased_own.boxed() }); |
850 | 0 | } else { |
851 | 0 | let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>(); |
852 | 0 | drop(unsafe { unerased_own.boxed() }); |
853 | 0 | } |
854 | 0 | } |
855 | | |
856 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
857 | 0 | unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
858 | 0 | where |
859 | 0 | C: 'static, |
860 | 0 | { |
861 | 0 | let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>(); |
862 | 0 | let unerased = unsafe { unerased_ref.deref() }; |
863 | 0 | if TypeId::of::<C>() == target { |
864 | 0 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
865 | | } else { |
866 | | // Recurse down the context chain per the inner error's vtable. |
867 | 0 | let source = &unerased._object.error; |
868 | 0 | unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) } |
869 | | } |
870 | 0 | } |
871 | | |
872 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
873 | | #[cfg(anyhow_no_ptr_addr_of)] |
874 | | unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
875 | | where |
876 | | C: 'static, |
877 | | { |
878 | | let unerased_mut = e.cast::<ErrorImpl<ContextError<C, Error>>>(); |
879 | | let unerased = unsafe { unerased_mut.deref_mut() }; |
880 | | if TypeId::of::<C>() == target { |
881 | | Some(Mut::new(&mut unerased._object.context).cast::<()>()) |
882 | | } else { |
883 | | // Recurse down the context chain per the inner error's vtable. |
884 | | let source = &mut unerased._object.error; |
885 | | unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) } |
886 | | } |
887 | | } |
888 | | |
889 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
890 | 0 | unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId) |
891 | 0 | where |
892 | 0 | C: 'static, |
893 | 0 | { |
894 | 0 | // Called after downcasting by value to either the C or one of the causes |
895 | 0 | // and doing a ptr::read to take ownership of that value. |
896 | 0 | if TypeId::of::<C>() == target { |
897 | 0 | let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>(); |
898 | 0 | // Drop the entire rest of the data structure rooted in the next Error. |
899 | 0 | drop(unsafe { unerased_own.boxed() }); |
900 | 0 | } else { |
901 | 0 | let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>(); |
902 | 0 | let unerased = unsafe { unerased_own.boxed() }; |
903 | 0 | // Read the Own<ErrorImpl> from the next error. |
904 | 0 | let inner = unerased._object.error.inner; |
905 | 0 | drop(unerased); |
906 | 0 | let vtable = unsafe { vtable(inner.ptr) }; |
907 | 0 | // Recursively drop the next error using the same target typeid. |
908 | 0 | unsafe { (vtable.object_drop_rest)(inner, target) }; |
909 | 0 | } |
910 | 0 | } |
911 | | |
912 | | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
913 | | #[cfg(all( |
914 | | not(error_generic_member_access), |
915 | | any(std_backtrace, feature = "backtrace") |
916 | | ))] |
917 | | #[allow(clippy::unnecessary_wraps)] |
918 | | unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace> |
919 | | where |
920 | | C: 'static, |
921 | | { |
922 | | let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>(); |
923 | | let unerased = unsafe { unerased_ref.deref() }; |
924 | | let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) }; |
925 | | Some(backtrace) |
926 | | } |
927 | | |
928 | | // NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor |
929 | | // of raw pointers and `NonNull`. |
930 | | // repr C to ensure that E remains in the final position. |
931 | | #[repr(C)] |
932 | | pub(crate) struct ErrorImpl<E = ()> { |
933 | | vtable: &'static ErrorVTable, |
934 | | backtrace: Option<Backtrace>, |
935 | | // NOTE: Don't use directly. Use only through vtable. Erased type may have |
936 | | // different alignment. |
937 | | _object: E, |
938 | | } |
939 | | |
940 | | // Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but |
941 | | // avoids converting `p` into a reference. |
942 | 1.33M | unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable { |
943 | 1.33M | // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl. |
944 | 1.33M | unsafe { *(p.as_ptr() as *const &'static ErrorVTable) } |
945 | 1.33M | } |
946 | | |
947 | | // repr C to ensure that ContextError<C, E> has the same layout as |
948 | | // ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>. |
949 | | #[repr(C)] |
950 | | pub(crate) struct ContextError<C, E> { |
951 | | pub context: C, |
952 | | pub error: E, |
953 | | } |
954 | | |
955 | | impl<E> ErrorImpl<E> { |
956 | 0 | fn erase(&self) -> Ref<ErrorImpl> { |
957 | 0 | // Erase the concrete type of E but preserve the vtable in self.vtable |
958 | 0 | // for manipulating the resulting thin pointer. This is analogous to an |
959 | 0 | // unsize coercion. |
960 | 0 | Ref::new(self).cast::<ErrorImpl>() |
961 | 0 | } Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::errors::Error>>::erase Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::escapei::EscapeError>>::erase Unexecuted instantiation: <anyhow::error::ErrorImpl<core::num::error::ParseIntError>>::erase Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<alloc::string::String>>>::erase Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<&str>>>::erase Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::BoxedError>>::erase |
962 | | } |
963 | | |
964 | | impl ErrorImpl { |
965 | 0 | pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) { |
966 | 0 | // Use vtable to attach E's native StdError vtable for the right |
967 | 0 | // original type E. |
968 | 0 | unsafe { (vtable(this.ptr).object_ref)(this).deref() } |
969 | 0 | } |
970 | | |
971 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
972 | 0 | pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) { |
973 | 0 | // Use vtable to attach E's native StdError vtable for the right |
974 | 0 | // original type E. |
975 | 0 |
|
976 | 0 | #[cfg(not(anyhow_no_ptr_addr_of))] |
977 | 0 | return unsafe { |
978 | 0 | (vtable(this.ptr).object_ref)(this.by_ref()) |
979 | 0 | .by_mut() |
980 | 0 | .deref_mut() |
981 | 0 | }; |
982 | 0 |
|
983 | 0 | #[cfg(anyhow_no_ptr_addr_of)] |
984 | 0 | return unsafe { (vtable(this.ptr).object_mut)(this) }; |
985 | 0 | } |
986 | | |
987 | | #[cfg(any(std_backtrace, feature = "backtrace"))] |
988 | 0 | pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace { |
989 | 0 | // This unwrap can only panic if the underlying error's backtrace method |
990 | 0 | // is nondeterministic, which would only happen in maliciously |
991 | 0 | // constructed code. |
992 | 0 | unsafe { this.deref() } |
993 | 0 | .backtrace |
994 | 0 | .as_ref() |
995 | 0 | .or_else(|| { |
996 | 0 | #[cfg(error_generic_member_access)] |
997 | 0 | return error::request_ref::<Backtrace>(unsafe { Self::error(this) }); |
998 | 0 | #[cfg(not(error_generic_member_access))] |
999 | 0 | return unsafe { (vtable(this.ptr).object_backtrace)(this) }; |
1000 | 0 | }) |
1001 | 0 | .expect("backtrace capture failed") |
1002 | 0 | } |
1003 | | |
1004 | | #[cfg(error_generic_member_access)] |
1005 | 0 | unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) { |
1006 | 0 | if let Some(backtrace) = unsafe { &this.deref().backtrace } { |
1007 | 0 | request.provide_ref(backtrace); |
1008 | 0 | } |
1009 | 0 | unsafe { Self::error(this) }.provide(request); |
1010 | 0 | } |
1011 | | |
1012 | | #[cold] |
1013 | 0 | pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain { |
1014 | 0 | Chain::new(unsafe { Self::error(this) }) |
1015 | 0 | } |
1016 | | } |
1017 | | |
1018 | | impl<E> StdError for ErrorImpl<E> |
1019 | | where |
1020 | | E: StdError, |
1021 | | { |
1022 | 0 | fn source(&self) -> Option<&(dyn StdError + 'static)> { |
1023 | 0 | unsafe { ErrorImpl::error(self.erase()).source() } |
1024 | 0 | } Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::errors::Error> as core::error::Error>::source Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::escapei::EscapeError> as core::error::Error>::source Unexecuted instantiation: <anyhow::error::ErrorImpl<core::num::error::ParseIntError> as core::error::Error>::source Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<alloc::string::String>> as core::error::Error>::source Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<&str>> as core::error::Error>::source Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::BoxedError> as core::error::Error>::source |
1025 | | |
1026 | | #[cfg(error_generic_member_access)] |
1027 | 0 | fn provide<'a>(&'a self, request: &mut Request<'a>) { |
1028 | 0 | unsafe { ErrorImpl::provide(self.erase(), request) } |
1029 | 0 | } Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::errors::Error> as core::error::Error>::provide Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::escapei::EscapeError> as core::error::Error>::provide Unexecuted instantiation: <anyhow::error::ErrorImpl<core::num::error::ParseIntError> as core::error::Error>::provide Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<alloc::string::String>> as core::error::Error>::provide Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<&str>> as core::error::Error>::provide Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::BoxedError> as core::error::Error>::provide |
1030 | | } |
1031 | | |
1032 | | impl<E> Debug for ErrorImpl<E> |
1033 | | where |
1034 | | E: Debug, |
1035 | | { |
1036 | 0 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
1037 | 0 | unsafe { ErrorImpl::debug(self.erase(), formatter) } |
1038 | 0 | } Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::errors::Error> as core::fmt::Debug>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::escapei::EscapeError> as core::fmt::Debug>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<core::num::error::ParseIntError> as core::fmt::Debug>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<alloc::string::String>> as core::fmt::Debug>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<&str>> as core::fmt::Debug>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::BoxedError> as core::fmt::Debug>::fmt |
1039 | | } |
1040 | | |
1041 | | impl<E> Display for ErrorImpl<E> |
1042 | | where |
1043 | | E: Display, |
1044 | | { |
1045 | 0 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
1046 | 0 | unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) } |
1047 | 0 | } Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::errors::Error> as core::fmt::Display>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<quick_xml::escapei::EscapeError> as core::fmt::Display>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<core::num::error::ParseIntError> as core::fmt::Display>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<alloc::string::String>> as core::fmt::Display>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::MessageError<&str>> as core::fmt::Display>::fmt Unexecuted instantiation: <anyhow::error::ErrorImpl<anyhow::wrapper::BoxedError> as core::fmt::Display>::fmt |
1048 | | } |
1049 | | |
1050 | | impl From<Error> for Box<dyn StdError + Send + Sync + 'static> { |
1051 | | #[cold] |
1052 | 0 | fn from(error: Error) -> Self { |
1053 | 0 | let outer = ManuallyDrop::new(error); |
1054 | 0 | unsafe { |
1055 | 0 | // Use vtable to attach ErrorImpl<E>'s native StdError vtable for |
1056 | 0 | // the right original type E. |
1057 | 0 | (vtable(outer.inner.ptr).object_boxed)(outer.inner) |
1058 | 0 | } |
1059 | 0 | } |
1060 | | } |
1061 | | |
1062 | | impl From<Error> for Box<dyn StdError + Send + 'static> { |
1063 | 0 | fn from(error: Error) -> Self { |
1064 | 0 | Box::<dyn StdError + Send + Sync>::from(error) |
1065 | 0 | } |
1066 | | } |
1067 | | |
1068 | | impl From<Error> for Box<dyn StdError + 'static> { |
1069 | 0 | fn from(error: Error) -> Self { |
1070 | 0 | Box::<dyn StdError + Send + Sync>::from(error) |
1071 | 0 | } |
1072 | | } |
1073 | | |
1074 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
1075 | | impl AsRef<dyn StdError + Send + Sync> for Error { |
1076 | 0 | fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) { |
1077 | 0 | &**self |
1078 | 0 | } |
1079 | | } |
1080 | | |
1081 | | #[cfg(any(feature = "std", not(anyhow_no_core_error)))] |
1082 | | impl AsRef<dyn StdError> for Error { |
1083 | 0 | fn as_ref(&self) -> &(dyn StdError + 'static) { |
1084 | 0 | &**self |
1085 | 0 | } |
1086 | | } |
1087 | | |
1088 | | #[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))] |
1089 | | impl UnwindSafe for Error {} |
1090 | | |
1091 | | #[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))] |
1092 | | impl RefUnwindSafe for Error {} |