@@ -64,6 +64,25 @@ use core::fmt::{self, write};
6464/// assert_eq!(error.to_string(), "some other error (code 36)");
6565/// # }
6666/// ```
67+ ///
68+ /// # From an `anyhow::Error`
69+ ///
70+ /// The `format_err!` macro can always convert an `anyhow::Error` into a
71+ /// `wasmtime::Error`, but when the `"anyhow"` cargo feature is enabled the
72+ /// resulting error will also return true for
73+ /// [`error.is::<anyhow::Error>()`][crate::Error::is] invocations.
74+ ///
75+ /// ```
76+ /// # fn _foo() {
77+ /// #![cfg(feature = "anyhow")]
78+ /// # use wasmtime_internal_error as wasmtime;
79+ /// use wasmtime::format_err;
80+ ///
81+ /// let anyhow_error: anyhow::Error = anyhow::anyhow!("aw crap");
82+ /// let wasmtime_error: wasmtime::Error = format_err!(anyhow_error);
83+ /// assert!(wasmtime_error.is::<anyhow::Error>());
84+ /// # }
85+ /// ```
6786#[ macro_export]
6887macro_rules! format_err {
6988 // Format-style invocation without explicit format arguments.
@@ -81,7 +100,7 @@ macro_rules! format_err {
81100 ( $error: expr $( , ) ? ) => { {
82101 use $crate:: macros:: ctor_specialization:: * ;
83102 let error = $error;
84- ( &&error) . wasmtime_error_choose_ctor( ) . construct( error)
103+ ( &&& error) . wasmtime_error_choose_ctor( ) . construct( error)
85104 } } ;
86105}
87106
@@ -204,14 +223,16 @@ macro_rules! ensure {
204223/// well-typed at the trait method call site `(&&&&&t).method()`, then
205224/// `Specialization1` will be prioritized over `Specialization3`.
206225///
207- /// In our specific case here of choosing an `Error` constructor, we only have
208- /// two specializations:
226+ /// In our specific case here of choosing an `Error` constructor, we have
227+ /// three specializations:
228+ ///
229+ /// 1. For `anyhow::Error`, we want to use the `Error::from_anyhow` constructor.
209230///
210- /// 1 . When the type implements `core::error::Error`, we want to use the
231+ /// 2 . When the type implements `core::error::Error`, we want to use the
211232/// `Error::new` constructor, which will preserve
212233/// `core::error::Error::source` chains.
213234///
214- /// 2 . Otherwise, we want to use the `Error::msg` constructor.
235+ /// 3 . Otherwise, we want to use the `Error::msg` constructor.
215236///
216237/// The `*CtorTrait`s are our `n` specialization traits. Their
217238/// `wasmtime_error_choose_ctor` methods will return different types, each of
@@ -222,14 +243,39 @@ macro_rules! ensure {
222243pub mod ctor_specialization {
223244 use super :: * ;
224245
246+ #[ cfg( feature = "anyhow" ) ]
247+ pub use anyhow:: * ;
248+ #[ cfg( feature = "anyhow" ) ]
249+ mod anyhow {
250+ use super :: * ;
251+
252+ pub trait AnyhowCtorTrait {
253+ #[ inline]
254+ fn wasmtime_error_choose_ctor ( & self ) -> AnyhowCtor {
255+ AnyhowCtor
256+ }
257+ }
258+
259+ impl AnyhowCtorTrait for & anyhow:: Error { }
260+
261+ pub struct AnyhowCtor ;
262+
263+ impl AnyhowCtor {
264+ #[ inline]
265+ pub fn construct ( & self , anyhow_error : :: anyhow:: Error ) -> Error {
266+ Error :: from_anyhow ( anyhow_error)
267+ }
268+ }
269+ }
270+
225271 pub trait NewCtorTrait {
226272 #[ inline]
227273 fn wasmtime_error_choose_ctor ( & self ) -> NewCtor {
228274 NewCtor
229275 }
230276 }
231277
232- impl < E : core:: error:: Error + Send + Sync + ' static > NewCtorTrait for & E { }
278+ impl < E : core:: error:: Error + Send + Sync + ' static > NewCtorTrait for & & E { }
233279
234280 pub struct NewCtor ;
235281
@@ -250,7 +296,7 @@ pub mod ctor_specialization {
250296 }
251297 }
252298
253- impl < M : fmt:: Debug + fmt:: Display + Send + Sync + ' static > MsgCtorTrait for & & M { }
299+ impl < M : fmt:: Debug + fmt:: Display + Send + Sync + ' static > MsgCtorTrait for & & & M { }
254300
255301 pub struct MsgCtor ;
256302
0 commit comments