@@ -7,15 +7,39 @@ use quote::{format_ident, quote, quote_spanned, ToTokens};
77use std:: collections:: BTreeSet as Set ;
88use syn:: { DeriveInput , GenericArgument , Member , PathArguments , Result , Token , Type } ;
99
10- pub fn derive ( node : & DeriveInput ) -> Result < TokenStream > {
11- let input = Input :: from_syn ( node) ?;
10+ pub fn derive ( input : & DeriveInput ) -> TokenStream {
11+ match try_expand ( input) {
12+ Ok ( expanded) => expanded,
13+ // If there are invalid attributes in the input, expand to an Error impl
14+ // anyway to minimize spurious knock-on errors in other code that uses
15+ // this type as an Error.
16+ Err ( error) => fallback ( input, error) ,
17+ }
18+ }
19+
20+ fn try_expand ( input : & DeriveInput ) -> Result < TokenStream > {
21+ let input = Input :: from_syn ( input) ?;
1222 input. validate ( ) ?;
1323 Ok ( match input {
1424 Input :: Struct ( input) => impl_struct ( input) ,
1525 Input :: Enum ( input) => impl_enum ( input) ,
1626 } )
1727}
1828
29+ fn fallback ( input : & DeriveInput , error : syn:: Error ) -> TokenStream {
30+ let ty = & input. ident ;
31+ let ( impl_generics, ty_generics, where_clause) = input. generics . split_for_impl ( ) ;
32+
33+ let error = error. to_compile_error ( ) ;
34+
35+ quote ! {
36+ #error
37+
38+ #[ allow( unused_qualifications) ]
39+ impl #impl_generics std:: error:: Error for #ty #ty_generics #where_clause { }
40+ }
41+ }
42+
1943fn impl_struct ( input : Struct ) -> TokenStream {
2044 let ty = & input. ident ;
2145 let ( impl_generics, ty_generics, where_clause) = input. generics . split_for_impl ( ) ;
0 commit comments