blob: 6931e6552add28eab90b998e251deecefd08f77f [file] [log] [blame]
use quote::quote;
pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
if let syn::Data::Union(_) = s.ast().data {
panic!("cannot derive on union")
}
s.add_bounds(synstructure::AddBounds::Generics);
let body_fold = s.each_variant(|vi| {
let bindings = vi.bindings();
vi.construct(|_, index| {
let bind = &bindings[index];
quote! {
::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)
}
})
});
let body_visit = s.fold(false, |acc, bind| {
quote! { #acc || ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
});
s.bound_impl(
quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
quote! {
fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>(
&self,
__folder: &mut __F
) -> Self {
match *self { #body_fold }
}
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
&self,
__folder: &mut __F
) -> bool {
match *self { #body_visit }
}
},
)
}