]> git.proxmox.com Git - rustc.git/blobdiff - vendor/rustc-ap-rustc_macros/src/type_foldable.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / vendor / rustc-ap-rustc_macros / src / type_foldable.rs
diff --git a/vendor/rustc-ap-rustc_macros/src/type_foldable.rs b/vendor/rustc-ap-rustc_macros/src/type_foldable.rs
new file mode 100644 (file)
index 0000000..082af08
--- /dev/null
@@ -0,0 +1,44 @@
+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_visit = s.each(|bind| {
+        quote! {
+            ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?;
+        }
+    });
+    s.bind_with(|_| synstructure::BindStyle::Move);
+    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)
+            }
+        })
+    });
+
+    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
+            ) -> ::std::ops::ControlFlow<__F::BreakTy> {
+                match *self { #body_visit }
+                ::std::ops::ControlFlow::CONTINUE
+            }
+        },
+    )
+}