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 | 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 | #[cfg (backtrace)] |
15 | use std::error::{self, Request}; |
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 — 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 | #[cfg (backtrace)] |
527 | pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) { |
528 | unsafe { ErrorImpl::provide(self.inner.by_ref(), request) } |
529 | } |
530 | |
531 | // Called by thiserror when you have `#[source] anyhow::Error`. This provide |
532 | // implementation includes the anyhow::Error's Backtrace if any, unlike |
533 | // deref'ing to dyn Error where the provide implementation would include |
534 | // only the original error's Backtrace from before it got wrapped into an |
535 | // anyhow::Error. |
536 | #[cfg (backtrace)] |
537 | #[doc (hidden)] |
538 | pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) { |
539 | Self::provide(self, request); |
540 | } |
541 | } |
542 | |
543 | #[cfg (feature = "std" )] |
544 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
545 | impl<E> From<E> for Error |
546 | where |
547 | E: StdError + Send + Sync + 'static, |
548 | { |
549 | #[cold ] |
550 | fn from(error: E) -> Self { |
551 | let backtrace: Option = backtrace_if_absent!(&error); |
552 | Error::from_std(error, backtrace) |
553 | } |
554 | } |
555 | |
556 | #[cfg (feature = "std" )] |
557 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
558 | impl Deref for Error { |
559 | type Target = dyn StdError + Send + Sync + 'static; |
560 | |
561 | fn deref(&self) -> &Self::Target { |
562 | unsafe { ErrorImpl::error(self.inner.by_ref()) } |
563 | } |
564 | } |
565 | |
566 | #[cfg (feature = "std" )] |
567 | #[cfg_attr (doc_cfg, doc(cfg(feature = "std" )))] |
568 | impl DerefMut for Error { |
569 | fn deref_mut(&mut self) -> &mut Self::Target { |
570 | unsafe { ErrorImpl::error_mut(self.inner.by_mut()) } |
571 | } |
572 | } |
573 | |
574 | impl Display for Error { |
575 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
576 | unsafe { ErrorImpl::display(self.inner.by_ref(), f:formatter) } |
577 | } |
578 | } |
579 | |
580 | impl Debug for Error { |
581 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
582 | unsafe { ErrorImpl::debug(self.inner.by_ref(), f:formatter) } |
583 | } |
584 | } |
585 | |
586 | impl Drop for Error { |
587 | fn drop(&mut self) { |
588 | unsafe { |
589 | // Invoke the vtable's drop behavior. |
590 | (vtable(self.inner.ptr).object_drop)(self.inner); |
591 | } |
592 | } |
593 | } |
594 | |
595 | struct ErrorVTable { |
596 | object_drop: unsafe fn(Own<ErrorImpl>), |
597 | object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>, |
598 | #[cfg (all(feature = "std" , anyhow_no_ptr_addr_of))] |
599 | object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static), |
600 | object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>, |
601 | object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>, |
602 | #[cfg (anyhow_no_ptr_addr_of)] |
603 | object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>, |
604 | object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId), |
605 | #[cfg (all(not(backtrace), feature = "backtrace" ))] |
606 | object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>, |
607 | } |
608 | |
609 | // Safety: requires layout of *e to match ErrorImpl<E>. |
610 | unsafe fn object_drop<E>(e: Own<ErrorImpl>) { |
611 | // Cast back to ErrorImpl<E> so that the allocator receives the correct |
612 | // Layout to deallocate the Box's memory. |
613 | let unerased: Box> = e.cast::<ErrorImpl<E>>().boxed(); |
614 | drop(unerased); |
615 | } |
616 | |
617 | // Safety: requires layout of *e to match ErrorImpl<E>. |
618 | unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) { |
619 | // Drop the fields of ErrorImpl other than E as well as the Box allocation, |
620 | // without dropping E itself. This is used by downcast after doing a |
621 | // ptr::read to take ownership of the E. |
622 | let _ = target; |
623 | let unerased: Box>> = e.cast::<ErrorImpl<ManuallyDrop<E>>>().boxed(); |
624 | drop(unerased); |
625 | } |
626 | |
627 | // Safety: requires layout of *e to match ErrorImpl<E>. |
628 | unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static> |
629 | where |
630 | E: StdError + Send + Sync + 'static, |
631 | { |
632 | // Attach E's native StdError vtable onto a pointer to self._object. |
633 | |
634 | let unerased: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>(); |
635 | |
636 | #[cfg (not(anyhow_no_ptr_addr_of))] |
637 | return Ref::from_raw(ptr:NonNull::new_unchecked( |
638 | ptr:ptr::addr_of!((*unerased.as_ptr())._object) as *mut E, |
639 | )); |
640 | |
641 | #[cfg (anyhow_no_ptr_addr_of)] |
642 | return Ref::new(&unerased.deref()._object); |
643 | } |
644 | |
645 | // Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived |
646 | // from a `&mut` |
647 | #[cfg (all(feature = "std" , anyhow_no_ptr_addr_of))] |
648 | unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static) |
649 | where |
650 | E: StdError + Send + Sync + 'static, |
651 | { |
652 | // Attach E's native StdError vtable onto a pointer to self._object. |
653 | &mut e.cast::<ErrorImpl<E>>().deref_mut()._object |
654 | } |
655 | |
656 | // Safety: requires layout of *e to match ErrorImpl<E>. |
657 | unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static> |
658 | where |
659 | E: StdError + Send + Sync + 'static, |
660 | { |
661 | // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below. |
662 | e.cast::<ErrorImpl<E>>().boxed() |
663 | } |
664 | |
665 | // Safety: requires layout of *e to match ErrorImpl<E>. |
666 | unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
667 | where |
668 | E: 'static, |
669 | { |
670 | if TypeId::of::<E>() == target { |
671 | // Caller is looking for an E pointer and e is ErrorImpl<E>, take a |
672 | // pointer to its E field. |
673 | |
674 | let unerased: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>(); |
675 | |
676 | #[cfg (not(anyhow_no_ptr_addr_of))] |
677 | return Some( |
678 | RefRef<'_, E>::from_raw(ptr:NonNull::new_unchecked( |
679 | ptr:ptr::addr_of!((*unerased.as_ptr())._object) as *mut E, |
680 | )) |
681 | .cast::<()>(), |
682 | ); |
683 | |
684 | #[cfg (anyhow_no_ptr_addr_of)] |
685 | return Some(Ref::new(&unerased.deref()._object).cast::<()>()); |
686 | } else { |
687 | None |
688 | } |
689 | } |
690 | |
691 | // Safety: requires layout of *e to match ErrorImpl<E>. |
692 | #[cfg (anyhow_no_ptr_addr_of)] |
693 | unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
694 | where |
695 | E: 'static, |
696 | { |
697 | if TypeId::of::<E>() == target { |
698 | // Caller is looking for an E pointer and e is ErrorImpl<E>, take a |
699 | // pointer to its E field. |
700 | let unerased = e.cast::<ErrorImpl<E>>().deref_mut(); |
701 | Some(Mut::new(&mut unerased._object).cast::<()>()) |
702 | } else { |
703 | None |
704 | } |
705 | } |
706 | |
707 | #[cfg (all(not(backtrace), feature = "backtrace" ))] |
708 | fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> { |
709 | let _ = e; |
710 | None |
711 | } |
712 | |
713 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
714 | #[cfg (feature = "std" )] |
715 | unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
716 | where |
717 | C: 'static, |
718 | E: 'static, |
719 | { |
720 | if TypeId::of::<C>() == target { |
721 | let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, E>>>().deref(); |
722 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
723 | } else if TypeId::of::<E>() == target { |
724 | let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, E>>>().deref(); |
725 | Some(Ref::new(&unerased._object.error).cast::<()>()) |
726 | } else { |
727 | None |
728 | } |
729 | } |
730 | |
731 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
732 | #[cfg (all(feature = "std" , anyhow_no_ptr_addr_of))] |
733 | unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
734 | where |
735 | C: 'static, |
736 | E: 'static, |
737 | { |
738 | if TypeId::of::<C>() == target { |
739 | let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut(); |
740 | Some(Mut::new(&mut unerased._object.context).cast::<()>()) |
741 | } else if TypeId::of::<E>() == target { |
742 | let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut(); |
743 | Some(Mut::new(&mut unerased._object.error).cast::<()>()) |
744 | } else { |
745 | None |
746 | } |
747 | } |
748 | |
749 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. |
750 | #[cfg (feature = "std" )] |
751 | unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId) |
752 | where |
753 | C: 'static, |
754 | E: 'static, |
755 | { |
756 | // Called after downcasting by value to either the C or the E and doing a |
757 | // ptr::read to take ownership of that value. |
758 | if TypeId::of::<C>() == target { |
759 | let unerased: Box>> = eOwn>> |
760 | .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>() |
761 | .boxed(); |
762 | drop(unerased); |
763 | } else { |
764 | let unerased: Box>> = eOwn>> |
765 | .cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>() |
766 | .boxed(); |
767 | drop(unerased); |
768 | } |
769 | } |
770 | |
771 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
772 | unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>> |
773 | where |
774 | C: 'static, |
775 | { |
776 | let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref(); |
777 | if TypeId::of::<C>() == target { |
778 | Some(Ref::new(&unerased._object.context).cast::<()>()) |
779 | } else { |
780 | // Recurse down the context chain per the inner error's vtable. |
781 | let source: &Error = &unerased._object.error; |
782 | (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) |
783 | } |
784 | } |
785 | |
786 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
787 | #[cfg (anyhow_no_ptr_addr_of)] |
788 | unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>> |
789 | where |
790 | C: 'static, |
791 | { |
792 | let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref_mut(); |
793 | if TypeId::of::<C>() == target { |
794 | Some(Mut::new(&mut unerased._object.context).cast::<()>()) |
795 | } else { |
796 | // Recurse down the context chain per the inner error's vtable. |
797 | let source = &mut unerased._object.error; |
798 | (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) |
799 | } |
800 | } |
801 | |
802 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
803 | unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId) |
804 | where |
805 | C: 'static, |
806 | { |
807 | // Called after downcasting by value to either the C or one of the causes |
808 | // and doing a ptr::read to take ownership of that value. |
809 | if TypeId::of::<C>() == target { |
810 | let unerased: Box>> = eOwn>> |
811 | .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>() |
812 | .boxed(); |
813 | // Drop the entire rest of the data structure rooted in the next Error. |
814 | drop(unerased); |
815 | } else { |
816 | let unerased: Box>> = eOwn>> |
817 | .cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>() |
818 | .boxed(); |
819 | // Read the Own<ErrorImpl> from the next error. |
820 | let inner: Own = unerased._object.error.inner; |
821 | drop(unerased); |
822 | let vtable: &ErrorVTable = vtable(inner.ptr); |
823 | // Recursively drop the next error using the same target typeid. |
824 | (vtable.object_drop_rest)(inner, target); |
825 | } |
826 | } |
827 | |
828 | // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. |
829 | #[cfg (all(not(backtrace), feature = "backtrace" ))] |
830 | #[allow (clippy::unnecessary_wraps)] |
831 | unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace> |
832 | where |
833 | C: 'static, |
834 | { |
835 | let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref(); |
836 | let backtrace = ErrorImpl::backtrace(unerased._object.error.inner.by_ref()); |
837 | Some(backtrace) |
838 | } |
839 | |
840 | // NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor |
841 | // of raw pointers and `NonNull`. |
842 | // repr C to ensure that E remains in the final position. |
843 | #[repr (C)] |
844 | pub(crate) struct ErrorImpl<E = ()> { |
845 | vtable: &'static ErrorVTable, |
846 | backtrace: Option<Backtrace>, |
847 | // NOTE: Don't use directly. Use only through vtable. Erased type may have |
848 | // different alignment. |
849 | _object: E, |
850 | } |
851 | |
852 | // Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but |
853 | // avoids converting `p` into a reference. |
854 | unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable { |
855 | // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl. |
856 | *(p.as_ptr() as *const &'static ErrorVTable) |
857 | } |
858 | |
859 | // repr C to ensure that ContextError<C, E> has the same layout as |
860 | // ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>. |
861 | #[repr (C)] |
862 | pub(crate) struct ContextError<C, E> { |
863 | pub context: C, |
864 | pub error: E, |
865 | } |
866 | |
867 | impl<E> ErrorImpl<E> { |
868 | fn erase(&self) -> Ref<ErrorImpl> { |
869 | // Erase the concrete type of E but preserve the vtable in self.vtable |
870 | // for manipulating the resulting thin pointer. This is analogous to an |
871 | // unsize coercion. |
872 | Ref::new(self).cast::<ErrorImpl>() |
873 | } |
874 | } |
875 | |
876 | impl ErrorImpl { |
877 | pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) { |
878 | // Use vtable to attach E's native StdError vtable for the right |
879 | // original type E. |
880 | (vtable(this.ptr).object_ref)(this).deref() |
881 | } |
882 | |
883 | #[cfg (feature = "std" )] |
884 | pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) { |
885 | // Use vtable to attach E's native StdError vtable for the right |
886 | // original type E. |
887 | |
888 | #[cfg (not(anyhow_no_ptr_addr_of))] |
889 | return (vtable(this.ptr).object_ref)(this.by_ref()) |
890 | .by_mut() |
891 | .deref_mut(); |
892 | |
893 | #[cfg (anyhow_no_ptr_addr_of)] |
894 | return (vtable(this.ptr).object_mut)(this); |
895 | } |
896 | |
897 | #[cfg (any(backtrace, feature = "backtrace" ))] |
898 | pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace { |
899 | // This unwrap can only panic if the underlying error's backtrace method |
900 | // is nondeterministic, which would only happen in maliciously |
901 | // constructed code. |
902 | this.deref() |
903 | .backtrace |
904 | .as_ref() |
905 | .or_else(|| { |
906 | #[cfg (backtrace)] |
907 | return error::request_ref::<Backtrace>(Self::error(this)); |
908 | #[cfg (not(backtrace))] |
909 | return (vtable(this.ptr).object_backtrace)(this); |
910 | }) |
911 | .expect("backtrace capture failed" ) |
912 | } |
913 | |
914 | #[cfg (backtrace)] |
915 | unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) { |
916 | if let Some(backtrace) = &this.deref().backtrace { |
917 | request.provide_ref(backtrace); |
918 | } |
919 | Self::error(this).provide(request); |
920 | } |
921 | |
922 | #[cold ] |
923 | pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain { |
924 | Chain::new(Self::error(this)) |
925 | } |
926 | } |
927 | |
928 | impl<E> StdError for ErrorImpl<E> |
929 | where |
930 | E: StdError, |
931 | { |
932 | fn source(&self) -> Option<&(dyn StdError + 'static)> { |
933 | unsafe { ErrorImpl::error(self.erase()).source() } |
934 | } |
935 | |
936 | #[cfg (backtrace)] |
937 | fn provide<'a>(&'a self, request: &mut Request<'a>) { |
938 | unsafe { ErrorImpl::provide(self.erase(), request) } |
939 | } |
940 | } |
941 | |
942 | impl<E> Debug for ErrorImpl<E> |
943 | where |
944 | E: Debug, |
945 | { |
946 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
947 | unsafe { ErrorImpl::debug(self.erase(), f:formatter) } |
948 | } |
949 | } |
950 | |
951 | impl<E> Display for ErrorImpl<E> |
952 | where |
953 | E: Display, |
954 | { |
955 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
956 | unsafe { Display::fmt(self:ErrorImpl::error(self.erase()), f:formatter) } |
957 | } |
958 | } |
959 | |
960 | impl From<Error> for Box<dyn StdError + Send + Sync + 'static> { |
961 | #[cold ] |
962 | fn from(error: Error) -> Self { |
963 | let outer: ManuallyDrop = ManuallyDrop::new(error); |
964 | unsafe { |
965 | // Use vtable to attach ErrorImpl<E>'s native StdError vtable for |
966 | // the right original type E. |
967 | (vtable(outer.inner.ptr).object_boxed)(outer.inner) |
968 | } |
969 | } |
970 | } |
971 | |
972 | impl From<Error> for Box<dyn StdError + Send + 'static> { |
973 | fn from(error: Error) -> Self { |
974 | Box::<dyn StdError + Send + Sync>::from(error) |
975 | } |
976 | } |
977 | |
978 | impl From<Error> for Box<dyn StdError + 'static> { |
979 | fn from(error: Error) -> Self { |
980 | Box::<dyn StdError + Send + Sync>::from(error) |
981 | } |
982 | } |
983 | |
984 | #[cfg (feature = "std" )] |
985 | impl AsRef<dyn StdError + Send + Sync> for Error { |
986 | fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) { |
987 | &**self |
988 | } |
989 | } |
990 | |
991 | #[cfg (feature = "std" )] |
992 | impl AsRef<dyn StdError> for Error { |
993 | fn as_ref(&self) -> &(dyn StdError + 'static) { |
994 | &**self |
995 | } |
996 | } |
997 | |