]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_macros/src/type_foldable.rs
Rollup merge of #81879 - imbrem:make-reverse-repr-transparent, r=m-ou-se
[rust.git] / compiler / rustc_macros / src / type_foldable.rs
1 use quote::quote;
2
3 pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {
4     if let syn::Data::Union(_) = s.ast().data {
5         panic!("cannot derive on union")
6     }
7
8     s.add_bounds(synstructure::AddBounds::Generics);
9     let body_visit = s.each(|bind| {
10         quote! {
11             ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
12         }
13     });
14     s.bind_with(|_| synstructure::BindStyle::Move);
15     let body_fold = s.each_variant(|vi| {
16         let bindings = vi.bindings();
17         vi.construct(|_, index| {
18             let bind = &bindings[index];
19             quote! {
20                 ::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)
21             }
22         })
23     });
24
25     s.bound_impl(
26         quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
27         quote! {
28             fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>(
29                 self,
30                 __folder: &mut __F
31             ) -> Self {
32                 match self { #body_fold }
33             }
34
35             fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
36                 &self,
37                 __folder: &mut __F
38             ) -> ::std::ops::ControlFlow<__F::BreakTy> {
39                 match *self { #body_visit }
40                 ::std::ops::ControlFlow::CONTINUE
41             }
42         },
43     )
44 }