Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/macros/src/lib.rs')
| -rw-r--r-- | crates/macros/src/lib.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/crates/macros/src/lib.rs b/crates/macros/src/lib.rs index 3f90ecc8f9..de8c3f2e55 100644 --- a/crates/macros/src/lib.rs +++ b/crates/macros/src/lib.rs @@ -25,6 +25,9 @@ decl_derive!( /// visited (and its type is not required to implement `TypeVisitable`). type_visitable_derive ); +decl_derive!( + [GenericTypeVisitable] => generic_type_visitable_derive +); fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { @@ -163,6 +166,33 @@ fn has_ignore_attr(attrs: &[syn::Attribute], name: &'static str, meta: &'static ignored } +fn generic_type_visitable_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::Fields); + s.bind_with(|_| synstructure::BindStyle::Move); + s.add_impl_generic(parse_quote!(__V: hir_ty::next_solver::interner::WorldExposer)); + let body_visit = s.each(|bind| { + quote! { + ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(#bind, __visitor); + } + }); + + s.bound_impl( + quote!(::rustc_type_ir::GenericTypeVisitable<__V>), + quote! { + fn generic_visit_with( + &self, + __visitor: &mut __V + ) { + match self { #body_visit } + } + }, + ) +} + decl_derive!( [UpmapFromRaFixture] => upmap_from_ra_fixture ); |