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