mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 15:54:15 +00:00
Create TypeFoldable derive proc-macro.
This commit is contained in:
parent
695fe96517
commit
9e28e9c545
@ -9,6 +9,7 @@ use synstructure::decl_derive;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
mod hash_stable;
|
||||
mod type_foldable;
|
||||
mod query;
|
||||
mod symbols;
|
||||
|
||||
@ -23,3 +24,4 @@ pub fn symbols(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
|
||||
decl_derive!([TypeFoldable, attributes(type_foldable)] => type_foldable::type_foldable_derive);
|
||||
|
39
src/librustc_macros/src/type_foldable.rs
Normal file
39
src/librustc_macros/src/type_foldable.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use synstructure;
|
||||
use syn;
|
||||
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_fold = s.each_variant(|vi| {
|
||||
let bindings = vi.bindings();
|
||||
vi.construct(|_, index| {
|
||||
let bind = &bindings[index];
|
||||
quote!{
|
||||
::rustc::ty::fold::TypeFoldable::fold_with(#bind, __folder)
|
||||
}
|
||||
})
|
||||
});
|
||||
let body_visit = s.fold(false, |acc, bind| {
|
||||
quote!{ #acc || ::rustc::ty::fold::TypeFoldable::visit_with(#bind, __folder) }
|
||||
});
|
||||
|
||||
s.bound_impl(quote!(::rustc::ty::fold::TypeFoldable<'tcx>), quote!{
|
||||
fn super_fold_with<__F: ::rustc::ty::fold::TypeFolder<'tcx>>(
|
||||
&self,
|
||||
__folder: &mut __F
|
||||
) -> Self {
|
||||
match *self { #body_fold }
|
||||
}
|
||||
|
||||
fn super_visit_with<__F: ::rustc::ty::fold::TypeVisitor<'tcx>>(
|
||||
&self,
|
||||
__folder: &mut __F
|
||||
) -> bool {
|
||||
match *self { #body_visit }
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user