(input: Enum)
| 219 | } |
| 220 | |
| 221 | fn impl_enum(input: Enum) -> TokenStream { |
| 222 | let ty = call_site_ident(&input.ident); |
| 223 | let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); |
| 224 | let mut error_inferred_bounds = InferredBounds::new(); |
| 225 | |
| 226 | let source_method = if input.has_source() { |
| 227 | let arms = input.variants.iter().map(|variant| { |
| 228 | let ident = &variant.ident; |
| 229 | if let Some(transparent_attr) = &variant.attrs.transparent { |
| 230 | let only_field = &variant.fields[0]; |
| 231 | if only_field.contains_generic { |
| 232 | error_inferred_bounds.insert(only_field.ty, quote!(::thiserror::#private::Error)); |
| 233 | } |
| 234 | let member = &only_field.member; |
| 235 | let source = quote_spanned! {transparent_attr.span=> |
| 236 | ::thiserror::#private::Error::source(transparent.as_dyn_error()) |
| 237 | }; |
| 238 | quote! { |
| 239 | #ty::#ident {#member: transparent} => #source, |
| 240 | } |
| 241 | } else if let Some(source_field) = variant.source_field() { |
| 242 | let source = &source_field.member; |
| 243 | if source_field.contains_generic { |
| 244 | let ty = unoptional_type(source_field.ty); |
| 245 | error_inferred_bounds.insert(ty, quote!(::thiserror::#private::Error + 'static)); |
| 246 | } |
| 247 | let asref = if type_is_option(source_field.ty) { |
| 248 | Some(quote_spanned!(source.span()=> .as_ref()?)) |
| 249 | } else { |
| 250 | None |
| 251 | }; |
| 252 | let varsource = quote!(source); |
| 253 | let dyn_error = quote_spanned! {source_field.source_span()=> |
| 254 | #varsource #asref.as_dyn_error() |
| 255 | }; |
| 256 | quote! { |
| 257 | #ty::#ident {#source: #varsource, ..} => ::core::option::Option::Some(#dyn_error), |
| 258 | } |
| 259 | } else { |
| 260 | quote! { |
| 261 | #ty::#ident {..} => ::core::option::Option::None, |
| 262 | } |
| 263 | } |
| 264 | }); |
| 265 | Some(quote! { |
| 266 | fn source(&self) -> ::core::option::Option<&(dyn ::thiserror::#private::Error + 'static)> { |
| 267 | use ::thiserror::#private::AsDynError as _; |
| 268 | #[allow(deprecated)] |
| 269 | match self { |
| 270 | #(#arms)* |
| 271 | } |
| 272 | } |
| 273 | }) |
| 274 | } else { |
| 275 | None |
| 276 | }; |
| 277 | |
| 278 | let provide_method = if input.has_backtrace() { |
no test coverage detected