New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combined from and backtrace field #137
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -58,18 +58,25 @@ fn impl_struct(input: Struct) -> TokenStream { | |||||||||||||||||||
self.#source.as_dyn_error().backtrace() | ||||||||||||||||||||
} | ||||||||||||||||||||
}; | ||||||||||||||||||||
let combinator = if type_is_option(backtrace_field.ty) { | ||||||||||||||||||||
if &source_field.member == backtrace { | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The changes on the next 20 lines here can be replaced with a simpler change that does the same thing and minimizes repetition: };
- let combinator = if type_is_option(backtrace_field.ty) {
+ let combinator = if source == backtrace {
+ source_backtrace
+ } else if type_is_option(backtrace_field.ty) {
quote! { |
||||||||||||||||||||
quote! { | ||||||||||||||||||||
#source_backtrace.or(self.#backtrace.as_ref()) | ||||||||||||||||||||
use thiserror::private::AsDynError; | ||||||||||||||||||||
#source_backtrace | ||||||||||||||||||||
} | ||||||||||||||||||||
} else { | ||||||||||||||||||||
let combinator = if type_is_option(backtrace_field.ty) { | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
#source_backtrace.or(self.#backtrace.as_ref()) | ||||||||||||||||||||
} | ||||||||||||||||||||
} else { | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
std::option::Option::Some(#source_backtrace.unwrap_or(&self.#backtrace)) | ||||||||||||||||||||
} | ||||||||||||||||||||
}; | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
std::option::Option::Some(#source_backtrace.unwrap_or(&self.#backtrace)) | ||||||||||||||||||||
use thiserror::private::AsDynError; | ||||||||||||||||||||
#combinator | ||||||||||||||||||||
} | ||||||||||||||||||||
}; | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
use thiserror::private::AsDynError; | ||||||||||||||||||||
#combinator | ||||||||||||||||||||
} | ||||||||||||||||||||
} else if type_is_option(backtrace_field.ty) { | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
|
@@ -123,20 +130,21 @@ fn impl_struct(input: Struct) -> TokenStream { | |||||||||||||||||||
} | ||||||||||||||||||||
}); | ||||||||||||||||||||
|
||||||||||||||||||||
let from_impl = input.from_field().map(|from_field| { | ||||||||||||||||||||
let backtrace_field = input.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_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 error_trait = spanned_error_trait(input.original); | ||||||||||||||||||||
|
||||||||||||||||||||
|
@@ -235,14 +243,32 @@ fn impl_enum(input: Enum) -> TokenStream { | |||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
(Some(backtrace_field), _) => { | ||||||||||||||||||||
let source = variant.from_field().map(|f| &f.member); | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think
Suggested change
|
||||||||||||||||||||
let backtrace = &backtrace_field.member; | ||||||||||||||||||||
let body = if type_is_option(backtrace_field.ty) { | ||||||||||||||||||||
quote!(backtrace.as_ref()) | ||||||||||||||||||||
if source == Some(backtrace) { | ||||||||||||||||||||
let varsource = quote!(source); | ||||||||||||||||||||
let source_backtrace = quote_spanned! {source.span()=> | ||||||||||||||||||||
#varsource.as_dyn_error().backtrace() | ||||||||||||||||||||
}; | ||||||||||||||||||||
Comment on lines
+250
to
+252
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thiserror permits the source field to be optional. This code should handle that like in the case above this one. Lines 212 to 220 in 031fea6
|
||||||||||||||||||||
|
||||||||||||||||||||
quote! { | ||||||||||||||||||||
#ty::#ident { | ||||||||||||||||||||
#source: #varsource, | ||||||||||||||||||||
.. | ||||||||||||||||||||
} => { | ||||||||||||||||||||
use thiserror::private::AsDynError; | ||||||||||||||||||||
#source_backtrace | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
} else { | ||||||||||||||||||||
quote!(std::option::Option::Some(backtrace)) | ||||||||||||||||||||
}; | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
#ty::#ident {#backtrace: backtrace, ..} => #body, | ||||||||||||||||||||
let body = if type_is_option(backtrace_field.ty) { | ||||||||||||||||||||
quote!(backtrace.as_ref()) | ||||||||||||||||||||
} else { | ||||||||||||||||||||
quote!(std::option::Option::Some(backtrace)) | ||||||||||||||||||||
}; | ||||||||||||||||||||
quote! { | ||||||||||||||||||||
#ty::#ident {#backtrace: backtrace, ..} => #body, | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
(None, _) => quote! { | ||||||||||||||||||||
|
@@ -315,8 +341,7 @@ fn impl_enum(input: Enum) -> TokenStream { | |||||||||||||||||||
}; | ||||||||||||||||||||
|
||||||||||||||||||||
let from_impls = input.variants.iter().filter_map(|variant| { | ||||||||||||||||||||
let from_field = variant.from_field()?; | ||||||||||||||||||||
let backtrace_field = variant.backtrace_field(); | ||||||||||||||||||||
let (from_field, backtrace_field) = variant.from_and_distinct_backtrace_fields()?; | ||||||||||||||||||||
let variant = &variant.ident; | ||||||||||||||||||||
let from = from_field.ty; | ||||||||||||||||||||
let body = from_initializer(from_field, backtrace_field); | ||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[from]
is not necessary. It should be sufficient for a field to be#[source]
(or just be namedsource
, which is implicitly#[source]
).