1 use crate::alloc::Box;
2 use crate::backtrace::Backtrace;
3 use crate::chain::Chain;
4 use crate::{Error, StdError};
5 use core::any::TypeId;
6 use core::fmt::{self, Debug, Display};
7 use core::mem::{self, ManuallyDrop};
8 use core::ptr::{self, NonNull};
9
10 #[cfg(feature = "std")]
11 use core::ops::{Deref, DerefMut};
12
13 impl Error {
14 /// Create a new error object from any error type.
15 ///
16 /// The error type must be threadsafe and `'static`, so that the `Error`
17 /// will be as well.
18 ///
19 /// If the error type does not provide a backtrace, a backtrace will be
20 /// created here to ensure that a backtrace exists.
21 #[cfg(feature = "std")]
22 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
new<E>(error: E) -> Self where E: StdError + Send + Sync + 'static,23 pub fn new<E>(error: E) -> Self
24 where
25 E: StdError + Send + Sync + 'static,
26 {
27 let backtrace = backtrace_if_absent!(error);
28 Error::from_std(error, backtrace)
29 }
30
31 /// Create a new error object from a printable error message.
32 ///
33 /// If the argument implements std::error::Error, prefer `Error::new`
34 /// instead which preserves the underlying error's cause chain and
35 /// backtrace. If the argument may or may not implement std::error::Error
36 /// now or in the future, use `anyhow!(err)` which handles either way
37 /// correctly.
38 ///
39 /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
40 /// convenient in places where a function is preferable over a macro, such
41 /// as iterator or stream combinators:
42 ///
43 /// ```
44 /// # mod ffi {
45 /// # pub struct Input;
46 /// # pub struct Output;
47 /// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
48 /// # unimplemented!()
49 /// # }
50 /// # }
51 /// #
52 /// # use ffi::{Input, Output};
53 /// #
54 /// use anyhow::{Error, Result};
55 /// use futures::stream::{Stream, StreamExt, TryStreamExt};
56 ///
57 /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
58 /// where
59 /// S: Stream<Item = Input>,
60 /// {
61 /// stream
62 /// .then(ffi::do_some_work) // returns Result<Output, &str>
63 /// .map_err(Error::msg)
64 /// .try_collect()
65 /// .await
66 /// }
67 /// ```
msg<M>(message: M) -> Self where M: Display + Debug + Send + Sync + 'static,68 pub fn msg<M>(message: M) -> Self
69 where
70 M: Display + Debug + Send + Sync + 'static,
71 {
72 Error::from_adhoc(message, backtrace!())
73 }
74
75 #[cfg(feature = "std")]
from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self where E: StdError + Send + Sync + 'static,76 pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
77 where
78 E: StdError + Send + Sync + 'static,
79 {
80 let vtable = &ErrorVTable {
81 object_drop: object_drop::<E>,
82 object_ref: object_ref::<E>,
83 #[cfg(feature = "std")]
84 object_mut: object_mut::<E>,
85 object_boxed: object_boxed::<E>,
86 object_downcast: object_downcast::<E>,
87 object_drop_rest: object_drop_front::<E>,
88 };
89
90 // Safety: passing vtable that operates on the right type E.
91 unsafe { Error::construct(error, vtable, backtrace) }
92 }
93
from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self where M: Display + Debug + Send + Sync + 'static,94 pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
95 where
96 M: Display + Debug + Send + Sync + 'static,
97 {
98 use crate::wrapper::MessageError;
99 let error: MessageError<M> = MessageError(message);
100 let vtable = &ErrorVTable {
101 object_drop: object_drop::<MessageError<M>>,
102 object_ref: object_ref::<MessageError<M>>,
103 #[cfg(feature = "std")]
104 object_mut: object_mut::<MessageError<M>>,
105 object_boxed: object_boxed::<MessageError<M>>,
106 object_downcast: object_downcast::<M>,
107 object_drop_rest: object_drop_front::<M>,
108 };
109
110 // Safety: MessageError is repr(transparent) so it is okay for the
111 // vtable to allow casting the MessageError<M> to M.
112 unsafe { Error::construct(error, vtable, backtrace) }
113 }
114
from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self where M: Display + Send + Sync + 'static,115 pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
116 where
117 M: Display + Send + Sync + 'static,
118 {
119 use crate::wrapper::DisplayError;
120 let error: DisplayError<M> = DisplayError(message);
121 let vtable = &ErrorVTable {
122 object_drop: object_drop::<DisplayError<M>>,
123 object_ref: object_ref::<DisplayError<M>>,
124 #[cfg(feature = "std")]
125 object_mut: object_mut::<DisplayError<M>>,
126 object_boxed: object_boxed::<DisplayError<M>>,
127 object_downcast: object_downcast::<M>,
128 object_drop_rest: object_drop_front::<M>,
129 };
130
131 // Safety: DisplayError is repr(transparent) so it is okay for the
132 // vtable to allow casting the DisplayError<M> to M.
133 unsafe { Error::construct(error, vtable, backtrace) }
134 }
135
136 #[cfg(feature = "std")]
from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self where C: Display + Send + Sync + 'static, E: StdError + Send + Sync + 'static,137 pub(crate) fn from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self
138 where
139 C: Display + Send + Sync + 'static,
140 E: StdError + Send + Sync + 'static,
141 {
142 let error: ContextError<C, E> = ContextError { context, error };
143
144 let vtable = &ErrorVTable {
145 object_drop: object_drop::<ContextError<C, E>>,
146 object_ref: object_ref::<ContextError<C, E>>,
147 #[cfg(feature = "std")]
148 object_mut: object_mut::<ContextError<C, E>>,
149 object_boxed: object_boxed::<ContextError<C, E>>,
150 object_downcast: context_downcast::<C, E>,
151 object_drop_rest: context_drop_rest::<C, E>,
152 };
153
154 // Safety: passing vtable that operates on the right type.
155 unsafe { Error::construct(error, vtable, backtrace) }
156 }
157
158 #[cfg(feature = "std")]
from_boxed( error: Box<dyn StdError + Send + Sync>, backtrace: Option<Backtrace>, ) -> Self159 pub(crate) fn from_boxed(
160 error: Box<dyn StdError + Send + Sync>,
161 backtrace: Option<Backtrace>,
162 ) -> Self {
163 use crate::wrapper::BoxedError;
164 let error = BoxedError(error);
165 let vtable = &ErrorVTable {
166 object_drop: object_drop::<BoxedError>,
167 object_ref: object_ref::<BoxedError>,
168 #[cfg(feature = "std")]
169 object_mut: object_mut::<BoxedError>,
170 object_boxed: object_boxed::<BoxedError>,
171 object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
172 object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
173 };
174
175 // Safety: BoxedError is repr(transparent) so it is okay for the vtable
176 // to allow casting to Box<dyn StdError + Send + Sync>.
177 unsafe { Error::construct(error, vtable, backtrace) }
178 }
179
180 // Takes backtrace as argument rather than capturing it here so that the
181 // user sees one fewer layer of wrapping noise in the backtrace.
182 //
183 // Unsafe because the given vtable must have sensible behavior on the error
184 // value of type E.
construct<E>( error: E, vtable: &'static ErrorVTable, backtrace: Option<Backtrace>, ) -> Self where E: StdError + Send + Sync + 'static,185 unsafe fn construct<E>(
186 error: E,
187 vtable: &'static ErrorVTable,
188 backtrace: Option<Backtrace>,
189 ) -> Self
190 where
191 E: StdError + Send + Sync + 'static,
192 {
193 let inner = Box::new(ErrorImpl {
194 vtable,
195 backtrace,
196 _object: error,
197 });
198 // Erase the concrete type of E from the compile-time type system. This
199 // is equivalent to the safe unsize coersion from Box<ErrorImpl<E>> to
200 // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
201 // result is a thin pointer. The necessary behavior for manipulating the
202 // underlying ErrorImpl<E> is preserved in the vtable provided by the
203 // caller rather than a builtin fat pointer vtable.
204 let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner);
205 let inner = ManuallyDrop::new(erased);
206 Error { inner }
207 }
208
209 /// Wrap the error value with additional context.
210 ///
211 /// For attaching context to a `Result` as it is propagated, the
212 /// [`Context`][crate::Context] extension trait may be more convenient than
213 /// this function.
214 ///
215 /// The primary reason to use `error.context(...)` instead of
216 /// `result.context(...)` via the `Context` trait would be if the context
217 /// needs to depend on some data held by the underlying error:
218 ///
219 /// ```
220 /// # use std::fmt::{self, Debug, Display};
221 /// #
222 /// # type T = ();
223 /// #
224 /// # impl std::error::Error for ParseError {}
225 /// # impl Debug for ParseError {
226 /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
227 /// # unimplemented!()
228 /// # }
229 /// # }
230 /// # impl Display for ParseError {
231 /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
232 /// # unimplemented!()
233 /// # }
234 /// # }
235 /// #
236 /// use anyhow::Result;
237 /// use std::fs::File;
238 /// use std::path::Path;
239 ///
240 /// struct ParseError {
241 /// line: usize,
242 /// column: usize,
243 /// }
244 ///
245 /// fn parse_impl(file: File) -> Result<T, ParseError> {
246 /// # const IGNORE: &str = stringify! {
247 /// ...
248 /// # };
249 /// # unimplemented!()
250 /// }
251 ///
252 /// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
253 /// let file = File::open(&path)?;
254 /// parse_impl(file).map_err(|error| {
255 /// let context = format!(
256 /// "only the first {} lines of {} are valid",
257 /// error.line, path.as_ref().display(),
258 /// );
259 /// anyhow::Error::new(error).context(context)
260 /// })
261 /// }
262 /// ```
context<C>(self, context: C) -> Self where C: Display + Send + Sync + 'static,263 pub fn context<C>(self, context: C) -> Self
264 where
265 C: Display + Send + Sync + 'static,
266 {
267 let error: ContextError<C, Error> = ContextError {
268 context,
269 error: self,
270 };
271
272 let vtable = &ErrorVTable {
273 object_drop: object_drop::<ContextError<C, Error>>,
274 object_ref: object_ref::<ContextError<C, Error>>,
275 #[cfg(feature = "std")]
276 object_mut: object_mut::<ContextError<C, Error>>,
277 object_boxed: object_boxed::<ContextError<C, Error>>,
278 object_downcast: context_chain_downcast::<C>,
279 object_drop_rest: context_chain_drop_rest::<C>,
280 };
281
282 // As the cause is anyhow::Error, we already have a backtrace for it.
283 let backtrace = None;
284
285 // Safety: passing vtable that operates on the right type.
286 unsafe { Error::construct(error, vtable, backtrace) }
287 }
288
289 /// Get the backtrace for this Error.
290 ///
291 /// Backtraces are only available on the nightly channel. Tracking issue:
292 /// [rust-lang/rust#53487][tracking].
293 ///
294 /// In order for the backtrace to be meaningful, one of the two environment
295 /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
296 /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
297 /// expensive to capture in Rust, so we don't necessarily want to be
298 /// capturing them all over the place all the time.
299 ///
300 /// - If you want panics and errors to both have backtraces, set
301 /// `RUST_BACKTRACE=1`;
302 /// - If you want only errors to have backtraces, set
303 /// `RUST_LIB_BACKTRACE=1`;
304 /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
305 /// `RUST_LIB_BACKTRACE=0`.
306 ///
307 /// [tracking]: https://github.com/rust-lang/rust/issues/53487
308 #[cfg(backtrace)]
backtrace(&self) -> &Backtrace309 pub fn backtrace(&self) -> &Backtrace {
310 self.inner.backtrace()
311 }
312
313 /// An iterator of the chain of source errors contained by this Error.
314 ///
315 /// This iterator will visit every error in the cause chain of this error
316 /// object, beginning with the error that this error object was created
317 /// from.
318 ///
319 /// # Example
320 ///
321 /// ```
322 /// use anyhow::Error;
323 /// use std::io;
324 ///
325 /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
326 /// for cause in error.chain() {
327 /// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
328 /// return Some(io_error.kind());
329 /// }
330 /// }
331 /// None
332 /// }
333 /// ```
334 #[cfg(feature = "std")]
chain(&self) -> Chain335 pub fn chain(&self) -> Chain {
336 self.inner.chain()
337 }
338
339 /// The lowest level cause of this error — this error's cause's
340 /// cause's cause etc.
341 ///
342 /// The root cause is the last error in the iterator produced by
343 /// [`chain()`][Error::chain].
344 #[cfg(feature = "std")]
root_cause(&self) -> &(dyn StdError + 'static)345 pub fn root_cause(&self) -> &(dyn StdError + 'static) {
346 let mut chain = self.chain();
347 let mut root_cause = chain.next().unwrap();
348 for cause in chain {
349 root_cause = cause;
350 }
351 root_cause
352 }
353
354 /// Returns true if `E` is the type held by this error object.
355 ///
356 /// For errors with context, this method returns true if `E` matches the
357 /// type of the context `C` **or** the type of the error on which the
358 /// context has been attached. For details about the interaction between
359 /// context and downcasting, [see here].
360 ///
361 /// [see here]: trait.Context.html#effect-on-downcasting
is<E>(&self) -> bool where E: Display + Debug + Send + Sync + 'static,362 pub fn is<E>(&self) -> bool
363 where
364 E: Display + Debug + Send + Sync + 'static,
365 {
366 self.downcast_ref::<E>().is_some()
367 }
368
369 /// Attempt to downcast the error object to a concrete type.
downcast<E>(self) -> Result<E, Self> where E: Display + Debug + Send + Sync + 'static,370 pub fn downcast<E>(self) -> Result<E, Self>
371 where
372 E: Display + Debug + Send + Sync + 'static,
373 {
374 let target = TypeId::of::<E>();
375 unsafe {
376 // Use vtable to find NonNull<()> which points to a value of type E
377 // somewhere inside the data structure.
378 let addr = match (self.inner.vtable.object_downcast)(&self.inner, target) {
379 Some(addr) => addr,
380 None => return Err(self),
381 };
382
383 // Prepare to read E out of the data structure. We'll drop the rest
384 // of the data structure separately so that E is not dropped.
385 let outer = ManuallyDrop::new(self);
386
387 // Read E from where the vtable found it.
388 let error = ptr::read(addr.cast::<E>().as_ptr());
389
390 // Read Box<ErrorImpl<()>> from self. Can't move it out because
391 // Error has a Drop impl which we want to not run.
392 let inner = ptr::read(&outer.inner);
393 let erased = ManuallyDrop::into_inner(inner);
394
395 // Drop rest of the data structure outside of E.
396 (erased.vtable.object_drop_rest)(erased, target);
397
398 Ok(error)
399 }
400 }
401
402 /// Downcast this error object by reference.
403 ///
404 /// # Example
405 ///
406 /// ```
407 /// # use anyhow::anyhow;
408 /// # use std::fmt::{self, Display};
409 /// # use std::task::Poll;
410 /// #
411 /// # #[derive(Debug)]
412 /// # enum DataStoreError {
413 /// # Censored(()),
414 /// # }
415 /// #
416 /// # impl Display for DataStoreError {
417 /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
418 /// # unimplemented!()
419 /// # }
420 /// # }
421 /// #
422 /// # impl std::error::Error for DataStoreError {}
423 /// #
424 /// # const REDACTED_CONTENT: () = ();
425 /// #
426 /// # let error = anyhow!("...");
427 /// # let root_cause = &error;
428 /// #
429 /// # let ret =
430 /// // If the error was caused by redaction, then return a tombstone instead
431 /// // of the content.
432 /// match root_cause.downcast_ref::<DataStoreError>() {
433 /// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
434 /// None => Err(error),
435 /// }
436 /// # ;
437 /// ```
downcast_ref<E>(&self) -> Option<&E> where E: Display + Debug + Send + Sync + 'static,438 pub fn downcast_ref<E>(&self) -> Option<&E>
439 where
440 E: Display + Debug + Send + Sync + 'static,
441 {
442 let target = TypeId::of::<E>();
443 unsafe {
444 // Use vtable to find NonNull<()> which points to a value of type E
445 // somewhere inside the data structure.
446 let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?;
447 Some(&*addr.cast::<E>().as_ptr())
448 }
449 }
450
451 /// Downcast this error object by mutable reference.
downcast_mut<E>(&mut self) -> Option<&mut E> where E: Display + Debug + Send + Sync + 'static,452 pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
453 where
454 E: Display + Debug + Send + Sync + 'static,
455 {
456 let target = TypeId::of::<E>();
457 unsafe {
458 // Use vtable to find NonNull<()> which points to a value of type E
459 // somewhere inside the data structure.
460 let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?;
461 Some(&mut *addr.cast::<E>().as_ptr())
462 }
463 }
464 }
465
466 #[cfg(feature = "std")]
467 impl<E> From<E> for Error
468 where
469 E: StdError + Send + Sync + 'static,
470 {
from(error: E) -> Self471 fn from(error: E) -> Self {
472 let backtrace = backtrace_if_absent!(error);
473 Error::from_std(error, backtrace)
474 }
475 }
476
477 #[cfg(feature = "std")]
478 impl Deref for Error {
479 type Target = dyn StdError + Send + Sync + 'static;
480
deref(&self) -> &Self::Target481 fn deref(&self) -> &Self::Target {
482 self.inner.error()
483 }
484 }
485
486 #[cfg(feature = "std")]
487 impl DerefMut for Error {
deref_mut(&mut self) -> &mut Self::Target488 fn deref_mut(&mut self) -> &mut Self::Target {
489 self.inner.error_mut()
490 }
491 }
492
493 impl Display for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result494 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
495 self.inner.display(formatter)
496 }
497 }
498
499 impl Debug for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result500 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
501 self.inner.debug(formatter)
502 }
503 }
504
505 impl Drop for Error {
drop(&mut self)506 fn drop(&mut self) {
507 unsafe {
508 // Read Box<ErrorImpl<()>> from self.
509 let inner = ptr::read(&self.inner);
510 let erased = ManuallyDrop::into_inner(inner);
511
512 // Invoke the vtable's drop behavior.
513 (erased.vtable.object_drop)(erased);
514 }
515 }
516 }
517
518 struct ErrorVTable {
519 object_drop: unsafe fn(Box<ErrorImpl<()>>),
520 object_ref: unsafe fn(&ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static),
521 #[cfg(feature = "std")]
522 object_mut: unsafe fn(&mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static),
523 object_boxed: unsafe fn(Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>,
524 object_downcast: unsafe fn(&ErrorImpl<()>, TypeId) -> Option<NonNull<()>>,
525 object_drop_rest: unsafe fn(Box<ErrorImpl<()>>, TypeId),
526 }
527
528 // Safety: requires layout of *e to match ErrorImpl<E>.
object_drop<E>(e: Box<ErrorImpl<()>>)529 unsafe fn object_drop<E>(e: Box<ErrorImpl<()>>) {
530 // Cast back to ErrorImpl<E> so that the allocator receives the correct
531 // Layout to deallocate the Box's memory.
532 let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e);
533 drop(unerased);
534 }
535
536 // Safety: requires layout of *e to match ErrorImpl<E>.
object_drop_front<E>(e: Box<ErrorImpl<()>>, target: TypeId)537 unsafe fn object_drop_front<E>(e: Box<ErrorImpl<()>>, target: TypeId) {
538 // Drop the fields of ErrorImpl other than E as well as the Box allocation,
539 // without dropping E itself. This is used by downcast after doing a
540 // ptr::read to take ownership of the E.
541 let _ = target;
542 let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<ManuallyDrop<E>>>>(e);
543 drop(unerased);
544 }
545
546 // Safety: requires layout of *e to match ErrorImpl<E>.
object_ref<E>(e: &ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static) where E: StdError + Send + Sync + 'static,547 unsafe fn object_ref<E>(e: &ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static)
548 where
549 E: StdError + Send + Sync + 'static,
550 {
551 // Attach E's native StdError vtable onto a pointer to self._object.
552 &(*(e as *const ErrorImpl<()> as *const ErrorImpl<E>))._object
553 }
554
555 // Safety: requires layout of *e to match ErrorImpl<E>.
556 #[cfg(feature = "std")]
object_mut<E>(e: &mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static) where E: StdError + Send + Sync + 'static,557 unsafe fn object_mut<E>(e: &mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static)
558 where
559 E: StdError + Send + Sync + 'static,
560 {
561 // Attach E's native StdError vtable onto a pointer to self._object.
562 &mut (*(e as *mut ErrorImpl<()> as *mut ErrorImpl<E>))._object
563 }
564
565 // Safety: requires layout of *e to match ErrorImpl<E>.
object_boxed<E>(e: Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static> where E: StdError + Send + Sync + 'static,566 unsafe fn object_boxed<E>(e: Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>
567 where
568 E: StdError + Send + Sync + 'static,
569 {
570 // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
571 mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e)
572 }
573
574 // Safety: requires layout of *e to match ErrorImpl<E>.
object_downcast<E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where E: 'static,575 unsafe fn object_downcast<E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
576 where
577 E: 'static,
578 {
579 if TypeId::of::<E>() == target {
580 // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
581 // pointer to its E field.
582 let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<E>;
583 let addr = &(*unerased)._object as *const E as *mut ();
584 Some(NonNull::new_unchecked(addr))
585 } else {
586 None
587 }
588 }
589
590 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
591 #[cfg(feature = "std")]
context_downcast<C, E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where C: 'static, E: 'static,592 unsafe fn context_downcast<C, E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
593 where
594 C: 'static,
595 E: 'static,
596 {
597 if TypeId::of::<C>() == target {
598 let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>;
599 let addr = &(*unerased)._object.context as *const C as *mut ();
600 Some(NonNull::new_unchecked(addr))
601 } else if TypeId::of::<E>() == target {
602 let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>;
603 let addr = &(*unerased)._object.error as *const E as *mut ();
604 Some(NonNull::new_unchecked(addr))
605 } else {
606 None
607 }
608 }
609
610 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
611 #[cfg(feature = "std")]
context_drop_rest<C, E>(e: Box<ErrorImpl<()>>, target: TypeId) where C: 'static, E: 'static,612 unsafe fn context_drop_rest<C, E>(e: Box<ErrorImpl<()>>, target: TypeId)
613 where
614 C: 'static,
615 E: 'static,
616 {
617 // Called after downcasting by value to either the C or the E and doing a
618 // ptr::read to take ownership of that value.
619 if TypeId::of::<C>() == target {
620 let unerased = mem::transmute::<
621 Box<ErrorImpl<()>>,
622 Box<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>,
623 >(e);
624 drop(unerased);
625 } else {
626 let unerased = mem::transmute::<
627 Box<ErrorImpl<()>>,
628 Box<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>,
629 >(e);
630 drop(unerased);
631 }
632 }
633
634 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where C: 'static,635 unsafe fn context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
636 where
637 C: 'static,
638 {
639 if TypeId::of::<C>() == target {
640 let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
641 let addr = &(*unerased)._object.context as *const C as *mut ();
642 Some(NonNull::new_unchecked(addr))
643 } else {
644 // Recurse down the context chain per the inner error's vtable.
645 let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
646 let source = &(*unerased)._object.error;
647 (source.inner.vtable.object_downcast)(&source.inner, target)
648 }
649 }
650
651 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId) where C: 'static,652 unsafe fn context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId)
653 where
654 C: 'static,
655 {
656 // Called after downcasting by value to either the C or one of the causes
657 // and doing a ptr::read to take ownership of that value.
658 if TypeId::of::<C>() == target {
659 let unerased = mem::transmute::<
660 Box<ErrorImpl<()>>,
661 Box<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>,
662 >(e);
663 // Drop the entire rest of the data structure rooted in the next Error.
664 drop(unerased);
665 } else {
666 let unerased = mem::transmute::<
667 Box<ErrorImpl<()>>,
668 Box<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>,
669 >(e);
670 // Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
671 let inner = ptr::read(&unerased._object.error.inner);
672 drop(unerased);
673 let erased = ManuallyDrop::into_inner(inner);
674 // Recursively drop the next error using the same target typeid.
675 (erased.vtable.object_drop_rest)(erased, target);
676 }
677 }
678
679 // repr C to ensure that E remains in the final position.
680 #[repr(C)]
681 pub(crate) struct ErrorImpl<E> {
682 vtable: &'static ErrorVTable,
683 backtrace: Option<Backtrace>,
684 // NOTE: Don't use directly. Use only through vtable. Erased type may have
685 // different alignment.
686 _object: E,
687 }
688
689 // repr C to ensure that ContextError<C, E> has the same layout as
690 // ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
691 #[repr(C)]
692 pub(crate) struct ContextError<C, E> {
693 pub context: C,
694 pub error: E,
695 }
696
697 impl<E> ErrorImpl<E> {
erase(&self) -> &ErrorImpl<()>698 fn erase(&self) -> &ErrorImpl<()> {
699 // Erase the concrete type of E but preserve the vtable in self.vtable
700 // for manipulating the resulting thin pointer. This is analogous to an
701 // unsize coersion.
702 unsafe { &*(self as *const ErrorImpl<E> as *const ErrorImpl<()>) }
703 }
704 }
705
706 impl ErrorImpl<()> {
error(&self) -> &(dyn StdError + Send + Sync + 'static)707 pub(crate) fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
708 // Use vtable to attach E's native StdError vtable for the right
709 // original type E.
710 unsafe { &*(self.vtable.object_ref)(self) }
711 }
712
713 #[cfg(feature = "std")]
error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static)714 pub(crate) fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
715 // Use vtable to attach E's native StdError vtable for the right
716 // original type E.
717 unsafe { &mut *(self.vtable.object_mut)(self) }
718 }
719
720 #[cfg(backtrace)]
backtrace(&self) -> &Backtrace721 pub(crate) fn backtrace(&self) -> &Backtrace {
722 // This unwrap can only panic if the underlying error's backtrace method
723 // is nondeterministic, which would only happen in maliciously
724 // constructed code.
725 self.backtrace
726 .as_ref()
727 .or_else(|| self.error().backtrace())
728 .expect("backtrace capture failed")
729 }
730
chain(&self) -> Chain731 pub(crate) fn chain(&self) -> Chain {
732 Chain::new(self.error())
733 }
734 }
735
736 impl<E> StdError for ErrorImpl<E>
737 where
738 E: StdError,
739 {
740 #[cfg(backtrace)]
backtrace(&self) -> Option<&Backtrace>741 fn backtrace(&self) -> Option<&Backtrace> {
742 Some(self.erase().backtrace())
743 }
744
source(&self) -> Option<&(dyn StdError + 'static)>745 fn source(&self) -> Option<&(dyn StdError + 'static)> {
746 self.erase().error().source()
747 }
748 }
749
750 impl<E> Debug for ErrorImpl<E>
751 where
752 E: Debug,
753 {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result754 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
755 self.erase().debug(formatter)
756 }
757 }
758
759 impl<E> Display for ErrorImpl<E>
760 where
761 E: Display,
762 {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result763 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
764 Display::fmt(&self.erase().error(), formatter)
765 }
766 }
767
768 impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
from(error: Error) -> Self769 fn from(error: Error) -> Self {
770 let outer = ManuallyDrop::new(error);
771 unsafe {
772 // Read Box<ErrorImpl<()>> from error. Can't move it out because
773 // Error has a Drop impl which we want to not run.
774 let inner = ptr::read(&outer.inner);
775 let erased = ManuallyDrop::into_inner(inner);
776
777 // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
778 // the right original type E.
779 (erased.vtable.object_boxed)(erased)
780 }
781 }
782 }
783
784 impl From<Error> for Box<dyn StdError + 'static> {
from(error: Error) -> Self785 fn from(error: Error) -> Self {
786 Box::<dyn StdError + Send + Sync>::from(error)
787 }
788 }
789
790 #[cfg(feature = "std")]
791 impl AsRef<dyn StdError + Send + Sync> for Error {
as_ref(&self) -> &(dyn StdError + Send + Sync + 'static)792 fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
793 &**self
794 }
795 }
796
797 #[cfg(feature = "std")]
798 impl AsRef<dyn StdError> for Error {
as_ref(&self) -> &(dyn StdError + 'static)799 fn as_ref(&self) -> &(dyn StdError + 'static) {
800 &**self
801 }
802 }
803