File tree Expand file tree Collapse file tree 2 files changed +41
-0
lines changed Expand file tree Collapse file tree 2 files changed +41
-0
lines changed Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ use synstructure::decl_derive;
9
9
use proc_macro:: TokenStream ;
10
10
11
11
mod hash_stable;
12
+ mod type_foldable;
12
13
mod query;
13
14
mod symbols;
14
15
@@ -23,3 +24,4 @@ pub fn symbols(input: TokenStream) -> TokenStream {
23
24
}
24
25
25
26
decl_derive ! ( [ HashStable , attributes( stable_hasher) ] => hash_stable:: hash_stable_derive) ;
27
+ decl_derive ! ( [ TypeFoldable , attributes( type_foldable) ] => type_foldable:: type_foldable_derive) ;
Original file line number Diff line number Diff line change
1
+ use synstructure;
2
+ use syn;
3
+ use quote:: quote;
4
+
5
+ pub fn type_foldable_derive ( mut s : synstructure:: Structure < ' _ > ) -> proc_macro2:: TokenStream {
6
+ if let syn:: Data :: Union ( _) = s. ast ( ) . data {
7
+ panic ! ( "cannot derive on union" )
8
+ }
9
+
10
+ s. add_bounds ( synstructure:: AddBounds :: Generics ) ;
11
+ let body_fold = s. each_variant ( |vi| {
12
+ let bindings = vi. bindings ( ) ;
13
+ vi. construct ( |_, index| {
14
+ let bind = & bindings[ index] ;
15
+ quote ! {
16
+ :: rustc:: ty:: fold:: TypeFoldable :: fold_with( #bind, __folder)
17
+ }
18
+ } )
19
+ } ) ;
20
+ let body_visit = s. fold ( false , |acc, bind| {
21
+ quote ! { #acc || :: rustc:: ty:: fold:: TypeFoldable :: visit_with( #bind, __folder) }
22
+ } ) ;
23
+
24
+ s. bound_impl ( quote ! ( :: rustc:: ty:: fold:: TypeFoldable <' tcx>) , quote ! {
25
+ fn super_fold_with<__F: :: rustc:: ty:: fold:: TypeFolder <' tcx>>(
26
+ & self ,
27
+ __folder: & mut __F
28
+ ) -> Self {
29
+ match * self { #body_fold }
30
+ }
31
+
32
+ fn super_visit_with<__F: :: rustc:: ty:: fold:: TypeVisitor <' tcx>>(
33
+ & self ,
34
+ __folder: & mut __F
35
+ ) -> bool {
36
+ match * self { #body_visit }
37
+ }
38
+ } )
39
+ }
You can’t perform that action at this time.
0 commit comments