diff --git a/impl/src/expand.rs b/impl/src/expand.rs index d712146..0f9d5ed 100644 --- a/impl/src/expand.rs +++ b/impl/src/expand.rs @@ -171,9 +171,10 @@ fn impl_enum(input: Enum) -> TokenStream { } else { None }; - let dyn_error = quote_spanned!(source.span()=> source #asref.as_dyn_error()); + let source_literal = quote! { source }; + let dyn_error = quote_spanned!(source.span()=> #source_literal #asref.as_dyn_error()); quote! { - #ty::#ident {#source: source, ..} => std::option::Option::Some(#dyn_error), + #ty::#ident {#source: #source_literal, ..} => std::option::Option::Some(#dyn_error), } } else { quote! { @@ -203,13 +204,14 @@ fn impl_enum(input: Enum) -> TokenStream { { let backtrace = &backtrace_field.member; let source = &source_field.member; + let source_literal = quote! { source }; let source_backtrace = if type_is_option(source_field.ty) { quote_spanned! {source.span()=> - source.as_ref().and_then(|source| source.as_dyn_error().backtrace()) + #source_literal.as_ref().and_then(|source| #source_literal.as_dyn_error().backtrace()) } } else { quote_spanned! {source.span()=> - source.as_dyn_error().backtrace() + #source_literal.as_dyn_error().backtrace() } }; let combinator = if type_is_option(backtrace_field.ty) { @@ -224,7 +226,7 @@ fn impl_enum(input: Enum) -> TokenStream { quote! { #ty::#ident { #backtrace: backtrace, - #source: source, + #source: #source_literal, .. } => { use thiserror::private::AsDynError; diff --git a/tests/test_source.rs b/tests/test_source.rs index 66d9dad..860e727 100644 --- a/tests/test_source.rs +++ b/tests/test_source.rs @@ -48,3 +48,16 @@ fn test_boxed_source() { let error = BoxedSource { source }; error.source().unwrap().downcast_ref::().unwrap(); } + +macro_rules! error_from_macro { + ($($variants:tt)*) => { + #[derive(Error)] + #[derive(Debug)] + pub enum MacroSource { + $($variants)* + } + } +} + +// Test that we generate impls with the proper hygiene +error_from_macro!(#[error("Something")] Variant(#[from] io::Error));