@@ -59,45 +59,53 @@ fn impl_struct(input: Struct) -> TokenStream {
5959 }
6060 } ) ;
6161
62- let backtrace_method = input. backtrace_field ( ) . map ( |backtrace_field| {
62+ let provide_method = input. backtrace_field ( ) . map ( |backtrace_field| {
63+ let demand = quote ! ( demand) ;
6364 let backtrace = & backtrace_field. member ;
6465 let body = if let Some ( source_field) = input. source_field ( ) {
6566 let source = & source_field. member ;
66- let source_backtrace = if type_is_option ( source_field. ty ) {
67+ let source_provide = if type_is_option ( source_field. ty ) {
6768 quote_spanned ! { source. span( ) =>
68- self . #source. as_ref( ) . and_then( |source| source. as_dyn_error( ) . backtrace( ) )
69+ if let std:: option:: Option :: Some ( source) = & self . #source {
70+ source. as_dyn_error( ) . provide( #demand) ;
71+ }
6972 }
7073 } else {
7174 quote_spanned ! { source. span( ) =>
72- self . #source. as_dyn_error( ) . backtrace ( )
75+ self . #source. as_dyn_error( ) . provide ( #demand ) ;
7376 }
7477 } ;
75- let combinator = if source == backtrace {
76- source_backtrace
78+ let self_provide = if source == backtrace {
79+ None
7780 } else if type_is_option ( backtrace_field. ty ) {
78- quote ! {
79- #source_backtrace. or( self . #backtrace. as_ref( ) )
80- }
81+ Some ( quote ! {
82+ if let std:: option:: Option :: Some ( backtrace) = & self . #backtrace {
83+ #demand. provide_ref:: <std:: backtrace:: Backtrace >( backtrace) ;
84+ }
85+ } )
8186 } else {
82- quote ! {
83- std :: option :: Option :: Some ( #source_backtrace . unwrap_or ( & self . #backtrace) )
84- }
87+ Some ( quote ! {
88+ #demand . provide_ref :: <std :: backtrace :: Backtrace > ( & self . #backtrace) ;
89+ } )
8590 } ;
8691 quote ! {
8792 use thiserror:: __private:: AsDynError ;
88- #combinator
93+ #source_provide
94+ #self_provide
8995 }
9096 } else if type_is_option ( backtrace_field. ty ) {
9197 quote ! {
92- self . #backtrace. as_ref( )
98+ if let std:: option:: Option :: Some ( backtrace) = & self . #backtrace {
99+ #demand. provide_ref:: <std:: backtrace:: Backtrace >( backtrace) ;
100+ }
93101 }
94102 } else {
95103 quote ! {
96- std :: option :: Option :: Some ( & self . #backtrace)
104+ #demand . provide_ref :: <std :: backtrace :: Backtrace > ( & self . #backtrace) ;
97105 }
98106 } ;
99107 quote ! {
100- fn backtrace ( & self ) -> std :: option :: Option < & std:: backtrace :: Backtrace > {
108+ fn provide< ' _demand> ( & ' _demand self , #demand : & mut std:: any :: Demand < ' _demand> ) {
101109 #body
102110 }
103111 }
@@ -177,7 +185,7 @@ fn impl_struct(input: Struct) -> TokenStream {
177185 #[ allow( unused_qualifications) ]
178186 impl #impl_generics #error_trait for #ty #ty_generics #error_where_clause {
179187 #source_method
180- #backtrace_method
188+ #provide_method
181189 }
182190 #display_impl
183191 #from_impl
@@ -237,7 +245,8 @@ fn impl_enum(input: Enum) -> TokenStream {
237245 None
238246 } ;
239247
240- let backtrace_method = if input. has_backtrace ( ) {
248+ let provide_method = if input. has_backtrace ( ) {
249+ let demand = quote ! ( demand) ;
241250 let arms = input. variants . iter ( ) . map ( |variant| {
242251 let ident = & variant. ident ;
243252 match ( variant. backtrace_field ( ) , variant. source_field ( ) ) {
@@ -247,22 +256,26 @@ fn impl_enum(input: Enum) -> TokenStream {
247256 let backtrace = & backtrace_field. member ;
248257 let source = & source_field. member ;
249258 let varsource = quote ! ( source) ;
250- let source_backtrace = if type_is_option ( source_field. ty ) {
259+ let source_provide = if type_is_option ( source_field. ty ) {
251260 quote_spanned ! { source. span( ) =>
252- #varsource. as_ref( ) . and_then( |source| source. as_dyn_error( ) . backtrace( ) )
261+ if let std:: option:: Option :: Some ( source) = #varsource {
262+ source. as_dyn_error( ) . provide( #demand) ;
263+ }
253264 }
254265 } else {
255266 quote_spanned ! { source. span( ) =>
256- #varsource. as_dyn_error( ) . backtrace ( )
267+ #varsource. as_dyn_error( ) . provide ( #demand ) ;
257268 }
258269 } ;
259- let combinator = if type_is_option ( backtrace_field. ty ) {
270+ let self_provide = if type_is_option ( backtrace_field. ty ) {
260271 quote ! {
261- #source_backtrace. or( backtrace. as_ref( ) )
272+ if let std:: option:: Option :: Some ( backtrace) = backtrace {
273+ #demand. provide_ref:: <std:: backtrace:: Backtrace >( backtrace) ;
274+ }
262275 }
263276 } else {
264277 quote ! {
265- std :: option :: Option :: Some ( #source_backtrace . unwrap_or ( backtrace) )
278+ #demand . provide_ref :: <std :: backtrace :: Backtrace > ( backtrace) ;
266279 }
267280 } ;
268281 quote ! {
@@ -272,7 +285,8 @@ fn impl_enum(input: Enum) -> TokenStream {
272285 ..
273286 } => {
274287 use thiserror:: __private:: AsDynError ;
275- #combinator
288+ #source_provide
289+ #self_provide
276290 }
277291 }
278292 }
@@ -281,40 +295,50 @@ fn impl_enum(input: Enum) -> TokenStream {
281295 {
282296 let backtrace = & backtrace_field. member ;
283297 let varsource = quote ! ( source) ;
284- let source_backtrace = if type_is_option ( source_field. ty ) {
298+ let source_provide = if type_is_option ( source_field. ty ) {
285299 quote_spanned ! { backtrace. span( ) =>
286- #varsource. as_ref( ) . and_then( |source| source. as_dyn_error( ) . backtrace( ) )
300+ if let std:: option:: Option :: Some ( source) = #varsource {
301+ source. as_dyn_error( ) . provide( #demand) ;
302+ }
287303 }
288304 } else {
289305 quote_spanned ! { backtrace. span( ) =>
290- #varsource. as_dyn_error( ) . backtrace ( )
306+ #varsource. as_dyn_error( ) . provide ( #demand ) ;
291307 }
292308 } ;
293309 quote ! {
294310 #ty:: #ident { #backtrace: #varsource, ..} => {
295311 use thiserror:: __private:: AsDynError ;
296- #source_backtrace
312+ #source_provide
297313 }
298314 }
299315 }
300316 ( Some ( backtrace_field) , _) => {
301317 let backtrace = & backtrace_field. member ;
302318 let body = if type_is_option ( backtrace_field. ty ) {
303- quote ! ( backtrace. as_ref( ) )
319+ quote ! {
320+ if let std:: option:: Option :: Some ( backtrace) = backtrace {
321+ #demand. provide_ref:: <std:: backtrace:: Backtrace >( backtrace) ;
322+ }
323+ }
304324 } else {
305- quote ! ( std:: option:: Option :: Some ( backtrace) )
325+ quote ! {
326+ #demand. provide_ref:: <std:: backtrace:: Backtrace >( backtrace) ;
327+ }
306328 } ;
307329 quote ! {
308- #ty:: #ident { #backtrace: backtrace, ..} => #body,
330+ #ty:: #ident { #backtrace: backtrace, ..} => {
331+ #body
332+ }
309333 }
310334 }
311335 ( None , _) => quote ! {
312- #ty:: #ident { ..} => std :: option :: Option :: None ,
336+ #ty:: #ident { ..} => { }
313337 } ,
314338 }
315339 } ) ;
316340 Some ( quote ! {
317- fn backtrace ( & self ) -> std :: option :: Option < & std:: backtrace :: Backtrace > {
341+ fn provide< ' _demand> ( & ' _demand self , #demand : & mut std:: any :: Demand < ' _demand> ) {
318342 #[ allow( deprecated) ]
319343 match self {
320344 #( #arms) *
@@ -420,7 +444,7 @@ fn impl_enum(input: Enum) -> TokenStream {
420444 #[ allow( unused_qualifications) ]
421445 impl #impl_generics #error_trait for #ty #ty_generics #error_where_clause {
422446 #source_method
423- #backtrace_method
447+ #provide_method
424448 }
425449 #display_impl
426450 #( #from_impls) *
0 commit comments