|
7 | 7 | // those terms. |
8 | 8 |
|
9 | 9 | use proc_macro2::{Span, TokenStream}; |
10 | | -use quote::ToTokens; |
| 10 | +use quote::{quote, ToTokens}; |
11 | 11 | use syn::{ |
12 | 12 | parse_quote, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error, Expr, ExprLit, Field, |
13 | | - Ident, Index, Lit, Meta, Path, Type, Variant, Visibility, |
| 13 | + Ident, ImplGenerics, Index, Lit, Meta, Path, Type, TypeGenerics, Variant, Visibility, |
| 14 | + WhereClause, |
14 | 15 | }; |
15 | 16 |
|
16 | 17 | pub(crate) struct Ctx { |
@@ -63,6 +64,60 @@ impl Ctx { |
63 | 64 | } |
64 | 65 | } |
65 | 66 |
|
| 67 | +pub(crate) struct ImplBlockBuilder<'a> { |
| 68 | + impl_generics: ImplGenerics<'a>, |
| 69 | + |
| 70 | + trait_name: Path, |
| 71 | + trait_generics: Option<TypeGenerics<'a>>, |
| 72 | + |
| 73 | + self_name: Ident, |
| 74 | + self_generics: TypeGenerics<'a>, |
| 75 | + |
| 76 | + where_clause: Option<&'a WhereClause>, |
| 77 | + |
| 78 | + ctx: &'a Ctx, |
| 79 | +} |
| 80 | + |
| 81 | +impl<'a> ImplBlockBuilder<'a> { |
| 82 | + pub(crate) fn from_derive_input( |
| 83 | + ctx: &'a Ctx, |
| 84 | + input: &'a DeriveInput, |
| 85 | + trait_name: Path, |
| 86 | + ) -> ImplBlockBuilder<'a> { |
| 87 | + let (impl_generics, self_generics, where_clause) = input.generics.split_for_impl(); |
| 88 | + |
| 89 | + Self { |
| 90 | + impl_generics, |
| 91 | + trait_name, |
| 92 | + trait_generics: None, |
| 93 | + self_name: input.ident.clone(), |
| 94 | + self_generics, |
| 95 | + where_clause, |
| 96 | + ctx, |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + pub(crate) fn build(self) -> TokenStream { |
| 101 | + let Self { |
| 102 | + impl_generics, |
| 103 | + trait_name, |
| 104 | + trait_generics, |
| 105 | + self_name, |
| 106 | + self_generics, |
| 107 | + where_clause, |
| 108 | + ctx, |
| 109 | + } = self; |
| 110 | + |
| 111 | + let zerocopy_crate = &ctx.zerocopy_crate; |
| 112 | + |
| 113 | + quote! { |
| 114 | + unsafe impl #impl_generics #trait_name #trait_generics for #self_name #self_generics #where_clause { |
| 115 | + fn only_derive_is_allowed_to_implement_this_trait() where Self: #zerocopy_crate::util::macro_util::core_reexport::marker::Sized {} |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | +} |
| 120 | + |
66 | 121 | pub(crate) trait DataExt { |
67 | 122 | /// Extracts the names and types of all fields. For enums, extracts the |
68 | 123 | /// names and types of fields from each variant. For tuple structs, the |
|
0 commit comments