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;
99use proc_macro:: TokenStream ;
1010
1111mod hash_stable;
12+ mod type_foldable;
1213mod query;
1314mod symbols;
1415
@@ -23,3 +24,4 @@ pub fn symbols(input: TokenStream) -> TokenStream {
2324}
2425
2526decl_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