diff --git a/impl/src/expand.rs b/impl/src/expand.rs index 42c02a5..6636eaf 100644 --- a/impl/src/expand.rs +++ b/impl/src/expand.rs @@ -129,21 +129,20 @@ fn impl_struct(input: Struct) -> TokenStream { } }); - let from_impl = input.from_and_distinct_backtrace_fields().map( - |(from_field, backtrace_field)| { - let from = from_field.ty; - let body = from_initializer(from_field, backtrace_field); - quote! { - #[allow(unused_qualifications)] - impl #impl_generics std::convert::From<#from> for #ty #ty_generics #where_clause { - #[allow(deprecated)] - fn from(source: #from) -> Self { - #ty #body - } + let from_impl = input.from_field().map(|from_field| { + let backtrace_field = input.distinct_backtrace_field(); + let from = from_field.ty; + let body = from_initializer(from_field, backtrace_field); + quote! { + #[allow(unused_qualifications)] + impl #impl_generics std::convert::From<#from> for #ty #ty_generics #where_clause { + #[allow(deprecated)] + fn from(source: #from) -> Self { + #ty #body } } - }, - ); + } + }); let error_trait = spanned_error_trait(input.original); @@ -342,7 +341,8 @@ fn impl_enum(input: Enum) -> TokenStream { }; let from_impls = input.variants.iter().filter_map(|variant| { - let (from_field, backtrace_field) = variant.from_and_distinct_backtrace_fields()?; + let from_field = variant.from_field()?; + let backtrace_field = variant.distinct_backtrace_field(); let variant = &variant.ident; let from = from_field.ty; let body = from_initializer(from_field, backtrace_field); diff --git a/impl/src/prop.rs b/impl/src/prop.rs index f80ca3d..f652e37 100644 --- a/impl/src/prop.rs +++ b/impl/src/prop.rs @@ -6,20 +6,6 @@ impl Struct<'_> { from_field(&self.fields) } - pub(crate) fn from_and_distinct_backtrace_fields(&self) -> Option<(&Field, Option<&Field>)> { - self.from_field().map(|from_field| { - if let Some(backtrace_field) = self.backtrace_field() { - if backtrace_field.member == from_field.member { - (from_field, None) - } else { - (from_field, Some(backtrace_field)) - } - } else { - (from_field, None) - } - }) - } - pub(crate) fn source_field(&self) -> Option<&Field> { source_field(&self.fields) } @@ -27,6 +13,18 @@ impl Struct<'_> { pub(crate) fn backtrace_field(&self) -> Option<&Field> { backtrace_field(&self.fields) } + + // The #[backtrace] field, if it is not the same as the #[from] field. + pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> { + let backtrace_field = self.backtrace_field()?; + if self.from_field().map_or(false, |from_field| { + from_field.member == backtrace_field.member + }) { + None + } else { + Some(backtrace_field) + } + } } impl Enum<'_> { @@ -61,20 +59,6 @@ impl Variant<'_> { from_field(&self.fields) } - pub(crate) fn from_and_distinct_backtrace_fields(&self) -> Option<(&Field, Option<&Field>)> { - self.from_field().map(|from_field| { - if let Some(backtrace_field) = self.backtrace_field() { - if backtrace_field.member == from_field.member { - (from_field, None) - } else { - (from_field, Some(backtrace_field)) - } - } else { - (from_field, None) - } - }) - } - pub(crate) fn source_field(&self) -> Option<&Field> { source_field(&self.fields) } @@ -82,6 +66,17 @@ impl Variant<'_> { pub(crate) fn backtrace_field(&self) -> Option<&Field> { backtrace_field(&self.fields) } + + pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> { + let backtrace_field = self.backtrace_field()?; + if self.from_field().map_or(false, |from_field| { + from_field.member == backtrace_field.member + }) { + None + } else { + Some(backtrace_field) + } + } } impl Field<'_> {