diff --git a/impl/src/expand.rs b/impl/src/expand.rs index 23301b5..c933f3e 100644 --- a/impl/src/expand.rs +++ b/impl/src/expand.rs @@ -35,10 +35,11 @@ fn struct_error(input: &DeriveInput, data: &DataStruct) -> Result { }; let source_method = source.map(|source| { - let member = quote_spanned!(source.span()=> &self.#source); + let member = quote_spanned!(source.span()=> self.#source); quote! { fn source(&self) -> std::option::Option<&(dyn std::error::Error + 'static)> { - std::option::Option::Some(#member) + use thiserror::private::AsDynError; + std::option::Option::Some(#member.as_dyn_error()) } } }); diff --git a/src/aserror.rs b/src/aserror.rs new file mode 100644 index 0000000..a98f633 --- /dev/null +++ b/src/aserror.rs @@ -0,0 +1,23 @@ +use std::error::Error; + +pub trait AsDynError { + fn as_dyn_error(&self) -> &(dyn Error + 'static); +} + +impl AsDynError for T { + fn as_dyn_error(&self) -> &(dyn Error + 'static) { + self + } +} + +impl AsDynError for dyn Error + 'static { + fn as_dyn_error(&self) -> &(dyn Error + 'static) { + self + } +} + +impl AsDynError for dyn Error + Send + Sync + 'static { + fn as_dyn_error(&self) -> &(dyn Error + 'static) { + self + } +} diff --git a/src/lib.rs b/src/lib.rs index f7a7376..3cb1684 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,9 @@ +mod aserror; + pub use thiserror_impl::*; + +// Not public API. +#[doc(hidden)] +pub mod private { + pub use crate::aserror::AsDynError; +}