1 use proc_macro2::{Span, TokenStream};
2 use quote::{format_ident, quote};
3 use std::collections::HashSet;
4 use std::fmt;
5 use syn::parse::{Parse, ParseStream};
6 use syn::punctuated::Punctuated;
7 use syn::{Data, DeriveInput, Error, Ident, Result, Token, braced, parse_quote};
8 use wasmtime_component_util::{DiscriminantSize, FlagsSize};
9 
10 mod kw {
11     syn::custom_keyword!(record);
12     syn::custom_keyword!(variant);
13     syn::custom_keyword!(flags);
14     syn::custom_keyword!(name);
15     syn::custom_keyword!(wasmtime_crate);
16 }
17 
18 #[derive(Debug, Copy, Clone)]
19 enum Style {
20     Record,
21     Enum,
22     Variant,
23 }
24 
25 impl fmt::Display for Style {
26     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27         match self {
28             Style::Record => f.write_str("record"),
29             Style::Enum => f.write_str("enum"),
30             Style::Variant => f.write_str("variant"),
31         }
32     }
33 }
34 
35 #[derive(Debug, Clone)]
36 enum ComponentAttr {
37     Style(Style),
38     WasmtimeCrate(syn::Path),
39 }
40 
41 impl Parse for ComponentAttr {
42     fn parse(input: ParseStream) -> Result<Self> {
43         let lookahead = input.lookahead1();
44         if lookahead.peek(kw::record) {
45             input.parse::<kw::record>()?;
46             Ok(ComponentAttr::Style(Style::Record))
47         } else if lookahead.peek(kw::variant) {
48             input.parse::<kw::variant>()?;
49             Ok(ComponentAttr::Style(Style::Variant))
50         } else if lookahead.peek(Token![enum]) {
51             input.parse::<Token![enum]>()?;
52             Ok(ComponentAttr::Style(Style::Enum))
53         } else if lookahead.peek(kw::wasmtime_crate) {
54             input.parse::<kw::wasmtime_crate>()?;
55             input.parse::<Token![=]>()?;
56             Ok(ComponentAttr::WasmtimeCrate(input.parse()?))
57         } else if input.peek(kw::flags) {
58             Err(input.error(
59                 "`flags` not allowed here; \
60                  use `wasmtime::component::flags!` macro to define `flags` types",
61             ))
62         } else {
63             Err(lookahead.error())
64         }
65     }
66 }
67 
68 fn find_rename(attributes: &[syn::Attribute]) -> Result<Option<syn::LitStr>> {
69     let mut name = None;
70 
71     for attribute in attributes {
72         if !attribute.path().is_ident("component") {
73             continue;
74         }
75         let name_literal = attribute.parse_args_with(|parser: ParseStream<'_>| {
76             parser.parse::<kw::name>()?;
77             parser.parse::<Token![=]>()?;
78             parser.parse::<syn::LitStr>()
79         })?;
80 
81         if name.is_some() {
82             return Err(Error::new_spanned(
83                 attribute,
84                 "duplicate field rename attribute",
85             ));
86         }
87 
88         name = Some(name_literal);
89     }
90 
91     Ok(name)
92 }
93 
94 fn add_trait_bounds(generics: &syn::Generics, bound: syn::TypeParamBound) -> syn::Generics {
95     let mut generics = generics.clone();
96     for param in &mut generics.params {
97         if let syn::GenericParam::Type(ref mut type_param) = *param {
98             type_param.bounds.push(bound.clone());
99         }
100     }
101     generics
102 }
103 
104 pub struct VariantCase<'a> {
105     attrs: &'a [syn::Attribute],
106     ident: &'a syn::Ident,
107     ty: Option<&'a syn::Type>,
108 }
109 
110 pub trait Expander {
111     fn expand_record(
112         &self,
113         name: &syn::Ident,
114         generics: &syn::Generics,
115         fields: &[&syn::Field],
116         wasmtime_crate: &syn::Path,
117     ) -> Result<TokenStream>;
118 
119     fn expand_variant(
120         &self,
121         name: &syn::Ident,
122         generics: &syn::Generics,
123         discriminant_size: DiscriminantSize,
124         cases: &[VariantCase],
125         wasmtime_crate: &syn::Path,
126     ) -> Result<TokenStream>;
127 
128     fn expand_enum(
129         &self,
130         name: &syn::Ident,
131         discriminant_size: DiscriminantSize,
132         cases: &[VariantCase],
133         wasmtime_crate: &syn::Path,
134     ) -> Result<TokenStream>;
135 }
136 
137 pub fn expand(expander: &dyn Expander, input: &DeriveInput) -> Result<TokenStream> {
138     let mut wasmtime_crate = None;
139     let mut style = None;
140 
141     for attribute in &input.attrs {
142         if !attribute.path().is_ident("component") {
143             continue;
144         }
145         match attribute.parse_args()? {
146             ComponentAttr::WasmtimeCrate(c) => wasmtime_crate = Some(c),
147             ComponentAttr::Style(attr_style) => {
148                 if style.is_some() {
149                     return Err(Error::new_spanned(
150                         attribute,
151                         "duplicate `component` attribute",
152                     ));
153                 }
154                 style = Some(attr_style);
155             }
156         }
157     }
158 
159     let style = style.ok_or_else(|| Error::new_spanned(input, "missing `component` attribute"))?;
160     let wasmtime_crate = wasmtime_crate.unwrap_or_else(default_wasmtime_crate);
161     match style {
162         Style::Record => expand_record(expander, input, &wasmtime_crate),
163         Style::Enum | Style::Variant => expand_variant(expander, input, style, &wasmtime_crate),
164     }
165 }
166 
167 fn default_wasmtime_crate() -> syn::Path {
168     Ident::new("wasmtime", Span::call_site()).into()
169 }
170 
171 fn expand_record(
172     expander: &dyn Expander,
173     input: &DeriveInput,
174     wasmtime_crate: &syn::Path,
175 ) -> Result<TokenStream> {
176     let name = &input.ident;
177 
178     let body = if let Data::Struct(body) = &input.data {
179         body
180     } else {
181         return Err(Error::new(
182             name.span(),
183             "`record` component types can only be derived for Rust `struct`s",
184         ));
185     };
186 
187     match &body.fields {
188         syn::Fields::Named(fields) => expander.expand_record(
189             &input.ident,
190             &input.generics,
191             &fields.named.iter().collect::<Vec<_>>(),
192             wasmtime_crate,
193         ),
194 
195         syn::Fields::Unnamed(_) | syn::Fields::Unit => Err(Error::new(
196             name.span(),
197             "`record` component types can only be derived for `struct`s with named fields",
198         )),
199     }
200 }
201 
202 fn expand_variant(
203     expander: &dyn Expander,
204     input: &DeriveInput,
205     style: Style,
206     wasmtime_crate: &syn::Path,
207 ) -> Result<TokenStream> {
208     let name = &input.ident;
209 
210     let body = if let Data::Enum(body) = &input.data {
211         body
212     } else {
213         return Err(Error::new(
214             name.span(),
215             format!("`{style}` component types can only be derived for Rust `enum`s"),
216         ));
217     };
218 
219     if body.variants.is_empty() {
220         return Err(Error::new(
221             name.span(),
222             format!(
223                 "`{style}` component types can only be derived for Rust `enum`s with at least one variant"
224             ),
225         ));
226     }
227 
228     let discriminant_size = DiscriminantSize::from_count(body.variants.len()).ok_or_else(|| {
229         Error::new(
230             input.ident.span(),
231             "`enum`s with more than 2^32 variants are not supported",
232         )
233     })?;
234 
235     let cases = body
236         .variants
237         .iter()
238         .map(
239             |syn::Variant {
240                  attrs,
241                  ident,
242                  fields,
243                  ..
244              }| {
245                 Ok(VariantCase {
246                     attrs,
247                     ident,
248                     ty: match fields {
249                         syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
250                             Some(&fields.unnamed[0].ty)
251                         }
252                         syn::Fields::Unit => None,
253                         _ => {
254                             return Err(Error::new(
255                                 name.span(),
256                                 format!(
257                                     "`{}` component types can only be derived for Rust `enum`s \
258                                      containing variants with {}",
259                                     style,
260                                     match style {
261                                         Style::Variant => "at most one unnamed field each",
262                                         Style::Enum => "no fields",
263                                         Style::Record => unreachable!(),
264                                     }
265                                 ),
266                             ));
267                         }
268                     },
269                 })
270             },
271         )
272         .collect::<Result<Vec<_>>>()?;
273 
274     match style {
275         Style::Variant => expander.expand_variant(
276             &input.ident,
277             &input.generics,
278             discriminant_size,
279             &cases,
280             wasmtime_crate,
281         ),
282         Style::Enum => {
283             validate_enum(input, &body, discriminant_size)?;
284             expander.expand_enum(&input.ident, discriminant_size, &cases, wasmtime_crate)
285         }
286         Style::Record => unreachable!(),
287     }
288 }
289 
290 /// Validates component model `enum` definitions are accompanied with
291 /// appropriate `#[repr]` tags. Additionally requires that no discriminants are
292 /// listed to ensure that unsafe transmutes in lift are valid.
293 fn validate_enum(input: &DeriveInput, body: &syn::DataEnum, size: DiscriminantSize) -> Result<()> {
294     if !input.generics.params.is_empty() {
295         return Err(Error::new_spanned(
296             &input.generics.params,
297             "cannot have generics on an `enum`",
298         ));
299     }
300     if let Some(clause) = &input.generics.where_clause {
301         return Err(Error::new_spanned(
302             clause,
303             "cannot have a where clause on an `enum`",
304         ));
305     }
306     let expected_discr = match size {
307         DiscriminantSize::Size1 => "u8",
308         DiscriminantSize::Size2 => "u16",
309         DiscriminantSize::Size4 => "u32",
310     };
311     let mut found_repr = false;
312     for attr in input.attrs.iter() {
313         if !attr.meta.path().is_ident("repr") {
314             continue;
315         }
316         let list = attr.meta.require_list()?;
317         found_repr = true;
318         if list.tokens.to_string() != expected_discr {
319             return Err(Error::new_spanned(
320                 &list.tokens,
321                 format!(
322                     "expected `repr({expected_discr})`, found `repr({})`",
323                     list.tokens
324                 ),
325             ));
326         }
327     }
328     if !found_repr {
329         return Err(Error::new_spanned(
330             &body.enum_token,
331             format!("missing required `#[repr({expected_discr})]`"),
332         ));
333     }
334 
335     for case in body.variants.iter() {
336         if let Some((_, expr)) = &case.discriminant {
337             return Err(Error::new_spanned(
338                 expr,
339                 "cannot have an explicit discriminant",
340             ));
341         }
342     }
343 
344     Ok(())
345 }
346 
347 fn expand_record_for_component_type(
348     name: &syn::Ident,
349     generics: &syn::Generics,
350     fields: &[&syn::Field],
351     typecheck: TokenStream,
352     typecheck_argument: TokenStream,
353     wt: &syn::Path,
354 ) -> Result<TokenStream> {
355     let internal = quote!(#wt::component::__internal);
356 
357     let mut lower_generic_params = TokenStream::new();
358     let mut lower_generic_args = TokenStream::new();
359     let mut lower_field_declarations = TokenStream::new();
360     let mut abi_list = TokenStream::new();
361     let mut unique_types = HashSet::new();
362 
363     for (index, syn::Field { ident, ty, .. }) in fields.iter().enumerate() {
364         let generic = format_ident!("T{}", index);
365 
366         lower_generic_params.extend(quote!(#generic: Copy,));
367         lower_generic_args.extend(quote!(<#ty as #wt::component::ComponentType>::Lower,));
368 
369         lower_field_declarations.extend(quote!(#ident: #generic,));
370 
371         abi_list.extend(quote!(
372             <#ty as #wt::component::ComponentType>::ABI,
373         ));
374 
375         unique_types.insert(ty);
376     }
377 
378     let generics = add_trait_bounds(generics, parse_quote!(#wt::component::ComponentType));
379     let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
380     let lower = format_ident!("Lower{}", name);
381 
382     // You may wonder why we make the types of all the fields of the #lower struct generic.  This is to work
383     // around the lack of [perfect derive support in
384     // rustc](https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/#what-is-perfect-derive)
385     // as of this writing.
386     //
387     // If the struct we're deriving a `ComponentType` impl for has any generic parameters, then #lower needs
388     // generic parameters too.  And if we just copy the parameters and bounds from the impl to #lower, then the
389     // `#[derive(Clone, Copy)]` will fail unless the original generics were declared with those bounds, which
390     // we don't want to require.
391     //
392     // Alternatively, we could just pass the `Lower` associated type of each generic type as arguments to
393     // #lower, but that would require distinguishing between generic and concrete types when generating
394     // #lower_field_declarations, which would require some form of symbol resolution.  That doesn't seem worth
395     // the trouble.
396 
397     let expanded = quote! {
398         #[doc(hidden)]
399         #[derive(Clone, Copy)]
400         #[repr(C)]
401         pub struct #lower <#lower_generic_params> {
402             #lower_field_declarations
403             _align: [#wt::ValRaw; 0],
404         }
405 
406         unsafe impl #impl_generics #wt::component::ComponentType for #name #ty_generics #where_clause {
407             type Lower = #lower <#lower_generic_args>;
408 
409             const ABI: #internal::CanonicalAbiInfo =
410                 #internal::CanonicalAbiInfo::record_static(&[#abi_list]);
411 
412             #[inline]
413             fn typecheck(
414                 ty: &#internal::InterfaceType,
415                 types: &#internal::InstanceType<'_>,
416             ) -> #internal::anyhow::Result<()> {
417                 #internal::#typecheck(ty, types, &[#typecheck_argument])
418             }
419         }
420     };
421 
422     Ok(quote!(const _: () = { #expanded };))
423 }
424 
425 fn quote(size: DiscriminantSize, discriminant: usize) -> TokenStream {
426     match size {
427         DiscriminantSize::Size1 => {
428             let discriminant = u8::try_from(discriminant).unwrap();
429             quote!(#discriminant)
430         }
431         DiscriminantSize::Size2 => {
432             let discriminant = u16::try_from(discriminant).unwrap();
433             quote!(#discriminant)
434         }
435         DiscriminantSize::Size4 => {
436             let discriminant = u32::try_from(discriminant).unwrap();
437             quote!(#discriminant)
438         }
439     }
440 }
441 
442 pub struct LiftExpander;
443 
444 impl Expander for LiftExpander {
445     fn expand_record(
446         &self,
447         name: &syn::Ident,
448         generics: &syn::Generics,
449         fields: &[&syn::Field],
450         wt: &syn::Path,
451     ) -> Result<TokenStream> {
452         let internal = quote!(#wt::component::__internal);
453 
454         let mut lifts = TokenStream::new();
455         let mut loads = TokenStream::new();
456 
457         for (i, syn::Field { ident, ty, .. }) in fields.iter().enumerate() {
458             let field_ty = quote!(ty.fields[#i].ty);
459             lifts.extend(quote!(#ident: <#ty as #wt::component::Lift>::lift(
460                 cx, #field_ty, &src.#ident
461             )?,));
462 
463             loads.extend(quote!(#ident: <#ty as #wt::component::Lift>::load(
464                 cx, #field_ty,
465                 &bytes
466                     [<#ty as #wt::component::ComponentType>::ABI.next_field32_size(&mut offset)..]
467                     [..<#ty as #wt::component::ComponentType>::SIZE32]
468             )?,));
469         }
470 
471         let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lift));
472         let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
473 
474         let extract_ty = quote! {
475             let ty = match ty {
476                 #internal::InterfaceType::Record(i) => &cx.types[i],
477                 _ => #internal::bad_type_info(),
478             };
479         };
480 
481         let expanded = quote! {
482             unsafe impl #impl_generics #wt::component::Lift for #name #ty_generics #where_clause {
483                 #[inline]
484                 fn lift(
485                     cx: &mut #internal::LiftContext<'_>,
486                     ty: #internal::InterfaceType,
487                     src: &Self::Lower,
488                 ) -> #internal::anyhow::Result<Self> {
489                     #extract_ty
490                     Ok(Self {
491                         #lifts
492                     })
493                 }
494 
495                 #[inline]
496                 fn load(
497                     cx: &mut #internal::LiftContext<'_>,
498                     ty: #internal::InterfaceType,
499                     bytes: &[u8],
500                 ) -> #internal::anyhow::Result<Self> {
501                     #extract_ty
502                     debug_assert!(
503                         (bytes.as_ptr() as usize)
504                             % (<Self as #wt::component::ComponentType>::ALIGN32 as usize)
505                             == 0
506                     );
507                     let mut offset = 0;
508                     Ok(Self {
509                         #loads
510                     })
511                 }
512             }
513         };
514 
515         Ok(expanded)
516     }
517 
518     fn expand_variant(
519         &self,
520         name: &syn::Ident,
521         generics: &syn::Generics,
522         discriminant_size: DiscriminantSize,
523         cases: &[VariantCase],
524         wt: &syn::Path,
525     ) -> Result<TokenStream> {
526         let internal = quote!(#wt::component::__internal);
527 
528         let mut lifts = TokenStream::new();
529         let mut loads = TokenStream::new();
530 
531         for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() {
532             let index_u32 = u32::try_from(index).unwrap();
533 
534             let index_quoted = quote(discriminant_size, index);
535 
536             if let Some(ty) = ty {
537                 let payload_ty = quote!(ty.cases[#index].unwrap_or_else(#internal::bad_type_info));
538                 lifts.extend(
539                     quote!(#index_u32 => Self::#ident(<#ty as #wt::component::Lift>::lift(
540                         cx, #payload_ty, unsafe { &src.payload.#ident }
541                     )?),),
542                 );
543 
544                 loads.extend(
545                     quote!(#index_quoted => Self::#ident(<#ty as #wt::component::Lift>::load(
546                         cx, #payload_ty, &payload[..<#ty as #wt::component::ComponentType>::SIZE32]
547                     )?),),
548                 );
549             } else {
550                 lifts.extend(quote!(#index_u32 => Self::#ident,));
551 
552                 loads.extend(quote!(#index_quoted => Self::#ident,));
553             }
554         }
555 
556         let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lift));
557         let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
558 
559         let from_bytes = match discriminant_size {
560             DiscriminantSize::Size1 => quote!(bytes[0]),
561             DiscriminantSize::Size2 => quote!(u16::from_le_bytes(bytes[0..2].try_into()?)),
562             DiscriminantSize::Size4 => quote!(u32::from_le_bytes(bytes[0..4].try_into()?)),
563         };
564 
565         let extract_ty = quote! {
566             let ty = match ty {
567                 #internal::InterfaceType::Variant(i) => &cx.types[i],
568                 _ => #internal::bad_type_info(),
569             };
570         };
571 
572         let expanded = quote! {
573             unsafe impl #impl_generics #wt::component::Lift for #name #ty_generics #where_clause {
574                 #[inline]
575                 fn lift(
576                     cx: &mut #internal::LiftContext<'_>,
577                     ty: #internal::InterfaceType,
578                     src: &Self::Lower,
579                 ) -> #internal::anyhow::Result<Self> {
580                     #extract_ty
581                     Ok(match src.tag.get_u32() {
582                         #lifts
583                         discrim => #internal::anyhow::bail!("unexpected discriminant: {}", discrim),
584                     })
585                 }
586 
587                 #[inline]
588                 fn load(
589                     cx: &mut #internal::LiftContext<'_>,
590                     ty: #internal::InterfaceType,
591                     bytes: &[u8],
592                 ) -> #internal::anyhow::Result<Self> {
593                     let align = <Self as #wt::component::ComponentType>::ALIGN32;
594                     debug_assert!((bytes.as_ptr() as usize) % (align as usize) == 0);
595                     let discrim = #from_bytes;
596                     let payload_offset = <Self as #internal::ComponentVariant>::PAYLOAD_OFFSET32;
597                     let payload = &bytes[payload_offset..];
598                     #extract_ty
599                     Ok(match discrim {
600                         #loads
601                         discrim => #internal::anyhow::bail!("unexpected discriminant: {}", discrim),
602                     })
603                 }
604             }
605         };
606 
607         Ok(expanded)
608     }
609 
610     fn expand_enum(
611         &self,
612         name: &syn::Ident,
613         discriminant_size: DiscriminantSize,
614         cases: &[VariantCase],
615         wt: &syn::Path,
616     ) -> Result<TokenStream> {
617         let internal = quote!(#wt::component::__internal);
618 
619         let (from_bytes, discrim_ty) = match discriminant_size {
620             DiscriminantSize::Size1 => (quote!(bytes[0]), quote!(u8)),
621             DiscriminantSize::Size2 => (
622                 quote!(u16::from_le_bytes(bytes[0..2].try_into()?)),
623                 quote!(u16),
624             ),
625             DiscriminantSize::Size4 => (
626                 quote!(u32::from_le_bytes(bytes[0..4].try_into()?)),
627                 quote!(u32),
628             ),
629         };
630         let discrim_limit = proc_macro2::Literal::usize_unsuffixed(cases.len());
631 
632         let extract_ty = quote! {
633             let ty = match ty {
634                 #internal::InterfaceType::Enum(i) => &cx.types[i],
635                 _ => #internal::bad_type_info(),
636             };
637         };
638 
639         let expanded = quote! {
640             unsafe impl #wt::component::Lift for #name {
641                 #[inline]
642                 fn lift(
643                     cx: &mut #internal::LiftContext<'_>,
644                     ty: #internal::InterfaceType,
645                     src: &Self::Lower,
646                 ) -> #internal::anyhow::Result<Self> {
647                     #extract_ty
648                     let discrim = src.tag.get_u32();
649                     if discrim >= #discrim_limit {
650                         #internal::anyhow::bail!("unexpected discriminant: {discrim}");
651                     }
652                     Ok(unsafe {
653                         #internal::transmute::<#discrim_ty, #name>(discrim as #discrim_ty)
654                     })
655                 }
656 
657                 #[inline]
658                 fn load(
659                     cx: &mut #internal::LiftContext<'_>,
660                     ty: #internal::InterfaceType,
661                     bytes: &[u8],
662                 ) -> #internal::anyhow::Result<Self> {
663                     let align = <Self as #wt::component::ComponentType>::ALIGN32;
664                     debug_assert!((bytes.as_ptr() as usize) % (align as usize) == 0);
665                     let discrim = #from_bytes;
666                     if discrim >= #discrim_limit {
667                         #internal::anyhow::bail!("unexpected discriminant: {discrim}");
668                     }
669                     Ok(unsafe {
670                         #internal::transmute::<#discrim_ty, #name>(discrim)
671                     })
672                 }
673             }
674         };
675 
676         Ok(expanded)
677     }
678 }
679 
680 pub struct LowerExpander;
681 
682 impl Expander for LowerExpander {
683     fn expand_record(
684         &self,
685         name: &syn::Ident,
686         generics: &syn::Generics,
687         fields: &[&syn::Field],
688         wt: &syn::Path,
689     ) -> Result<TokenStream> {
690         let internal = quote!(#wt::component::__internal);
691 
692         let mut lowers = TokenStream::new();
693         let mut stores = TokenStream::new();
694 
695         for (i, syn::Field { ident, ty, .. }) in fields.iter().enumerate() {
696             let field_ty = quote!(ty.fields[#i].ty);
697             lowers.extend(quote!(#wt::component::Lower::lower(
698                 &self.#ident, cx, #field_ty, #internal::map_maybe_uninit!(dst.#ident)
699             )?;));
700 
701             stores.extend(quote!(#wt::component::Lower::store(
702                 &self.#ident,
703                 cx,
704                 #field_ty,
705                 <#ty as #wt::component::ComponentType>::ABI.next_field32_size(&mut offset),
706             )?;));
707         }
708 
709         let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lower));
710         let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
711 
712         let extract_ty = quote! {
713             let ty = match ty {
714                 #internal::InterfaceType::Record(i) => &cx.types[i],
715                 _ => #internal::bad_type_info(),
716             };
717         };
718 
719         let expanded = quote! {
720             unsafe impl #impl_generics #wt::component::Lower for #name #ty_generics #where_clause {
721                 #[inline]
722                 fn lower<T>(
723                     &self,
724                     cx: &mut #internal::LowerContext<'_, T>,
725                     ty: #internal::InterfaceType,
726                     dst: &mut core::mem::MaybeUninit<Self::Lower>,
727                 ) -> #internal::anyhow::Result<()> {
728                     #extract_ty
729                     #lowers
730                     Ok(())
731                 }
732 
733                 #[inline]
734                 fn store<T>(
735                     &self,
736                     cx: &mut #internal::LowerContext<'_, T>,
737                     ty: #internal::InterfaceType,
738                     mut offset: usize
739                 ) -> #internal::anyhow::Result<()> {
740                     debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
741                     #extract_ty
742                     #stores
743                     Ok(())
744                 }
745             }
746         };
747 
748         Ok(expanded)
749     }
750 
751     fn expand_variant(
752         &self,
753         name: &syn::Ident,
754         generics: &syn::Generics,
755         discriminant_size: DiscriminantSize,
756         cases: &[VariantCase],
757         wt: &syn::Path,
758     ) -> Result<TokenStream> {
759         let internal = quote!(#wt::component::__internal);
760 
761         let mut lowers = TokenStream::new();
762         let mut stores = TokenStream::new();
763 
764         for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() {
765             let index_u32 = u32::try_from(index).unwrap();
766 
767             let index_quoted = quote(discriminant_size, index);
768 
769             let discriminant_size = usize::from(discriminant_size);
770 
771             let pattern;
772             let lower;
773             let store;
774 
775             if ty.is_some() {
776                 let ty = quote!(ty.cases[#index].unwrap_or_else(#internal::bad_type_info));
777                 pattern = quote!(Self::#ident(value));
778                 lower = quote!(value.lower(cx, #ty, dst));
779                 store = quote!(value.store(
780                     cx,
781                     #ty,
782                     offset + <Self as #internal::ComponentVariant>::PAYLOAD_OFFSET32,
783                 ));
784             } else {
785                 pattern = quote!(Self::#ident);
786                 lower = quote!(Ok(()));
787                 store = quote!(Ok(()));
788             }
789 
790             lowers.extend(quote!(#pattern => {
791                 #internal::map_maybe_uninit!(dst.tag).write(#wt::ValRaw::u32(#index_u32));
792                 unsafe {
793                     #internal::lower_payload(
794                         #internal::map_maybe_uninit!(dst.payload),
795                         |payload| #internal::map_maybe_uninit!(payload.#ident),
796                         |dst| #lower,
797                     )
798                 }
799             }));
800 
801             stores.extend(quote!(#pattern => {
802                 *cx.get::<#discriminant_size>(offset) = #index_quoted.to_le_bytes();
803                 #store
804             }));
805         }
806 
807         let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lower));
808         let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
809 
810         let extract_ty = quote! {
811             let ty = match ty {
812                 #internal::InterfaceType::Variant(i) => &cx.types[i],
813                 _ => #internal::bad_type_info(),
814             };
815         };
816 
817         let expanded = quote! {
818             unsafe impl #impl_generics #wt::component::Lower for #name #ty_generics #where_clause {
819                 #[inline]
820                 fn lower<T>(
821                     &self,
822                     cx: &mut #internal::LowerContext<'_, T>,
823                     ty: #internal::InterfaceType,
824                     dst: &mut core::mem::MaybeUninit<Self::Lower>,
825                 ) -> #internal::anyhow::Result<()> {
826                     #extract_ty
827                     match self {
828                         #lowers
829                     }
830                 }
831 
832                 #[inline]
833                 fn store<T>(
834                     &self,
835                     cx: &mut #internal::LowerContext<'_, T>,
836                     ty: #internal::InterfaceType,
837                     mut offset: usize
838                 ) -> #internal::anyhow::Result<()> {
839                     #extract_ty
840                     debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
841                     match self {
842                         #stores
843                     }
844                 }
845             }
846         };
847 
848         Ok(expanded)
849     }
850 
851     fn expand_enum(
852         &self,
853         name: &syn::Ident,
854         discriminant_size: DiscriminantSize,
855         _cases: &[VariantCase],
856         wt: &syn::Path,
857     ) -> Result<TokenStream> {
858         let internal = quote!(#wt::component::__internal);
859 
860         let extract_ty = quote! {
861             let ty = match ty {
862                 #internal::InterfaceType::Enum(i) => &cx.types[i],
863                 _ => #internal::bad_type_info(),
864             };
865         };
866 
867         let (size, ty) = match discriminant_size {
868             DiscriminantSize::Size1 => (1, quote!(u8)),
869             DiscriminantSize::Size2 => (2, quote!(u16)),
870             DiscriminantSize::Size4 => (4, quote!(u32)),
871         };
872         let size = proc_macro2::Literal::usize_unsuffixed(size);
873 
874         let expanded = quote! {
875             unsafe impl #wt::component::Lower for #name {
876                 #[inline]
877                 fn lower<T>(
878                     &self,
879                     cx: &mut #internal::LowerContext<'_, T>,
880                     ty: #internal::InterfaceType,
881                     dst: &mut core::mem::MaybeUninit<Self::Lower>,
882                 ) -> #internal::anyhow::Result<()> {
883                     #extract_ty
884                     #internal::map_maybe_uninit!(dst.tag)
885                         .write(#wt::ValRaw::u32(*self as u32));
886                     Ok(())
887                 }
888 
889                 #[inline]
890                 fn store<T>(
891                     &self,
892                     cx: &mut #internal::LowerContext<'_, T>,
893                     ty: #internal::InterfaceType,
894                     mut offset: usize
895                 ) -> #internal::anyhow::Result<()> {
896                     #extract_ty
897                     debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
898                     let discrim = *self as #ty;
899                     *cx.get::<#size>(offset) = discrim.to_le_bytes();
900                     Ok(())
901                 }
902             }
903         };
904 
905         Ok(expanded)
906     }
907 }
908 
909 pub struct ComponentTypeExpander;
910 
911 impl Expander for ComponentTypeExpander {
912     fn expand_record(
913         &self,
914         name: &syn::Ident,
915         generics: &syn::Generics,
916         fields: &[&syn::Field],
917         wt: &syn::Path,
918     ) -> Result<TokenStream> {
919         expand_record_for_component_type(
920             name,
921             generics,
922             fields,
923             quote!(typecheck_record),
924             fields
925                 .iter()
926                 .map(
927                     |syn::Field {
928                          attrs, ident, ty, ..
929                      }| {
930                         let name = find_rename(attrs)?.unwrap_or_else(|| {
931                             let ident = ident.as_ref().unwrap();
932                             syn::LitStr::new(&ident.to_string(), ident.span())
933                         });
934 
935                         Ok(quote!((#name, <#ty as #wt::component::ComponentType>::typecheck),))
936                     },
937                 )
938                 .collect::<Result<_>>()?,
939             wt,
940         )
941     }
942 
943     fn expand_variant(
944         &self,
945         name: &syn::Ident,
946         generics: &syn::Generics,
947         _discriminant_size: DiscriminantSize,
948         cases: &[VariantCase],
949         wt: &syn::Path,
950     ) -> Result<TokenStream> {
951         let internal = quote!(#wt::component::__internal);
952 
953         let mut case_names_and_checks = TokenStream::new();
954         let mut lower_payload_generic_params = TokenStream::new();
955         let mut lower_payload_generic_args = TokenStream::new();
956         let mut lower_payload_case_declarations = TokenStream::new();
957         let mut lower_generic_args = TokenStream::new();
958         let mut abi_list = TokenStream::new();
959         let mut unique_types = HashSet::new();
960 
961         for (index, VariantCase { attrs, ident, ty }) in cases.iter().enumerate() {
962             let rename = find_rename(attrs)?;
963 
964             let name = rename.unwrap_or_else(|| syn::LitStr::new(&ident.to_string(), ident.span()));
965 
966             if let Some(ty) = ty {
967                 abi_list.extend(quote!(Some(<#ty as #wt::component::ComponentType>::ABI),));
968 
969                 case_names_and_checks.extend(
970                     quote!((#name, Some(<#ty as #wt::component::ComponentType>::typecheck)),),
971                 );
972 
973                 let generic = format_ident!("T{}", index);
974 
975                 lower_payload_generic_params.extend(quote!(#generic: Copy,));
976                 lower_payload_generic_args.extend(quote!(#generic,));
977                 lower_payload_case_declarations.extend(quote!(#ident: #generic,));
978                 lower_generic_args.extend(quote!(<#ty as #wt::component::ComponentType>::Lower,));
979 
980                 unique_types.insert(ty);
981             } else {
982                 abi_list.extend(quote!(None,));
983                 case_names_and_checks.extend(quote!((#name, None),));
984                 lower_payload_case_declarations.extend(quote!(#ident: [#wt::ValRaw; 0],));
985             }
986         }
987 
988         let generics = add_trait_bounds(generics, parse_quote!(#wt::component::ComponentType));
989         let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
990         let lower = format_ident!("Lower{}", name);
991         let lower_payload = format_ident!("LowerPayload{}", name);
992 
993         // You may wonder why we make the types of all the fields of the #lower struct and #lower_payload union
994         // generic.  This is to work around a [normalization bug in
995         // rustc](https://github.com/rust-lang/rust/issues/90903) such that the compiler does not understand that
996         // e.g. `<i32 as ComponentType>::Lower` is `Copy` despite the bound specified in `ComponentType`'s
997         // definition.
998         //
999         // See also the comment in `Self::expand_record` above for another reason why we do this.
1000 
1001         let expanded = quote! {
1002             #[doc(hidden)]
1003             #[derive(Clone, Copy)]
1004             #[repr(C)]
1005             pub struct #lower<#lower_payload_generic_params> {
1006                 tag: #wt::ValRaw,
1007                 payload: #lower_payload<#lower_payload_generic_args>
1008             }
1009 
1010             #[doc(hidden)]
1011             #[allow(non_snake_case)]
1012             #[derive(Clone, Copy)]
1013             #[repr(C)]
1014             union #lower_payload<#lower_payload_generic_params> {
1015                 #lower_payload_case_declarations
1016             }
1017 
1018             unsafe impl #impl_generics #wt::component::ComponentType for #name #ty_generics #where_clause {
1019                 type Lower = #lower<#lower_generic_args>;
1020 
1021                 #[inline]
1022                 fn typecheck(
1023                     ty: &#internal::InterfaceType,
1024                     types: &#internal::InstanceType<'_>,
1025                 ) -> #internal::anyhow::Result<()> {
1026                     #internal::typecheck_variant(ty, types, &[#case_names_and_checks])
1027                 }
1028 
1029                 const ABI: #internal::CanonicalAbiInfo =
1030                     #internal::CanonicalAbiInfo::variant_static(&[#abi_list]);
1031             }
1032 
1033             unsafe impl #impl_generics #internal::ComponentVariant for #name #ty_generics #where_clause {
1034                 const CASES: &'static [Option<#internal::CanonicalAbiInfo>] = &[#abi_list];
1035             }
1036         };
1037 
1038         Ok(quote!(const _: () = { #expanded };))
1039     }
1040 
1041     fn expand_enum(
1042         &self,
1043         name: &syn::Ident,
1044         _discriminant_size: DiscriminantSize,
1045         cases: &[VariantCase],
1046         wt: &syn::Path,
1047     ) -> Result<TokenStream> {
1048         let internal = quote!(#wt::component::__internal);
1049 
1050         let mut case_names = TokenStream::new();
1051         let mut abi_list = TokenStream::new();
1052 
1053         for VariantCase { attrs, ident, ty } in cases.iter() {
1054             let rename = find_rename(attrs)?;
1055 
1056             let name = rename.unwrap_or_else(|| syn::LitStr::new(&ident.to_string(), ident.span()));
1057 
1058             if ty.is_some() {
1059                 return Err(Error::new(
1060                     ident.span(),
1061                     "payloads are not permitted for `enum` cases",
1062                 ));
1063             }
1064             abi_list.extend(quote!(None,));
1065             case_names.extend(quote!(#name,));
1066         }
1067 
1068         let lower = format_ident!("Lower{}", name);
1069 
1070         let cases_len = cases.len();
1071         let expanded = quote! {
1072             #[doc(hidden)]
1073             #[derive(Clone, Copy)]
1074             #[repr(C)]
1075             pub struct #lower {
1076                 tag: #wt::ValRaw,
1077             }
1078 
1079             unsafe impl #wt::component::ComponentType for #name {
1080                 type Lower = #lower;
1081 
1082                 #[inline]
1083                 fn typecheck(
1084                     ty: &#internal::InterfaceType,
1085                     types: &#internal::InstanceType<'_>,
1086                 ) -> #internal::anyhow::Result<()> {
1087                     #internal::typecheck_enum(ty, types, &[#case_names])
1088                 }
1089 
1090                 const ABI: #internal::CanonicalAbiInfo =
1091                     #internal::CanonicalAbiInfo::enum_(#cases_len);
1092             }
1093 
1094             unsafe impl #internal::ComponentVariant for #name {
1095                 const CASES: &'static [Option<#internal::CanonicalAbiInfo>] = &[#abi_list];
1096             }
1097         };
1098 
1099         Ok(quote!(const _: () = { #expanded };))
1100     }
1101 }
1102 
1103 #[derive(Debug)]
1104 struct Flag {
1105     rename: Option<String>,
1106     name: String,
1107 }
1108 
1109 impl Parse for Flag {
1110     fn parse(input: ParseStream) -> Result<Self> {
1111         let attributes = syn::Attribute::parse_outer(input)?;
1112 
1113         let rename = find_rename(&attributes)?.map(|literal| literal.value());
1114 
1115         input.parse::<Token![const]>()?;
1116         let name = input.parse::<syn::Ident>()?.to_string();
1117 
1118         Ok(Self { rename, name })
1119     }
1120 }
1121 
1122 #[derive(Debug)]
1123 pub struct Flags {
1124     name: String,
1125     flags: Vec<Flag>,
1126 }
1127 
1128 impl Parse for Flags {
1129     fn parse(input: ParseStream) -> Result<Self> {
1130         let name = input.parse::<syn::Ident>()?.to_string();
1131 
1132         let content;
1133         braced!(content in input);
1134 
1135         let flags = content
1136             .parse_terminated(Flag::parse, Token![;])?
1137             .into_iter()
1138             .collect();
1139 
1140         Ok(Self { name, flags })
1141     }
1142 }
1143 
1144 pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
1145     let wt = default_wasmtime_crate();
1146     let size = FlagsSize::from_count(flags.flags.len());
1147 
1148     let ty;
1149     let eq;
1150 
1151     let count = flags.flags.len();
1152 
1153     match size {
1154         FlagsSize::Size0 => {
1155             ty = quote!(());
1156             eq = quote!(true);
1157         }
1158         FlagsSize::Size1 => {
1159             ty = quote!(u8);
1160 
1161             eq = if count == 8 {
1162                 quote!(self.__inner0.eq(&rhs.__inner0))
1163             } else {
1164                 let mask = !(0xFF_u8 << count);
1165 
1166                 quote!((self.__inner0 & #mask).eq(&(rhs.__inner0 & #mask)))
1167             };
1168         }
1169         FlagsSize::Size2 => {
1170             ty = quote!(u16);
1171 
1172             eq = if count == 16 {
1173                 quote!(self.__inner0.eq(&rhs.__inner0))
1174             } else {
1175                 let mask = !(0xFFFF_u16 << count);
1176 
1177                 quote!((self.__inner0 & #mask).eq(&(rhs.__inner0 & #mask)))
1178             };
1179         }
1180         FlagsSize::Size4Plus(n) => {
1181             ty = quote!(u32);
1182 
1183             let comparisons = (0..(n - 1))
1184                 .map(|index| {
1185                     let field = format_ident!("__inner{}", index);
1186 
1187                     quote!(self.#field.eq(&rhs.#field) &&)
1188                 })
1189                 .collect::<TokenStream>();
1190 
1191             let field = format_ident!("__inner{}", n - 1);
1192 
1193             eq = if count % 32 == 0 {
1194                 quote!(#comparisons self.#field.eq(&rhs.#field))
1195             } else {
1196                 let mask = !(0xFFFF_FFFF_u32 << (count % 32));
1197 
1198                 quote!(#comparisons (self.#field & #mask).eq(&(rhs.#field & #mask)))
1199             }
1200         }
1201     }
1202 
1203     let count;
1204     let mut as_array;
1205     let mut bitor;
1206     let mut bitor_assign;
1207     let mut bitand;
1208     let mut bitand_assign;
1209     let mut bitxor;
1210     let mut bitxor_assign;
1211     let mut not;
1212 
1213     match size {
1214         FlagsSize::Size0 => {
1215             count = 0;
1216             as_array = quote!([]);
1217             bitor = quote!(Self {});
1218             bitor_assign = quote!();
1219             bitand = quote!(Self {});
1220             bitand_assign = quote!();
1221             bitxor = quote!(Self {});
1222             bitxor_assign = quote!();
1223             not = quote!(Self {});
1224         }
1225         FlagsSize::Size1 | FlagsSize::Size2 => {
1226             count = 1;
1227             as_array = quote!([self.__inner0 as u32]);
1228             bitor = quote!(Self {
1229                 __inner0: self.__inner0.bitor(rhs.__inner0)
1230             });
1231             bitor_assign = quote!(self.__inner0.bitor_assign(rhs.__inner0));
1232             bitand = quote!(Self {
1233                 __inner0: self.__inner0.bitand(rhs.__inner0)
1234             });
1235             bitand_assign = quote!(self.__inner0.bitand_assign(rhs.__inner0));
1236             bitxor = quote!(Self {
1237                 __inner0: self.__inner0.bitxor(rhs.__inner0)
1238             });
1239             bitxor_assign = quote!(self.__inner0.bitxor_assign(rhs.__inner0));
1240             not = quote!(Self {
1241                 __inner0: self.__inner0.not()
1242             });
1243         }
1244         FlagsSize::Size4Plus(n) => {
1245             count = usize::from(n);
1246             as_array = TokenStream::new();
1247             bitor = TokenStream::new();
1248             bitor_assign = TokenStream::new();
1249             bitand = TokenStream::new();
1250             bitand_assign = TokenStream::new();
1251             bitxor = TokenStream::new();
1252             bitxor_assign = TokenStream::new();
1253             not = TokenStream::new();
1254 
1255             for index in 0..n {
1256                 let field = format_ident!("__inner{}", index);
1257 
1258                 as_array.extend(quote!(self.#field,));
1259                 bitor.extend(quote!(#field: self.#field.bitor(rhs.#field),));
1260                 bitor_assign.extend(quote!(self.#field.bitor_assign(rhs.#field);));
1261                 bitand.extend(quote!(#field: self.#field.bitand(rhs.#field),));
1262                 bitand_assign.extend(quote!(self.#field.bitand_assign(rhs.#field);));
1263                 bitxor.extend(quote!(#field: self.#field.bitxor(rhs.#field),));
1264                 bitxor_assign.extend(quote!(self.#field.bitxor_assign(rhs.#field);));
1265                 not.extend(quote!(#field: self.#field.not(),));
1266             }
1267 
1268             as_array = quote!([#as_array]);
1269             bitor = quote!(Self { #bitor });
1270             bitand = quote!(Self { #bitand });
1271             bitxor = quote!(Self { #bitxor });
1272             not = quote!(Self { #not });
1273         }
1274     };
1275 
1276     let name = format_ident!("{}", flags.name);
1277 
1278     let mut constants = TokenStream::new();
1279     let mut rust_names = TokenStream::new();
1280     let mut component_names = TokenStream::new();
1281 
1282     for (index, Flag { name, rename }) in flags.flags.iter().enumerate() {
1283         rust_names.extend(quote!(#name,));
1284 
1285         let component_name = rename.as_ref().unwrap_or(name);
1286         component_names.extend(quote!(#component_name,));
1287 
1288         let fields = match size {
1289             FlagsSize::Size0 => quote!(),
1290             FlagsSize::Size1 => {
1291                 let init = 1_u8 << index;
1292                 quote!(__inner0: #init)
1293             }
1294             FlagsSize::Size2 => {
1295                 let init = 1_u16 << index;
1296                 quote!(__inner0: #init)
1297             }
1298             FlagsSize::Size4Plus(n) => (0..n)
1299                 .map(|i| {
1300                     let field = format_ident!("__inner{}", i);
1301 
1302                     let init = if index / 32 == usize::from(i) {
1303                         1_u32 << (index % 32)
1304                     } else {
1305                         0
1306                     };
1307 
1308                     quote!(#field: #init,)
1309                 })
1310                 .collect::<TokenStream>(),
1311         };
1312 
1313         let name = format_ident!("{}", name);
1314 
1315         constants.extend(quote!(pub const #name: Self = Self { #fields };));
1316     }
1317 
1318     let generics = syn::Generics {
1319         lt_token: None,
1320         params: Punctuated::new(),
1321         gt_token: None,
1322         where_clause: None,
1323     };
1324 
1325     let fields = {
1326         let ty = syn::parse2::<syn::Type>(ty.clone())?;
1327 
1328         (0..count)
1329             .map(|index| syn::Field {
1330                 attrs: Vec::new(),
1331                 vis: syn::Visibility::Inherited,
1332                 ident: Some(format_ident!("__inner{}", index)),
1333                 colon_token: None,
1334                 ty: ty.clone(),
1335                 mutability: syn::FieldMutability::None,
1336             })
1337             .collect::<Vec<_>>()
1338     };
1339 
1340     let fields = fields.iter().collect::<Vec<_>>();
1341 
1342     let component_type_impl = expand_record_for_component_type(
1343         &name,
1344         &generics,
1345         &fields,
1346         quote!(typecheck_flags),
1347         component_names,
1348         &wt,
1349     )?;
1350 
1351     let internal = quote!(#wt::component::__internal);
1352 
1353     let field_names = fields
1354         .iter()
1355         .map(|syn::Field { ident, .. }| ident)
1356         .collect::<Vec<_>>();
1357 
1358     let fields = fields
1359         .iter()
1360         .map(|syn::Field { ident, .. }| quote!(#[doc(hidden)] #ident: #ty,))
1361         .collect::<TokenStream>();
1362 
1363     let (field_interface_type, field_size) = match size {
1364         FlagsSize::Size0 => (quote!(NOT USED), 0usize),
1365         FlagsSize::Size1 => (quote!(#internal::InterfaceType::U8), 1),
1366         FlagsSize::Size2 => (quote!(#internal::InterfaceType::U16), 2),
1367         FlagsSize::Size4Plus(_) => (quote!(#internal::InterfaceType::U32), 4),
1368     };
1369 
1370     let expanded = quote! {
1371         #[derive(Copy, Clone, Default)]
1372         pub struct #name { #fields }
1373 
1374         impl #name {
1375             #constants
1376 
1377             pub fn as_array(&self) -> [u32; #count] {
1378                 #as_array
1379             }
1380 
1381             pub fn empty() -> Self {
1382                 Self::default()
1383             }
1384 
1385             pub fn all() -> Self {
1386                 use core::ops::Not;
1387                 Self::default().not()
1388             }
1389 
1390             pub fn contains(&self, other: Self) -> bool {
1391                 *self & other == other
1392             }
1393 
1394             pub fn intersects(&self, other: Self) -> bool {
1395                 *self & other != Self::empty()
1396             }
1397         }
1398 
1399         impl core::cmp::PartialEq for #name {
1400             fn eq(&self, rhs: &#name) -> bool {
1401                 #eq
1402             }
1403         }
1404 
1405         impl core::cmp::Eq for #name { }
1406 
1407         impl core::fmt::Debug for #name {
1408             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1409                 #internal::format_flags(&self.as_array(), &[#rust_names], f)
1410             }
1411         }
1412 
1413         impl core::ops::BitOr for #name {
1414             type Output = #name;
1415 
1416             fn bitor(self, rhs: #name) -> #name {
1417                 #bitor
1418             }
1419         }
1420 
1421         impl core::ops::BitOrAssign for #name {
1422             fn bitor_assign(&mut self, rhs: #name) {
1423                 #bitor_assign
1424             }
1425         }
1426 
1427         impl core::ops::BitAnd for #name {
1428             type Output = #name;
1429 
1430             fn bitand(self, rhs: #name) -> #name {
1431                 #bitand
1432             }
1433         }
1434 
1435         impl core::ops::BitAndAssign for #name {
1436             fn bitand_assign(&mut self, rhs: #name) {
1437                 #bitand_assign
1438             }
1439         }
1440 
1441         impl core::ops::BitXor for #name {
1442             type Output = #name;
1443 
1444             fn bitxor(self, rhs: #name) -> #name {
1445                 #bitxor
1446             }
1447         }
1448 
1449         impl core::ops::BitXorAssign for #name {
1450             fn bitxor_assign(&mut self, rhs: #name) {
1451                 #bitxor_assign
1452             }
1453         }
1454 
1455         impl core::ops::Not for #name {
1456             type Output = #name;
1457 
1458             fn not(self) -> #name {
1459                 #not
1460             }
1461         }
1462 
1463         #component_type_impl
1464 
1465         unsafe impl #wt::component::Lower for #name {
1466             fn lower<T>(
1467                 &self,
1468                 cx: &mut #internal::LowerContext<'_, T>,
1469                 _ty: #internal::InterfaceType,
1470                 dst: &mut core::mem::MaybeUninit<Self::Lower>,
1471             ) -> #internal::anyhow::Result<()> {
1472                 #(
1473                     self.#field_names.lower(
1474                         cx,
1475                         #field_interface_type,
1476                         #internal::map_maybe_uninit!(dst.#field_names),
1477                     )?;
1478                 )*
1479                 Ok(())
1480             }
1481 
1482             fn store<T>(
1483                 &self,
1484                 cx: &mut #internal::LowerContext<'_, T>,
1485                 _ty: #internal::InterfaceType,
1486                 mut offset: usize
1487             ) -> #internal::anyhow::Result<()> {
1488                 debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
1489                 #(
1490                     self.#field_names.store(
1491                         cx,
1492                         #field_interface_type,
1493                         offset,
1494                     )?;
1495                     offset += core::mem::size_of_val(&self.#field_names);
1496                 )*
1497                 Ok(())
1498             }
1499         }
1500 
1501         unsafe impl #wt::component::Lift for #name {
1502             fn lift(
1503                 cx: &mut #internal::LiftContext<'_>,
1504                 _ty: #internal::InterfaceType,
1505                 src: &Self::Lower,
1506             ) -> #internal::anyhow::Result<Self> {
1507                 Ok(Self {
1508                     #(
1509                         #field_names: #wt::component::Lift::lift(
1510                             cx,
1511                             #field_interface_type,
1512                             &src.#field_names,
1513                         )?,
1514                     )*
1515                 })
1516             }
1517 
1518             fn load(
1519                 cx: &mut #internal::LiftContext<'_>,
1520                 _ty: #internal::InterfaceType,
1521                 bytes: &[u8],
1522             ) -> #internal::anyhow::Result<Self> {
1523                 debug_assert!(
1524                     (bytes.as_ptr() as usize)
1525                         % (<Self as #wt::component::ComponentType>::ALIGN32 as usize)
1526                         == 0
1527                 );
1528                 #(
1529                     let (field, bytes) = bytes.split_at(#field_size);
1530                     let #field_names = #wt::component::Lift::load(
1531                         cx,
1532                         #field_interface_type,
1533                         field,
1534                     )?;
1535                 )*
1536                 Ok(Self { #(#field_names,)* })
1537             }
1538         }
1539     };
1540 
1541     Ok(expanded)
1542 }
1543