Adjust how distinct backtrace field is accessed

This commit is contained in:
David Tolnay 2021-08-28 13:08:53 -07:00
parent ca33ed9bc7
commit 9b542cef8f
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 37 additions and 42 deletions

View File

@ -129,21 +129,20 @@ fn impl_struct(input: Struct) -> TokenStream {
} }
}); });
let from_impl = input.from_and_distinct_backtrace_fields().map( let from_impl = input.from_field().map(|from_field| {
|(from_field, backtrace_field)| { let backtrace_field = input.distinct_backtrace_field();
let from = from_field.ty; let from = from_field.ty;
let body = from_initializer(from_field, backtrace_field); let body = from_initializer(from_field, backtrace_field);
quote! { quote! {
#[allow(unused_qualifications)] #[allow(unused_qualifications)]
impl #impl_generics std::convert::From<#from> for #ty #ty_generics #where_clause { impl #impl_generics std::convert::From<#from> for #ty #ty_generics #where_clause {
#[allow(deprecated)] #[allow(deprecated)]
fn from(source: #from) -> Self { fn from(source: #from) -> Self {
#ty #body #ty #body
}
} }
} }
}, }
); });
let error_trait = spanned_error_trait(input.original); 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_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 variant = &variant.ident;
let from = from_field.ty; let from = from_field.ty;
let body = from_initializer(from_field, backtrace_field); let body = from_initializer(from_field, backtrace_field);

View File

@ -6,20 +6,6 @@ impl Struct<'_> {
from_field(&self.fields) 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> { pub(crate) fn source_field(&self) -> Option<&Field> {
source_field(&self.fields) source_field(&self.fields)
} }
@ -27,6 +13,18 @@ impl Struct<'_> {
pub(crate) fn backtrace_field(&self) -> Option<&Field> { pub(crate) fn backtrace_field(&self) -> Option<&Field> {
backtrace_field(&self.fields) 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<'_> { impl Enum<'_> {
@ -61,20 +59,6 @@ impl Variant<'_> {
from_field(&self.fields) 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> { pub(crate) fn source_field(&self) -> Option<&Field> {
source_field(&self.fields) source_field(&self.fields)
} }
@ -82,6 +66,17 @@ impl Variant<'_> {
pub(crate) fn backtrace_field(&self) -> Option<&Field> { pub(crate) fn backtrace_field(&self) -> Option<&Field> {
backtrace_field(&self.fields) 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<'_> { impl Field<'_> {