]> git.lizzy.rs Git - rust.git/blob - src/librustc_macros/src/type_foldable.rs
Rollup merge of #66789 - eddyb:mir-source-scope-local-data, r=oli-obk
[rust.git] / src / librustc_macros / src / type_foldable.rs
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 }