1use quote::quote;
2pub(crate) fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
5 if let syn::Data::Union(_) = s.ast().data {
6 panic!("cannot derive on union")
7 }
8
9 s.add_bounds(synstructure::AddBounds::Fields);
15 s.bind_with(|_| synstructure::BindStyle::Move);
16 let body_fold = s.each_variant(|vi| {
17 let bindings = vi.bindings();
18 vi.construct(|_, index| {
19 let bind = &bindings[index];
20 quote! {
21 ::flux_middle::rty::fold::TypeFoldable::try_fold_with(#bind, __folder)?
22 }
23 })
24 });
25
26 s.bound_impl(
27 quote!(::flux_middle::rty::fold::TypeFoldable),
28 quote! {
29 fn try_fold_with<__F: ::flux_middle::rty::fold::FallibleTypeFolder>(
30 &self,
32 __folder: &mut __F
33 ) -> Result<Self, __F::Error> {
34 Ok(match self { #body_fold })
35 }
36 },
37 )
38}
39
40pub(crate) fn type_visitable_derive(
41 mut s: synstructure::Structure<'_>,
42) -> proc_macro2::TokenStream {
43 if let syn::Data::Union(_) = s.ast().data {
44 panic!("cannot derive on union")
45 }
46
47 s.add_bounds(synstructure::AddBounds::Fields);
53 let body_visit = s.each(|bind| {
54 quote! {
55 ::flux_middle::rty::fold::TypeVisitable::visit_with(#bind, __visitor)?;
56 }
57 });
58 s.bind_with(|_| synstructure::BindStyle::Move);
59
60 s.bound_impl(
61 quote!(::flux_middle::rty::fold::TypeVisitable),
62 quote! {
63 fn visit_with<__V: ::flux_middle::rty::fold::TypeVisitor>(
64 &self,
65 __visitor: &mut __V
66 ) -> ::core::ops::ControlFlow<__V::BreakTy> {
67 match *self { #body_visit }
68 ::core::ops::ControlFlow::Continue(())
69 }
70 },
71 )
72}