wasmtime_internal_component_macro/
component.rs

1use proc_macro2::{Span, TokenStream};
2use quote::{format_ident, quote};
3use std::collections::HashSet;
4use std::fmt;
5use syn::parse::{Parse, ParseStream};
6use syn::punctuated::Punctuated;
7use syn::{Data, DeriveInput, Error, Ident, Result, Token, braced, parse_quote};
8use wasmtime_component_util::{DiscriminantSize, FlagsSize};
9
10mod 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)]
19enum Style {
20    Record,
21    Enum,
22    Variant,
23}
24
25impl 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)]
36enum ComponentAttr {
37    Style(Style),
38    WasmtimeCrate(syn::Path),
39}
40
41impl 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
68fn 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
94fn 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
104pub struct VariantCase<'a> {
105    attrs: &'a [syn::Attribute],
106    ident: &'a syn::Ident,
107    ty: Option<&'a syn::Type>,
108}
109
110pub 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
137pub 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
167fn default_wasmtime_crate() -> syn::Path {
168    Ident::new("wasmtime", Span::call_site()).into()
169}
170
171fn 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
202fn 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.
293fn 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
347fn 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
425fn 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
442pub struct LiftExpander;
443
444impl 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(
460                quote!(#ident: <#ty as #wt::component::Lift>::linear_lift_from_flat(
461                cx, #field_ty, &src.#ident
462            )?,),
463            );
464
465            loads.extend(
466                quote!(#ident: <#ty as #wt::component::Lift>::linear_lift_from_memory(
467                cx, #field_ty,
468                &bytes
469                    [<#ty as #wt::component::ComponentType>::ABI.next_field32_size(&mut offset)..]
470                    [..<#ty as #wt::component::ComponentType>::SIZE32]
471            )?,),
472            );
473        }
474
475        let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lift));
476        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
477
478        let extract_ty = quote! {
479            let ty = match ty {
480                #internal::InterfaceType::Record(i) => &cx.types[i],
481                _ => #internal::bad_type_info(),
482            };
483        };
484
485        let expanded = quote! {
486            unsafe impl #impl_generics #wt::component::Lift for #name #ty_generics #where_clause {
487                #[inline]
488                fn linear_lift_from_flat(
489                    cx: &mut #internal::LiftContext<'_>,
490                    ty: #internal::InterfaceType,
491                    src: &Self::Lower,
492                ) -> #internal::anyhow::Result<Self> {
493                    #extract_ty
494                    Ok(Self {
495                        #lifts
496                    })
497                }
498
499                #[inline]
500                fn linear_lift_from_memory(
501                    cx: &mut #internal::LiftContext<'_>,
502                    ty: #internal::InterfaceType,
503                    bytes: &[u8],
504                ) -> #internal::anyhow::Result<Self> {
505                    #extract_ty
506                    debug_assert!(
507                        (bytes.as_ptr() as usize)
508                            % (<Self as #wt::component::ComponentType>::ALIGN32 as usize)
509                            == 0
510                    );
511                    let mut offset = 0;
512                    Ok(Self {
513                        #loads
514                    })
515                }
516            }
517        };
518
519        Ok(expanded)
520    }
521
522    fn expand_variant(
523        &self,
524        name: &syn::Ident,
525        generics: &syn::Generics,
526        discriminant_size: DiscriminantSize,
527        cases: &[VariantCase],
528        wt: &syn::Path,
529    ) -> Result<TokenStream> {
530        let internal = quote!(#wt::component::__internal);
531
532        let mut lifts = TokenStream::new();
533        let mut loads = TokenStream::new();
534
535        for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() {
536            let index_u32 = u32::try_from(index).unwrap();
537
538            let index_quoted = quote(discriminant_size, index);
539
540            if let Some(ty) = ty {
541                let payload_ty = quote!(ty.cases[#index].unwrap_or_else(#internal::bad_type_info));
542                lifts.extend(
543                    quote!(#index_u32 => Self::#ident(<#ty as #wt::component::Lift>::linear_lift_from_flat(
544                        cx, #payload_ty, unsafe { &src.payload.#ident }
545                    )?),),
546                );
547
548                loads.extend(
549                    quote!(#index_quoted => Self::#ident(<#ty as #wt::component::Lift>::linear_lift_from_memory(
550                        cx, #payload_ty, &payload[..<#ty as #wt::component::ComponentType>::SIZE32]
551                    )?),),
552                );
553            } else {
554                lifts.extend(quote!(#index_u32 => Self::#ident,));
555
556                loads.extend(quote!(#index_quoted => Self::#ident,));
557            }
558        }
559
560        let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lift));
561        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
562
563        let from_bytes = match discriminant_size {
564            DiscriminantSize::Size1 => quote!(bytes[0]),
565            DiscriminantSize::Size2 => quote!(u16::from_le_bytes(bytes[0..2].try_into()?)),
566            DiscriminantSize::Size4 => quote!(u32::from_le_bytes(bytes[0..4].try_into()?)),
567        };
568
569        let extract_ty = quote! {
570            let ty = match ty {
571                #internal::InterfaceType::Variant(i) => &cx.types[i],
572                _ => #internal::bad_type_info(),
573            };
574        };
575
576        let expanded = quote! {
577            unsafe impl #impl_generics #wt::component::Lift for #name #ty_generics #where_clause {
578                #[inline]
579                fn linear_lift_from_flat(
580                    cx: &mut #internal::LiftContext<'_>,
581                    ty: #internal::InterfaceType,
582                    src: &Self::Lower,
583                ) -> #internal::anyhow::Result<Self> {
584                    #extract_ty
585                    Ok(match src.tag.get_u32() {
586                        #lifts
587                        discrim => #internal::anyhow::bail!("unexpected discriminant: {}", discrim),
588                    })
589                }
590
591                #[inline]
592                fn linear_lift_from_memory(
593                    cx: &mut #internal::LiftContext<'_>,
594                    ty: #internal::InterfaceType,
595                    bytes: &[u8],
596                ) -> #internal::anyhow::Result<Self> {
597                    let align = <Self as #wt::component::ComponentType>::ALIGN32;
598                    debug_assert!((bytes.as_ptr() as usize) % (align as usize) == 0);
599                    let discrim = #from_bytes;
600                    let payload_offset = <Self as #internal::ComponentVariant>::PAYLOAD_OFFSET32;
601                    let payload = &bytes[payload_offset..];
602                    #extract_ty
603                    Ok(match discrim {
604                        #loads
605                        discrim => #internal::anyhow::bail!("unexpected discriminant: {}", discrim),
606                    })
607                }
608            }
609        };
610
611        Ok(expanded)
612    }
613
614    fn expand_enum(
615        &self,
616        name: &syn::Ident,
617        discriminant_size: DiscriminantSize,
618        cases: &[VariantCase],
619        wt: &syn::Path,
620    ) -> Result<TokenStream> {
621        let internal = quote!(#wt::component::__internal);
622
623        let (from_bytes, discrim_ty) = match discriminant_size {
624            DiscriminantSize::Size1 => (quote!(bytes[0]), quote!(u8)),
625            DiscriminantSize::Size2 => (
626                quote!(u16::from_le_bytes(bytes[0..2].try_into()?)),
627                quote!(u16),
628            ),
629            DiscriminantSize::Size4 => (
630                quote!(u32::from_le_bytes(bytes[0..4].try_into()?)),
631                quote!(u32),
632            ),
633        };
634        let discrim_limit = proc_macro2::Literal::usize_unsuffixed(cases.len());
635
636        let extract_ty = quote! {
637            let ty = match ty {
638                #internal::InterfaceType::Enum(i) => &cx.types[i],
639                _ => #internal::bad_type_info(),
640            };
641        };
642
643        let expanded = quote! {
644            unsafe impl #wt::component::Lift for #name {
645                #[inline]
646                fn linear_lift_from_flat(
647                    cx: &mut #internal::LiftContext<'_>,
648                    ty: #internal::InterfaceType,
649                    src: &Self::Lower,
650                ) -> #internal::anyhow::Result<Self> {
651                    #extract_ty
652                    let discrim = src.tag.get_u32();
653                    if discrim >= #discrim_limit {
654                        #internal::anyhow::bail!("unexpected discriminant: {discrim}");
655                    }
656                    Ok(unsafe {
657                        #internal::transmute::<#discrim_ty, #name>(discrim as #discrim_ty)
658                    })
659                }
660
661                #[inline]
662                fn linear_lift_from_memory(
663                    cx: &mut #internal::LiftContext<'_>,
664                    ty: #internal::InterfaceType,
665                    bytes: &[u8],
666                ) -> #internal::anyhow::Result<Self> {
667                    let align = <Self as #wt::component::ComponentType>::ALIGN32;
668                    debug_assert!((bytes.as_ptr() as usize) % (align as usize) == 0);
669                    let discrim = #from_bytes;
670                    if discrim >= #discrim_limit {
671                        #internal::anyhow::bail!("unexpected discriminant: {discrim}");
672                    }
673                    Ok(unsafe {
674                        #internal::transmute::<#discrim_ty, #name>(discrim)
675                    })
676                }
677            }
678        };
679
680        Ok(expanded)
681    }
682}
683
684pub struct LowerExpander;
685
686impl Expander for LowerExpander {
687    fn expand_record(
688        &self,
689        name: &syn::Ident,
690        generics: &syn::Generics,
691        fields: &[&syn::Field],
692        wt: &syn::Path,
693    ) -> Result<TokenStream> {
694        let internal = quote!(#wt::component::__internal);
695
696        let mut lowers = TokenStream::new();
697        let mut stores = TokenStream::new();
698
699        for (i, syn::Field { ident, ty, .. }) in fields.iter().enumerate() {
700            let field_ty = quote!(ty.fields[#i].ty);
701            lowers.extend(quote!(#wt::component::Lower::linear_lower_to_flat(
702                &self.#ident, cx, #field_ty, #internal::map_maybe_uninit!(dst.#ident)
703            )?;));
704
705            stores.extend(quote!(#wt::component::Lower::linear_lower_to_memory(
706                &self.#ident,
707                cx,
708                #field_ty,
709                <#ty as #wt::component::ComponentType>::ABI.next_field32_size(&mut offset),
710            )?;));
711        }
712
713        let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lower));
714        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
715
716        let extract_ty = quote! {
717            let ty = match ty {
718                #internal::InterfaceType::Record(i) => &cx.types[i],
719                _ => #internal::bad_type_info(),
720            };
721        };
722
723        let expanded = quote! {
724            unsafe impl #impl_generics #wt::component::Lower for #name #ty_generics #where_clause {
725                #[inline]
726                fn linear_lower_to_flat<T>(
727                    &self,
728                    cx: &mut #internal::LowerContext<'_, T>,
729                    ty: #internal::InterfaceType,
730                    dst: &mut core::mem::MaybeUninit<Self::Lower>,
731                ) -> #internal::anyhow::Result<()> {
732                    #extract_ty
733                    #lowers
734                    Ok(())
735                }
736
737                #[inline]
738                fn linear_lower_to_memory<T>(
739                    &self,
740                    cx: &mut #internal::LowerContext<'_, T>,
741                    ty: #internal::InterfaceType,
742                    mut offset: usize
743                ) -> #internal::anyhow::Result<()> {
744                    debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
745                    #extract_ty
746                    #stores
747                    Ok(())
748                }
749            }
750        };
751
752        Ok(expanded)
753    }
754
755    fn expand_variant(
756        &self,
757        name: &syn::Ident,
758        generics: &syn::Generics,
759        discriminant_size: DiscriminantSize,
760        cases: &[VariantCase],
761        wt: &syn::Path,
762    ) -> Result<TokenStream> {
763        let internal = quote!(#wt::component::__internal);
764
765        let mut lowers = TokenStream::new();
766        let mut stores = TokenStream::new();
767
768        for (index, VariantCase { ident, ty, .. }) in cases.iter().enumerate() {
769            let index_u32 = u32::try_from(index).unwrap();
770
771            let index_quoted = quote(discriminant_size, index);
772
773            let discriminant_size = usize::from(discriminant_size);
774
775            let pattern;
776            let lower;
777            let store;
778
779            if ty.is_some() {
780                let ty = quote!(ty.cases[#index].unwrap_or_else(#internal::bad_type_info));
781                pattern = quote!(Self::#ident(value));
782                lower = quote!(value.linear_lower_to_flat(cx, #ty, dst));
783                store = quote!(value.linear_lower_to_memory(
784                    cx,
785                    #ty,
786                    offset + <Self as #internal::ComponentVariant>::PAYLOAD_OFFSET32,
787                ));
788            } else {
789                pattern = quote!(Self::#ident);
790                lower = quote!(Ok(()));
791                store = quote!(Ok(()));
792            }
793
794            lowers.extend(quote!(#pattern => {
795                #internal::map_maybe_uninit!(dst.tag).write(#wt::ValRaw::u32(#index_u32));
796                unsafe {
797                    #internal::lower_payload(
798                        #internal::map_maybe_uninit!(dst.payload),
799                        |payload| #internal::map_maybe_uninit!(payload.#ident),
800                        |dst| #lower,
801                    )
802                }
803            }));
804
805            stores.extend(quote!(#pattern => {
806                *cx.get::<#discriminant_size>(offset) = #index_quoted.to_le_bytes();
807                #store
808            }));
809        }
810
811        let generics = add_trait_bounds(generics, parse_quote!(#wt::component::Lower));
812        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
813
814        let extract_ty = quote! {
815            let ty = match ty {
816                #internal::InterfaceType::Variant(i) => &cx.types[i],
817                _ => #internal::bad_type_info(),
818            };
819        };
820
821        let expanded = quote! {
822            unsafe impl #impl_generics #wt::component::Lower for #name #ty_generics #where_clause {
823                #[inline]
824                fn linear_lower_to_flat<T>(
825                    &self,
826                    cx: &mut #internal::LowerContext<'_, T>,
827                    ty: #internal::InterfaceType,
828                    dst: &mut core::mem::MaybeUninit<Self::Lower>,
829                ) -> #internal::anyhow::Result<()> {
830                    #extract_ty
831                    match self {
832                        #lowers
833                    }
834                }
835
836                #[inline]
837                fn linear_lower_to_memory<T>(
838                    &self,
839                    cx: &mut #internal::LowerContext<'_, T>,
840                    ty: #internal::InterfaceType,
841                    mut offset: usize
842                ) -> #internal::anyhow::Result<()> {
843                    #extract_ty
844                    debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
845                    match self {
846                        #stores
847                    }
848                }
849            }
850        };
851
852        Ok(expanded)
853    }
854
855    fn expand_enum(
856        &self,
857        name: &syn::Ident,
858        discriminant_size: DiscriminantSize,
859        _cases: &[VariantCase],
860        wt: &syn::Path,
861    ) -> Result<TokenStream> {
862        let internal = quote!(#wt::component::__internal);
863
864        let extract_ty = quote! {
865            let ty = match ty {
866                #internal::InterfaceType::Enum(i) => &cx.types[i],
867                _ => #internal::bad_type_info(),
868            };
869        };
870
871        let (size, ty) = match discriminant_size {
872            DiscriminantSize::Size1 => (1, quote!(u8)),
873            DiscriminantSize::Size2 => (2, quote!(u16)),
874            DiscriminantSize::Size4 => (4, quote!(u32)),
875        };
876        let size = proc_macro2::Literal::usize_unsuffixed(size);
877
878        let expanded = quote! {
879            unsafe impl #wt::component::Lower for #name {
880                #[inline]
881                fn linear_lower_to_flat<T>(
882                    &self,
883                    cx: &mut #internal::LowerContext<'_, T>,
884                    ty: #internal::InterfaceType,
885                    dst: &mut core::mem::MaybeUninit<Self::Lower>,
886                ) -> #internal::anyhow::Result<()> {
887                    #extract_ty
888                    #internal::map_maybe_uninit!(dst.tag)
889                        .write(#wt::ValRaw::u32(*self as u32));
890                    Ok(())
891                }
892
893                #[inline]
894                fn linear_lower_to_memory<T>(
895                    &self,
896                    cx: &mut #internal::LowerContext<'_, T>,
897                    ty: #internal::InterfaceType,
898                    mut offset: usize
899                ) -> #internal::anyhow::Result<()> {
900                    #extract_ty
901                    debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
902                    let discrim = *self as #ty;
903                    *cx.get::<#size>(offset) = discrim.to_le_bytes();
904                    Ok(())
905                }
906            }
907        };
908
909        Ok(expanded)
910    }
911}
912
913pub struct ComponentTypeExpander;
914
915impl Expander for ComponentTypeExpander {
916    fn expand_record(
917        &self,
918        name: &syn::Ident,
919        generics: &syn::Generics,
920        fields: &[&syn::Field],
921        wt: &syn::Path,
922    ) -> Result<TokenStream> {
923        expand_record_for_component_type(
924            name,
925            generics,
926            fields,
927            quote!(typecheck_record),
928            fields
929                .iter()
930                .map(
931                    |syn::Field {
932                         attrs, ident, ty, ..
933                     }| {
934                        let name = find_rename(attrs)?.unwrap_or_else(|| {
935                            let ident = ident.as_ref().unwrap();
936                            syn::LitStr::new(&ident.to_string(), ident.span())
937                        });
938
939                        Ok(quote!((#name, <#ty as #wt::component::ComponentType>::typecheck),))
940                    },
941                )
942                .collect::<Result<_>>()?,
943            wt,
944        )
945    }
946
947    fn expand_variant(
948        &self,
949        name: &syn::Ident,
950        generics: &syn::Generics,
951        _discriminant_size: DiscriminantSize,
952        cases: &[VariantCase],
953        wt: &syn::Path,
954    ) -> Result<TokenStream> {
955        let internal = quote!(#wt::component::__internal);
956
957        let mut case_names_and_checks = TokenStream::new();
958        let mut lower_payload_generic_params = TokenStream::new();
959        let mut lower_payload_generic_args = TokenStream::new();
960        let mut lower_payload_case_declarations = TokenStream::new();
961        let mut lower_generic_args = TokenStream::new();
962        let mut abi_list = TokenStream::new();
963        let mut unique_types = HashSet::new();
964
965        for (index, VariantCase { attrs, ident, ty }) in cases.iter().enumerate() {
966            let rename = find_rename(attrs)?;
967
968            let name = rename.unwrap_or_else(|| syn::LitStr::new(&ident.to_string(), ident.span()));
969
970            if let Some(ty) = ty {
971                abi_list.extend(quote!(Some(<#ty as #wt::component::ComponentType>::ABI),));
972
973                case_names_and_checks.extend(
974                    quote!((#name, Some(<#ty as #wt::component::ComponentType>::typecheck)),),
975                );
976
977                let generic = format_ident!("T{}", index);
978
979                lower_payload_generic_params.extend(quote!(#generic: Copy,));
980                lower_payload_generic_args.extend(quote!(#generic,));
981                lower_payload_case_declarations.extend(quote!(#ident: #generic,));
982                lower_generic_args.extend(quote!(<#ty as #wt::component::ComponentType>::Lower,));
983
984                unique_types.insert(ty);
985            } else {
986                abi_list.extend(quote!(None,));
987                case_names_and_checks.extend(quote!((#name, None),));
988                lower_payload_case_declarations.extend(quote!(#ident: [#wt::ValRaw; 0],));
989            }
990        }
991
992        let generics = add_trait_bounds(generics, parse_quote!(#wt::component::ComponentType));
993        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
994        let lower = format_ident!("Lower{}", name);
995        let lower_payload = format_ident!("LowerPayload{}", name);
996
997        // You may wonder why we make the types of all the fields of the #lower struct and #lower_payload union
998        // generic.  This is to work around a [normalization bug in
999        // rustc](https://github.com/rust-lang/rust/issues/90903) such that the compiler does not understand that
1000        // e.g. `<i32 as ComponentType>::Lower` is `Copy` despite the bound specified in `ComponentType`'s
1001        // definition.
1002        //
1003        // See also the comment in `Self::expand_record` above for another reason why we do this.
1004
1005        let expanded = quote! {
1006            #[doc(hidden)]
1007            #[derive(Clone, Copy)]
1008            #[repr(C)]
1009            pub struct #lower<#lower_payload_generic_params> {
1010                tag: #wt::ValRaw,
1011                payload: #lower_payload<#lower_payload_generic_args>
1012            }
1013
1014            #[doc(hidden)]
1015            #[allow(non_snake_case)]
1016            #[derive(Clone, Copy)]
1017            #[repr(C)]
1018            union #lower_payload<#lower_payload_generic_params> {
1019                #lower_payload_case_declarations
1020            }
1021
1022            unsafe impl #impl_generics #wt::component::ComponentType for #name #ty_generics #where_clause {
1023                type Lower = #lower<#lower_generic_args>;
1024
1025                #[inline]
1026                fn typecheck(
1027                    ty: &#internal::InterfaceType,
1028                    types: &#internal::InstanceType<'_>,
1029                ) -> #internal::anyhow::Result<()> {
1030                    #internal::typecheck_variant(ty, types, &[#case_names_and_checks])
1031                }
1032
1033                const ABI: #internal::CanonicalAbiInfo =
1034                    #internal::CanonicalAbiInfo::variant_static(&[#abi_list]);
1035            }
1036
1037            unsafe impl #impl_generics #internal::ComponentVariant for #name #ty_generics #where_clause {
1038                const CASES: &'static [Option<#internal::CanonicalAbiInfo>] = &[#abi_list];
1039            }
1040        };
1041
1042        Ok(quote!(const _: () = { #expanded };))
1043    }
1044
1045    fn expand_enum(
1046        &self,
1047        name: &syn::Ident,
1048        _discriminant_size: DiscriminantSize,
1049        cases: &[VariantCase],
1050        wt: &syn::Path,
1051    ) -> Result<TokenStream> {
1052        let internal = quote!(#wt::component::__internal);
1053
1054        let mut case_names = TokenStream::new();
1055        let mut abi_list = TokenStream::new();
1056
1057        for VariantCase { attrs, ident, ty } in cases.iter() {
1058            let rename = find_rename(attrs)?;
1059
1060            let name = rename.unwrap_or_else(|| syn::LitStr::new(&ident.to_string(), ident.span()));
1061
1062            if ty.is_some() {
1063                return Err(Error::new(
1064                    ident.span(),
1065                    "payloads are not permitted for `enum` cases",
1066                ));
1067            }
1068            abi_list.extend(quote!(None,));
1069            case_names.extend(quote!(#name,));
1070        }
1071
1072        let lower = format_ident!("Lower{}", name);
1073
1074        let cases_len = cases.len();
1075        let expanded = quote! {
1076            #[doc(hidden)]
1077            #[derive(Clone, Copy)]
1078            #[repr(C)]
1079            pub struct #lower {
1080                tag: #wt::ValRaw,
1081            }
1082
1083            unsafe impl #wt::component::ComponentType for #name {
1084                type Lower = #lower;
1085
1086                #[inline]
1087                fn typecheck(
1088                    ty: &#internal::InterfaceType,
1089                    types: &#internal::InstanceType<'_>,
1090                ) -> #internal::anyhow::Result<()> {
1091                    #internal::typecheck_enum(ty, types, &[#case_names])
1092                }
1093
1094                const ABI: #internal::CanonicalAbiInfo =
1095                    #internal::CanonicalAbiInfo::enum_(#cases_len);
1096            }
1097
1098            unsafe impl #internal::ComponentVariant for #name {
1099                const CASES: &'static [Option<#internal::CanonicalAbiInfo>] = &[#abi_list];
1100            }
1101        };
1102
1103        Ok(quote!(const _: () = { #expanded };))
1104    }
1105}
1106
1107#[derive(Debug)]
1108struct Flag {
1109    rename: Option<String>,
1110    name: String,
1111}
1112
1113impl Parse for Flag {
1114    fn parse(input: ParseStream) -> Result<Self> {
1115        let attributes = syn::Attribute::parse_outer(input)?;
1116
1117        let rename = find_rename(&attributes)?.map(|literal| literal.value());
1118
1119        input.parse::<Token![const]>()?;
1120        let name = input.parse::<syn::Ident>()?.to_string();
1121
1122        Ok(Self { rename, name })
1123    }
1124}
1125
1126#[derive(Debug)]
1127pub struct Flags {
1128    name: String,
1129    flags: Vec<Flag>,
1130}
1131
1132impl Parse for Flags {
1133    fn parse(input: ParseStream) -> Result<Self> {
1134        let name = input.parse::<syn::Ident>()?.to_string();
1135
1136        let content;
1137        braced!(content in input);
1138
1139        let flags = content
1140            .parse_terminated(Flag::parse, Token![;])?
1141            .into_iter()
1142            .collect();
1143
1144        Ok(Self { name, flags })
1145    }
1146}
1147
1148pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
1149    let wt = default_wasmtime_crate();
1150    let size = FlagsSize::from_count(flags.flags.len());
1151
1152    let ty;
1153    let eq;
1154
1155    let count = flags.flags.len();
1156
1157    match size {
1158        FlagsSize::Size0 => {
1159            ty = quote!(());
1160            eq = quote!(true);
1161        }
1162        FlagsSize::Size1 => {
1163            ty = quote!(u8);
1164
1165            eq = if count == 8 {
1166                quote!(self.__inner0.eq(&rhs.__inner0))
1167            } else {
1168                let mask = !(0xFF_u8 << count);
1169
1170                quote!((self.__inner0 & #mask).eq(&(rhs.__inner0 & #mask)))
1171            };
1172        }
1173        FlagsSize::Size2 => {
1174            ty = quote!(u16);
1175
1176            eq = if count == 16 {
1177                quote!(self.__inner0.eq(&rhs.__inner0))
1178            } else {
1179                let mask = !(0xFFFF_u16 << count);
1180
1181                quote!((self.__inner0 & #mask).eq(&(rhs.__inner0 & #mask)))
1182            };
1183        }
1184        FlagsSize::Size4Plus(n) => {
1185            ty = quote!(u32);
1186
1187            let comparisons = (0..(n - 1))
1188                .map(|index| {
1189                    let field = format_ident!("__inner{}", index);
1190
1191                    quote!(self.#field.eq(&rhs.#field) &&)
1192                })
1193                .collect::<TokenStream>();
1194
1195            let field = format_ident!("__inner{}", n - 1);
1196
1197            eq = if count % 32 == 0 {
1198                quote!(#comparisons self.#field.eq(&rhs.#field))
1199            } else {
1200                let mask = !(0xFFFF_FFFF_u32 << (count % 32));
1201
1202                quote!(#comparisons (self.#field & #mask).eq(&(rhs.#field & #mask)))
1203            }
1204        }
1205    }
1206
1207    let count;
1208    let mut as_array;
1209    let mut bitor;
1210    let mut bitor_assign;
1211    let mut bitand;
1212    let mut bitand_assign;
1213    let mut bitxor;
1214    let mut bitxor_assign;
1215    let mut not;
1216
1217    match size {
1218        FlagsSize::Size0 => {
1219            count = 0;
1220            as_array = quote!([]);
1221            bitor = quote!(Self {});
1222            bitor_assign = quote!();
1223            bitand = quote!(Self {});
1224            bitand_assign = quote!();
1225            bitxor = quote!(Self {});
1226            bitxor_assign = quote!();
1227            not = quote!(Self {});
1228        }
1229        FlagsSize::Size1 | FlagsSize::Size2 => {
1230            count = 1;
1231            as_array = quote!([self.__inner0 as u32]);
1232            bitor = quote!(Self {
1233                __inner0: self.__inner0.bitor(rhs.__inner0)
1234            });
1235            bitor_assign = quote!(self.__inner0.bitor_assign(rhs.__inner0));
1236            bitand = quote!(Self {
1237                __inner0: self.__inner0.bitand(rhs.__inner0)
1238            });
1239            bitand_assign = quote!(self.__inner0.bitand_assign(rhs.__inner0));
1240            bitxor = quote!(Self {
1241                __inner0: self.__inner0.bitxor(rhs.__inner0)
1242            });
1243            bitxor_assign = quote!(self.__inner0.bitxor_assign(rhs.__inner0));
1244            not = quote!(Self {
1245                __inner0: self.__inner0.not()
1246            });
1247        }
1248        FlagsSize::Size4Plus(n) => {
1249            count = usize::from(n);
1250            as_array = TokenStream::new();
1251            bitor = TokenStream::new();
1252            bitor_assign = TokenStream::new();
1253            bitand = TokenStream::new();
1254            bitand_assign = TokenStream::new();
1255            bitxor = TokenStream::new();
1256            bitxor_assign = TokenStream::new();
1257            not = TokenStream::new();
1258
1259            for index in 0..n {
1260                let field = format_ident!("__inner{}", index);
1261
1262                as_array.extend(quote!(self.#field,));
1263                bitor.extend(quote!(#field: self.#field.bitor(rhs.#field),));
1264                bitor_assign.extend(quote!(self.#field.bitor_assign(rhs.#field);));
1265                bitand.extend(quote!(#field: self.#field.bitand(rhs.#field),));
1266                bitand_assign.extend(quote!(self.#field.bitand_assign(rhs.#field);));
1267                bitxor.extend(quote!(#field: self.#field.bitxor(rhs.#field),));
1268                bitxor_assign.extend(quote!(self.#field.bitxor_assign(rhs.#field);));
1269                not.extend(quote!(#field: self.#field.not(),));
1270            }
1271
1272            as_array = quote!([#as_array]);
1273            bitor = quote!(Self { #bitor });
1274            bitand = quote!(Self { #bitand });
1275            bitxor = quote!(Self { #bitxor });
1276            not = quote!(Self { #not });
1277        }
1278    };
1279
1280    let name = format_ident!("{}", flags.name);
1281
1282    let mut constants = TokenStream::new();
1283    let mut rust_names = TokenStream::new();
1284    let mut component_names = TokenStream::new();
1285
1286    for (index, Flag { name, rename }) in flags.flags.iter().enumerate() {
1287        rust_names.extend(quote!(#name,));
1288
1289        let component_name = rename.as_ref().unwrap_or(name);
1290        component_names.extend(quote!(#component_name,));
1291
1292        let fields = match size {
1293            FlagsSize::Size0 => quote!(),
1294            FlagsSize::Size1 => {
1295                let init = 1_u8 << index;
1296                quote!(__inner0: #init)
1297            }
1298            FlagsSize::Size2 => {
1299                let init = 1_u16 << index;
1300                quote!(__inner0: #init)
1301            }
1302            FlagsSize::Size4Plus(n) => (0..n)
1303                .map(|i| {
1304                    let field = format_ident!("__inner{}", i);
1305
1306                    let init = if index / 32 == usize::from(i) {
1307                        1_u32 << (index % 32)
1308                    } else {
1309                        0
1310                    };
1311
1312                    quote!(#field: #init,)
1313                })
1314                .collect::<TokenStream>(),
1315        };
1316
1317        let name = format_ident!("{}", name);
1318
1319        constants.extend(quote!(pub const #name: Self = Self { #fields };));
1320    }
1321
1322    let generics = syn::Generics {
1323        lt_token: None,
1324        params: Punctuated::new(),
1325        gt_token: None,
1326        where_clause: None,
1327    };
1328
1329    let fields = {
1330        let ty = syn::parse2::<syn::Type>(ty.clone())?;
1331
1332        (0..count)
1333            .map(|index| syn::Field {
1334                attrs: Vec::new(),
1335                vis: syn::Visibility::Inherited,
1336                ident: Some(format_ident!("__inner{}", index)),
1337                colon_token: None,
1338                ty: ty.clone(),
1339                mutability: syn::FieldMutability::None,
1340            })
1341            .collect::<Vec<_>>()
1342    };
1343
1344    let fields = fields.iter().collect::<Vec<_>>();
1345
1346    let component_type_impl = expand_record_for_component_type(
1347        &name,
1348        &generics,
1349        &fields,
1350        quote!(typecheck_flags),
1351        component_names,
1352        &wt,
1353    )?;
1354
1355    let internal = quote!(#wt::component::__internal);
1356
1357    let field_names = fields
1358        .iter()
1359        .map(|syn::Field { ident, .. }| ident)
1360        .collect::<Vec<_>>();
1361
1362    let fields = fields
1363        .iter()
1364        .map(|syn::Field { ident, .. }| quote!(#[doc(hidden)] #ident: #ty,))
1365        .collect::<TokenStream>();
1366
1367    let (field_interface_type, field_size) = match size {
1368        FlagsSize::Size0 => (quote!(NOT USED), 0usize),
1369        FlagsSize::Size1 => (quote!(#internal::InterfaceType::U8), 1),
1370        FlagsSize::Size2 => (quote!(#internal::InterfaceType::U16), 2),
1371        FlagsSize::Size4Plus(_) => (quote!(#internal::InterfaceType::U32), 4),
1372    };
1373
1374    let expanded = quote! {
1375        #[derive(Copy, Clone, Default)]
1376        pub struct #name { #fields }
1377
1378        impl #name {
1379            #constants
1380
1381            pub fn as_array(&self) -> [u32; #count] {
1382                #as_array
1383            }
1384
1385            pub fn empty() -> Self {
1386                Self::default()
1387            }
1388
1389            pub fn all() -> Self {
1390                use core::ops::Not;
1391                Self::default().not()
1392            }
1393
1394            pub fn contains(&self, other: Self) -> bool {
1395                *self & other == other
1396            }
1397
1398            pub fn intersects(&self, other: Self) -> bool {
1399                *self & other != Self::empty()
1400            }
1401        }
1402
1403        impl core::cmp::PartialEq for #name {
1404            fn eq(&self, rhs: &#name) -> bool {
1405                #eq
1406            }
1407        }
1408
1409        impl core::cmp::Eq for #name { }
1410
1411        impl core::fmt::Debug for #name {
1412            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1413                #internal::format_flags(&self.as_array(), &[#rust_names], f)
1414            }
1415        }
1416
1417        impl core::ops::BitOr for #name {
1418            type Output = #name;
1419
1420            fn bitor(self, rhs: #name) -> #name {
1421                #bitor
1422            }
1423        }
1424
1425        impl core::ops::BitOrAssign for #name {
1426            fn bitor_assign(&mut self, rhs: #name) {
1427                #bitor_assign
1428            }
1429        }
1430
1431        impl core::ops::BitAnd for #name {
1432            type Output = #name;
1433
1434            fn bitand(self, rhs: #name) -> #name {
1435                #bitand
1436            }
1437        }
1438
1439        impl core::ops::BitAndAssign for #name {
1440            fn bitand_assign(&mut self, rhs: #name) {
1441                #bitand_assign
1442            }
1443        }
1444
1445        impl core::ops::BitXor for #name {
1446            type Output = #name;
1447
1448            fn bitxor(self, rhs: #name) -> #name {
1449                #bitxor
1450            }
1451        }
1452
1453        impl core::ops::BitXorAssign for #name {
1454            fn bitxor_assign(&mut self, rhs: #name) {
1455                #bitxor_assign
1456            }
1457        }
1458
1459        impl core::ops::Not for #name {
1460            type Output = #name;
1461
1462            fn not(self) -> #name {
1463                #not
1464            }
1465        }
1466
1467        #component_type_impl
1468
1469        unsafe impl #wt::component::Lower for #name {
1470            fn linear_lower_to_flat<T>(
1471                &self,
1472                cx: &mut #internal::LowerContext<'_, T>,
1473                _ty: #internal::InterfaceType,
1474                dst: &mut core::mem::MaybeUninit<Self::Lower>,
1475            ) -> #internal::anyhow::Result<()> {
1476                #(
1477                    self.#field_names.linear_lower_to_flat(
1478                        cx,
1479                        #field_interface_type,
1480                        #internal::map_maybe_uninit!(dst.#field_names),
1481                    )?;
1482                )*
1483                Ok(())
1484            }
1485
1486            fn linear_lower_to_memory<T>(
1487                &self,
1488                cx: &mut #internal::LowerContext<'_, T>,
1489                _ty: #internal::InterfaceType,
1490                mut offset: usize
1491            ) -> #internal::anyhow::Result<()> {
1492                debug_assert!(offset % (<Self as #wt::component::ComponentType>::ALIGN32 as usize) == 0);
1493                #(
1494                    self.#field_names.linear_lower_to_memory(
1495                        cx,
1496                        #field_interface_type,
1497                        offset,
1498                    )?;
1499                    offset += core::mem::size_of_val(&self.#field_names);
1500                )*
1501                Ok(())
1502            }
1503        }
1504
1505        unsafe impl #wt::component::Lift for #name {
1506            fn linear_lift_from_flat(
1507                cx: &mut #internal::LiftContext<'_>,
1508                _ty: #internal::InterfaceType,
1509                src: &Self::Lower,
1510            ) -> #internal::anyhow::Result<Self> {
1511                Ok(Self {
1512                    #(
1513                        #field_names: #wt::component::Lift::linear_lift_from_flat(
1514                            cx,
1515                            #field_interface_type,
1516                            &src.#field_names,
1517                        )?,
1518                    )*
1519                })
1520            }
1521
1522            fn linear_lift_from_memory(
1523                cx: &mut #internal::LiftContext<'_>,
1524                _ty: #internal::InterfaceType,
1525                bytes: &[u8],
1526            ) -> #internal::anyhow::Result<Self> {
1527                debug_assert!(
1528                    (bytes.as_ptr() as usize)
1529                        % (<Self as #wt::component::ComponentType>::ALIGN32 as usize)
1530                        == 0
1531                );
1532                #(
1533                    let (field, bytes) = bytes.split_at(#field_size);
1534                    let #field_names = #wt::component::Lift::linear_lift_from_memory(
1535                        cx,
1536                        #field_interface_type,
1537                        field,
1538                    )?;
1539                )*
1540                Ok(Self { #(#field_names,)* })
1541            }
1542        }
1543    };
1544
1545    Ok(expanded)
1546}