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