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 | pub fn new<E>(error: E) -> Self |
35 | where |
36 | E: StdError + Send + Sync + 'static, |
37 | { |
38 | let backtrace = backtrace_if_absent!(&error); |
39 | Error::construct_from_std(error, backtrace) |
40 | } |
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 | pub fn msg<M>(message: M) -> Self |
82 | where |
83 | M: Display + Debug + Send + Sync + 'static, |
84 | { |
85 | Error::construct_from_adhoc(message, backtrace!()) |
86 | } |
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 | pub fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self { |
145 | let backtrace = backtrace_if_absent!(&*boxed_error); |
146 | Error::construct_from_boxed(boxed_error, backtrace) |
147 | } |
148 | |
149 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
150 | #[cold ] |
151 | pub(crate) fn construct_from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self |
152 | where |
153 | E: StdError + Send + Sync + 'static, |
154 | { |
155 | let vtable = &ErrorVTable { |
156 | object_drop: object_drop::<E>, |
157 | object_ref: object_ref::<E>, |
158 | #[cfg (anyhow_no_ptr_addr_of)] |
159 | object_mut: object_mut::<E>, |
160 | object_boxed: object_boxed::<E>, |
161 | object_downcast: object_downcast::<E>, |
162 | #[cfg (anyhow_no_ptr_addr_of)] |
163 | object_downcast_mut: object_downcast_mut::<E>, |
164 | object_drop_rest: object_drop_front::<E>, |
165 | #[cfg (all( |
166 | not(error_generic_member_access), |
167 | any(std_backtrace, feature = "backtrace" ) |
168 | ))] |
169 | object_backtrace: no_backtrace, |
170 | }; |
171 | |
172 | // Safety: passing vtable that operates on the right type E. |
173 | unsafe { Error::construct(error, vtable, backtrace) } |
174 | } |
175 | |
176 | #[cold ] |
177 | pub(crate) fn construct_from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self |
178 | where |
179 | M: Display + Debug + Send + Sync + 'static, |
180 | { |
181 | use crate::wrapper::MessageError; |
182 | let error: MessageError<M> = MessageError(message); |
183 | let vtable = &ErrorVTable { |
184 | object_drop: object_drop::<MessageError<M>>, |
185 | object_ref: object_ref::<MessageError<M>>, |
186 | #[cfg (all(any(feature = "std" , not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
187 | object_mut: object_mut::<MessageError<M>>, |
188 | object_boxed: object_boxed::<MessageError<M>>, |
189 | object_downcast: object_downcast::<M>, |
190 | #[cfg (anyhow_no_ptr_addr_of)] |
191 | object_downcast_mut: object_downcast_mut::<M>, |
192 | object_drop_rest: object_drop_front::<M>, |
193 | #[cfg (all( |
194 | not(error_generic_member_access), |
195 | any(std_backtrace, feature = "backtrace" ) |
196 | ))] |
197 | object_backtrace: no_backtrace, |
198 | }; |
199 | |
200 | // Safety: MessageError is repr(transparent) so it is okay for the |
201 | // vtable to allow casting the MessageError<M> to M. |
202 | unsafe { Error::construct(error, vtable, backtrace) } |
203 | } |
204 | |
205 | #[cold ] |
206 | pub(crate) fn construct_from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self |
207 | where |
208 | M: Display + Send + Sync + 'static, |
209 | { |
210 | use crate::wrapper::DisplayError; |
211 | let error: DisplayError<M> = DisplayError(message); |
212 | let vtable = &ErrorVTable { |
213 | object_drop: object_drop::<DisplayError<M>>, |
214 | object_ref: object_ref::<DisplayError<M>>, |
215 | #[cfg (all(any(feature = "std" , not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
216 | object_mut: object_mut::<DisplayError<M>>, |
217 | object_boxed: object_boxed::<DisplayError<M>>, |
218 | object_downcast: object_downcast::<M>, |
219 | #[cfg (anyhow_no_ptr_addr_of)] |
220 | object_downcast_mut: object_downcast_mut::<M>, |
221 | object_drop_rest: object_drop_front::<M>, |
222 | #[cfg (all( |
223 | not(error_generic_member_access), |
224 | any(std_backtrace, feature = "backtrace" ) |
225 | ))] |
226 | object_backtrace: no_backtrace, |
227 | }; |
228 | |
229 | // Safety: DisplayError is repr(transparent) so it is okay for the |
230 | // vtable to allow casting the DisplayError<M> to M. |
231 | unsafe { Error::construct(error, vtable, backtrace) } |
232 | } |
233 | |
234 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
235 | #[cold ] |
236 | pub(crate) fn construct_from_context<C, E>( |
237 | context: C, |
238 | error: E, |
239 | backtrace: Option<Backtrace>, |
240 | ) -> Self |
241 | where |
242 | C: Display + Send + Sync + 'static, |
243 | E: StdError + Send + Sync + 'static, |
244 | { |
245 | let error: ContextError<C, E> = ContextError { context, error }; |
246 | |
247 | let vtable = &ErrorVTable { |
248 | object_drop: object_drop::<ContextError<C, E>>, |
249 | object_ref: object_ref::<ContextError<C, E>>, |
250 | #[cfg (anyhow_no_ptr_addr_of)] |
251 | object_mut: object_mut::<ContextError<C, E>>, |
252 | object_boxed: object_boxed::<ContextError<C, E>>, |
253 | object_downcast: context_downcast::<C, E>, |
254 | #[cfg (anyhow_no_ptr_addr_of)] |
255 | object_downcast_mut: context_downcast_mut::<C, E>, |
256 | object_drop_rest: context_drop_rest::<C, E>, |
257 | #[cfg (all( |
258 | not(error_generic_member_access), |
259 | any(std_backtrace, feature = "backtrace" ) |
260 | ))] |
261 | object_backtrace: no_backtrace, |
262 | }; |
263 | |
264 | // Safety: passing vtable that operates on the right type. |
265 | unsafe { Error::construct(error, vtable, backtrace) } |
266 | } |
267 | |
268 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
269 | #[cold ] |
270 | pub(crate) fn construct_from_boxed( |
271 | error: Box<dyn StdError + Send + Sync>, |
272 | backtrace: Option<Backtrace>, |
273 | ) -> Self { |
274 | use crate::wrapper::BoxedError; |
275 | let error = BoxedError(error); |
276 | let vtable = &ErrorVTable { |
277 | object_drop: object_drop::<BoxedError>, |
278 | object_ref: object_ref::<BoxedError>, |
279 | #[cfg (anyhow_no_ptr_addr_of)] |
280 | object_mut: object_mut::<BoxedError>, |
281 | object_boxed: object_boxed::<BoxedError>, |
282 | object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>, |
283 | #[cfg (anyhow_no_ptr_addr_of)] |
284 | object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>, |
285 | object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>, |
286 | #[cfg (all( |
287 | not(error_generic_member_access), |
288 | any(std_backtrace, feature = "backtrace" ) |
289 | ))] |
290 | object_backtrace: no_backtrace, |
291 | }; |
292 | |
293 | // Safety: BoxedError is repr(transparent) so it is okay for the vtable |
294 | // to allow casting to Box<dyn StdError + Send + Sync>. |
295 | unsafe { Error::construct(error, vtable, backtrace) } |
296 | } |
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 | unsafe fn construct<E>( |
305 | error: E, |
306 | vtable: &'static ErrorVTable, |
307 | backtrace: Option<Backtrace>, |
308 | ) -> Self |
309 | where |
310 | E: StdError + Send + Sync + 'static, |
311 | { |
312 | let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl { |
313 | vtable, |
314 | backtrace, |
315 | _object: error, |
316 | }); |
317 | // Erase the concrete type of E from the compile-time type system. This |
318 | // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to |
319 | // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the |
320 | // result is a thin pointer. The necessary behavior for manipulating the |
321 | // underlying ErrorImpl<E> is preserved in the vtable provided by the |
322 | // caller rather than a builtin fat pointer vtable. |
323 | let inner = Own::new(inner).cast::<ErrorImpl>(); |
324 | Error { inner } |
325 | } |
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 | pub fn context<C>(self, context: C) -> Self |
384 | where |
385 | C: Display + Send + Sync + 'static, |
386 | { |
387 | let error: ContextError<C, Error> = ContextError { |
388 | context, |
389 | error: self, |
390 | }; |
391 | |
392 | let vtable = &ErrorVTable { |
393 | object_drop: object_drop::<ContextError<C, Error>>, |
394 | object_ref: object_ref::<ContextError<C, Error>>, |
395 | #[cfg (all(any(feature = "std" , not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] |
396 | object_mut: object_mut::<ContextError<C, Error>>, |
397 | object_boxed: object_boxed::<ContextError<C, Error>>, |
398 | object_downcast: context_chain_downcast::<C>, |
399 | #[cfg (anyhow_no_ptr_addr_of)] |
400 | object_downcast_mut: context_chain_downcast_mut::<C>, |
401 | object_drop_rest: context_chain_drop_rest::<C>, |
402 | #[cfg (all( |
403 | not(error_generic_member_access), |
404 | any(std_backtrace, feature = "backtrace" ) |
405 | ))] |
406 | object_backtrace: context_backtrace::<C>, |
407 | }; |
408 | |
409 | // As the cause is anyhow::Error, we already have a backtrace for it. |
410 | let backtrace = None; |
411 | |
412 | // Safety: passing vtable that operates on the right type. |
413 | unsafe { Error::construct(error, vtable, backtrace) } |
414 | } |
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 | pub fn backtrace(&self) -> &impl_backtrace!() { |
445 | unsafe { ErrorImpl::backtrace(self.inner.by_ref()) } |
446 | } |
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 | pub fn chain(&self) -> Chain { |
472 | unsafe { ErrorImpl::chain(self.inner.by_ref()) } |
473 | } |
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 | pub fn root_cause(&self) -> &(dyn StdError + 'static) { |
482 | self.chain().last().unwrap() |
483 | } |
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 | pub fn is<E>(&self) -> bool |
494 | where |
495 | E: Display + Debug + Send + Sync + 'static, |
496 | { |
497 | self.downcast_ref::<E>().is_some() |
498 | } |
499 | |
500 | /// Attempt to downcast the error object to a concrete type. |
501 | pub fn downcast<E>(mut self) -> Result<E, Self> |
502 | where |
503 | E: Display + Debug + Send + Sync + 'static, |
504 | { |
505 | let target = TypeId::of::<E>(); |
506 | 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 | let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) { |
512 | Some(addr) => addr.by_mut().extend(), |
513 | 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 | let outer = ManuallyDrop::new(self); |
524 | |
525 | // Read E from where the vtable found it. |
526 | let error = addr.cast::<E>().read(); |
527 | |
528 | // Drop rest of the data structure outside of E. |
529 | (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target); |
530 | |
531 | Ok(error) |
532 | } |
533 | } |
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 | pub fn downcast_ref<E>(&self) -> Option<&E> |
572 | where |
573 | E: Display + Debug + Send + Sync + 'static, |
574 | { |
575 | 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 | let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?; |
580 | Some(addr.cast::<E>().deref()) |
581 | } |
582 | } |
583 | |
584 | /// Downcast this error object by mutable reference. |
585 | pub fn downcast_mut<E>(&mut self) -> Option<&mut E> |
586 | where |
587 | E: Display + Debug + Send + Sync + 'static, |
588 | { |
589 | 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 | let addr = |
596 | (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut(); |
597 | |
598 | #[cfg (anyhow_no_ptr_addr_of)] |
599 | let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?; |
600 | |
601 | Some(addr.cast::<E>().deref_mut()) |
602 | } |
603 | } |
604 | |
605 | #[cfg (error_generic_member_access)] |
606 | pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) { |
607 | unsafe { ErrorImpl::provide(self.inner.by_ref(), request) } |
608 | } |
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 | pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) { |
618 | Self::provide(self, request); |
619 | } |
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 | fn from(error: E) -> Self { |
629 | let backtrace: Option = backtrace_if_absent!(&error); |
630 | Error::construct_from_std(error, backtrace) |
631 | } |
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 | fn deref(&self) -> &Self::Target { |
639 | unsafe { ErrorImpl::error(self.inner.by_ref()) } |
640 | } |
641 | } |
642 | |
643 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
644 | impl DerefMut for Error { |
645 | fn deref_mut(&mut self) -> &mut Self::Target { |
646 | unsafe { ErrorImpl::error_mut(self.inner.by_mut()) } |
647 | } |
648 | } |
649 | |
650 | impl Display for Error { |
651 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
652 | unsafe { ErrorImpl::display(self.inner.by_ref(), f:formatter) } |
653 | } |
654 | } |
655 | |
656 | impl Debug for Error { |
657 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
658 | unsafe { ErrorImpl::debug(self.inner.by_ref(), f:formatter) } |
659 | } |
660 | } |
661 | |
662 | impl Drop for Error { |
663 | fn drop(&mut self) { |
664 | unsafe { |
665 | // Invoke the vtable's drop behavior. |
666 | (vtable(self.inner.ptr).object_drop)(self.inner); |
667 | } |
668 | } |
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 | unsafe fn object_drop<E>(e: Own<ErrorImpl>) { |
690 | // Cast back to ErrorImpl<E> so that the allocator receives the correct |
691 | // Layout to deallocate the Box's memory. |
692 | let unerased_own: Own> = e.cast::<ErrorImpl<E>>(); |
693 | drop(unsafe { unerased_own.boxed() }); |
694 | } |
695 | |
696 | // Safety: requires layout of *e to match ErrorImpl<E>. |
697 | unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) { |
698 | // Drop the fields of ErrorImpl other than E as well as the Box allocation, |
699 | // without dropping E itself. This is used by downcast after doing a |
700 | // ptr::read to take ownership of the E. |
701 | let _ = target; |
702 | let unerased_own: Own>> = e.cast::<ErrorImpl<ManuallyDrop<E>>>(); |
703 | drop(unsafe { unerased_own.boxed() }); |
704 | } |
705 | |
706 | // Safety: requires layout of *e to match ErrorImpl<E>. |
707 | unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static> |
708 | where |
709 | E: StdError + Send + Sync + 'static, |
710 | { |
711 | // Attach E's native StdError vtable onto a pointer to self._object. |
712 | |
713 | let unerased_ref: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>(); |
714 | |
715 | #[cfg (not(anyhow_no_ptr_addr_of))] |
716 | return Ref::from_raw(ptr:unsafe { |
717 | NonNull::new_unchecked(ptr:ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) |
718 | }); |
719 | |
720 | #[cfg (anyhow_no_ptr_addr_of)] |
721 | return Ref::new(unsafe { &unerased_ref.deref()._object }); |
722 | } |
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 | unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static> |
738 | where |
739 | E: StdError + Send + Sync + 'static, |
740 | { |
741 | // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below. |
742 | let unerased_own: Own> = e.cast::<ErrorImpl<E>>(); |
743 | unsafe { unerased_own.boxed() } |
744 | } |
745 | |
746 | // Safety: requires layout of *e to match ErrorImpl<E>. |
747 | unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
748 | where |
749 | E: 'static, |
750 | { |
751 | 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 | let unerased_ref: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>(); |
756 | |
757 | #[cfg (not(anyhow_no_ptr_addr_of))] |
758 | return Some( |
759 | RefRef<'_, E>::from_raw(ptr:unsafe { |
760 | NonNull::new_unchecked(ptr:ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) |
761 | }) |
762 | .cast::<()>(), |
763 | ); |
764 | |
765 | #[cfg (anyhow_no_ptr_addr_of)] |
766 | return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>()); |
767 | } else { |
768 | None |
769 | } |
770 | } |
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 | unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
801 | where |
802 | C: 'static, |
803 | E: 'static, |
804 | { |
805 | if TypeId::of::<C>() == target { |
806 | let unerased_ref: Ref<'_, ErrorImpl>> = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
807 | let unerased: &ErrorImpl> = unsafe { unerased_ref.deref() }; |
808 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
809 | } else if TypeId::of::<E>() == target { |
810 | let unerased_ref: Ref<'_, ErrorImpl>> = e.cast::<ErrorImpl<ContextError<C, E>>>(); |
811 | let unerased: &ErrorImpl> = unsafe { unerased_ref.deref() }; |
812 | Some(Ref::new(&unerased._object.error).cast::<()>()) |
813 | } else { |
814 | None |
815 | } |
816 | } |
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 | unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId) |
841 | where |
842 | C: 'static, |
843 | E: 'static, |
844 | { |
845 | // Called after downcasting by value to either the C or the E and doing a |
846 | // ptr::read to take ownership of that value. |
847 | if TypeId::of::<C>() == target { |
848 | let unerased_own: Own>> = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>(); |
849 | drop(unsafe { unerased_own.boxed() }); |
850 | } else { |
851 | let unerased_own: Own>> = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>(); |
852 | drop(unsafe { unerased_own.boxed() }); |
853 | } |
854 | } |
855 | |
856 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
857 | unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
858 | where |
859 | C: 'static, |
860 | { |
861 | let unerased_ref: Ref<'_, ErrorImpl>> = e.cast::<ErrorImpl<ContextError<C, Error>>>(); |
862 | let unerased: &ErrorImpl> = unsafe { unerased_ref.deref() }; |
863 | if TypeId::of::<C>() == target { |
864 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
865 | } else { |
866 | // Recurse down the context chain per the inner error's vtable. |
867 | let source: &Error = &unerased._object.error; |
868 | unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) } |
869 | } |
870 | } |
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 | unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId) |
891 | where |
892 | C: 'static, |
893 | { |
894 | // Called after downcasting by value to either the C or one of the causes |
895 | // and doing a ptr::read to take ownership of that value. |
896 | if TypeId::of::<C>() == target { |
897 | let unerased_own: Own>> = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>(); |
898 | // Drop the entire rest of the data structure rooted in the next Error. |
899 | drop(unsafe { unerased_own.boxed() }); |
900 | } else { |
901 | let unerased_own: Own>> = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>(); |
902 | let unerased: Box>> = unsafe { unerased_own.boxed() }; |
903 | // Read the Own<ErrorImpl> from the next error. |
904 | let inner: Own = unerased._object.error.inner; |
905 | drop(unerased); |
906 | let vtable: &'static ErrorVTable = unsafe { vtable(inner.ptr) }; |
907 | // Recursively drop the next error using the same target typeid. |
908 | unsafe { (vtable.object_drop_rest)(inner, target) }; |
909 | } |
910 | } |
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 | unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable { |
943 | // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl. |
944 | unsafe { *(p.as_ptr() as *const &'static ErrorVTable) } |
945 | } |
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 | fn erase(&self) -> Ref<ErrorImpl> { |
957 | // Erase the concrete type of E but preserve the vtable in self.vtable |
958 | // for manipulating the resulting thin pointer. This is analogous to an |
959 | // unsize coercion. |
960 | Ref::new(self).cast::<ErrorImpl>() |
961 | } |
962 | } |
963 | |
964 | impl ErrorImpl { |
965 | pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) { |
966 | // Use vtable to attach E's native StdError vtable for the right |
967 | // original type E. |
968 | unsafe { (vtable(this.ptr).object_ref)(this).deref() } |
969 | } |
970 | |
971 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
972 | pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) { |
973 | // Use vtable to attach E's native StdError vtable for the right |
974 | // original type E. |
975 | |
976 | #[cfg (not(anyhow_no_ptr_addr_of))] |
977 | return unsafe { |
978 | (vtable(this.ptr).object_ref)(this.by_ref()) |
979 | .by_mut() |
980 | .deref_mut() |
981 | }; |
982 | |
983 | #[cfg (anyhow_no_ptr_addr_of)] |
984 | return unsafe { (vtable(this.ptr).object_mut)(this) }; |
985 | } |
986 | |
987 | #[cfg (any(std_backtrace, feature = "backtrace" ))] |
988 | pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace { |
989 | // This unwrap can only panic if the underlying error's backtrace method |
990 | // is nondeterministic, which would only happen in maliciously |
991 | // constructed code. |
992 | unsafe { this.deref() } |
993 | .backtrace |
994 | .as_ref() |
995 | .or_else(|| { |
996 | #[cfg (error_generic_member_access)] |
997 | return error::request_ref::<Backtrace>(unsafe { Self::error(this) }); |
998 | #[cfg (not(error_generic_member_access))] |
999 | return unsafe { (vtable(this.ptr).object_backtrace)(this) }; |
1000 | }) |
1001 | .expect("backtrace capture failed" ) |
1002 | } |
1003 | |
1004 | #[cfg (error_generic_member_access)] |
1005 | unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) { |
1006 | if let Some(backtrace) = unsafe { &this.deref().backtrace } { |
1007 | request.provide_ref(backtrace); |
1008 | } |
1009 | unsafe { Self::error(this) }.provide(request); |
1010 | } |
1011 | |
1012 | #[cold ] |
1013 | pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain { |
1014 | Chain::new(unsafe { Self::error(this) }) |
1015 | } |
1016 | } |
1017 | |
1018 | impl<E> StdError for ErrorImpl<E> |
1019 | where |
1020 | E: StdError, |
1021 | { |
1022 | fn source(&self) -> Option<&(dyn StdError + 'static)> { |
1023 | unsafe { ErrorImpl::error(self.erase()).source() } |
1024 | } |
1025 | |
1026 | #[cfg (error_generic_member_access)] |
1027 | fn provide<'a>(&'a self, request: &mut Request<'a>) { |
1028 | unsafe { ErrorImpl::provide(self.erase(), request) } |
1029 | } |
1030 | } |
1031 | |
1032 | impl<E> Debug for ErrorImpl<E> |
1033 | where |
1034 | E: Debug, |
1035 | { |
1036 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
1037 | unsafe { ErrorImpl::debug(self.erase(), f:formatter) } |
1038 | } |
1039 | } |
1040 | |
1041 | impl<E> Display for ErrorImpl<E> |
1042 | where |
1043 | E: Display, |
1044 | { |
1045 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
1046 | unsafe { Display::fmt(self:ErrorImpl::error(self.erase()), f:formatter) } |
1047 | } |
1048 | } |
1049 | |
1050 | impl From<Error> for Box<dyn StdError + Send + Sync + 'static> { |
1051 | #[cold ] |
1052 | fn from(error: Error) -> Self { |
1053 | let outer: ManuallyDrop = ManuallyDrop::new(error); |
1054 | unsafe { |
1055 | // Use vtable to attach ErrorImpl<E>'s native StdError vtable for |
1056 | // the right original type E. |
1057 | (vtable(outer.inner.ptr).object_boxed)(outer.inner) |
1058 | } |
1059 | } |
1060 | } |
1061 | |
1062 | impl From<Error> for Box<dyn StdError + Send + 'static> { |
1063 | fn from(error: Error) -> Self { |
1064 | Box::<dyn StdError + Send + Sync>::from(error) |
1065 | } |
1066 | } |
1067 | |
1068 | impl From<Error> for Box<dyn StdError + 'static> { |
1069 | fn from(error: Error) -> Self { |
1070 | Box::<dyn StdError + Send + Sync>::from(error) |
1071 | } |
1072 | } |
1073 | |
1074 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
1075 | impl AsRef<dyn StdError + Send + Sync> for Error { |
1076 | fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) { |
1077 | &**self |
1078 | } |
1079 | } |
1080 | |
1081 | #[cfg (any(feature = "std" , not(anyhow_no_core_error)))] |
1082 | impl AsRef<dyn StdError> for Error { |
1083 | fn as_ref(&self) -> &(dyn StdError + 'static) { |
1084 | &**self |
1085 | } |
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 {} |
1093 | |