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