]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_macros/src/type_foldable.rs
Auto merge of #92167 - pierwill:chalk-update, r=jackh726
[rust.git] / compiler / rustc_macros / src / type_foldable.rs
1 use quote::quote;
2 use syn::parse_quote;
3
4 pub 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     if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
10         s.add_impl_generic(parse_quote! { 'tcx });
11     }
12
13     s.add_bounds(synstructure::AddBounds::Generics);
14     let body_visit = s.each(|bind| {
15         quote! {
16             ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
17         }
18     });
19     s.bind_with(|_| synstructure::BindStyle::Move);
20     let body_fold = s.each_variant(|vi| {
21         let bindings = vi.bindings();
22         vi.construct(|_, index| {
23             let bind = &bindings[index];
24             quote! {
25                 ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)?
26             }
27         })
28     });
29
30     s.bound_impl(
31         quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
32         quote! {
33             fn try_super_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>(
34                 self,
35                 __folder: &mut __F
36             ) -> Result<Self, __F::Error> {
37                 Ok(match self { #body_fold })
38             }
39
40             fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
41                 &self,
42                 __folder: &mut __F
43             ) -> ::std::ops::ControlFlow<__F::BreakTy> {
44                 match *self { #body_visit }
45                 ::std::ops::ControlFlow::CONTINUE
46             }
47         },
48     )
49 }