Skip to main content

wit_bindgen_rust/
lib.rs

1use crate::interface::InterfaceGenerator;
2use anyhow::{Result, bail};
3use core::panic;
4use heck::*;
5use indexmap::{IndexMap, IndexSet};
6use std::collections::{BTreeMap, HashMap, HashSet};
7use std::fmt::{self, Write as _};
8use std::mem;
9use std::path::{Path, PathBuf};
10use std::str::FromStr;
11use wit_bindgen_core::abi::{Bitcast, WasmType};
12use wit_bindgen_core::{
13    AsyncFilterSet, Files, InterfaceGenerator as _, Source, Types, WorldGenerator, dealias,
14    name_package_module, uwrite, uwriteln, wit_parser::*,
15};
16
17mod bindgen;
18mod interface;
19
20struct InterfaceName {
21    /// True when this interface name has been remapped through the use of `with` in the `bindgen!`
22    /// macro invocation.
23    remapped: bool,
24
25    /// The string name for this interface.
26    path: String,
27}
28
29#[derive(Default)]
30pub struct RustWasm {
31    types: Types,
32    src_preamble: Source,
33    src: Source,
34    opts: Opts,
35    import_modules: Vec<(String, Vec<String>)>,
36    export_modules: Vec<(String, Vec<String>)>,
37    skip: HashSet<String>,
38    interface_names: HashMap<InterfaceId, InterfaceName>,
39    exported_resources: HashSet<TypeId>,
40    import_funcs_called: bool,
41    with_name_counter: usize,
42    // Track which interfaces and types are generated. Remapped interfaces and types provided via `with`
43    // are required to be used.
44    generated_types: HashSet<String>,
45    world: Option<WorldId>,
46
47    rt_module: IndexSet<RuntimeItem>,
48    export_macros: Vec<(String, String)>,
49
50    /// Maps wit interface and type names to their Rust identifiers
51    with: GenerationConfiguration,
52
53    future_payloads: IndexMap<Option<Type>, String>,
54    stream_payloads: IndexMap<Option<Type>, String>,
55}
56
57#[derive(Default)]
58struct GenerationConfiguration {
59    map: HashMap<String, TypeGeneration>,
60    generate_by_default: bool,
61}
62
63impl GenerationConfiguration {
64    fn get(&self, key: &str) -> Option<&TypeGeneration> {
65        self.map.get(key).or_else(|| {
66            self.generate_by_default
67                .then_some(&TypeGeneration::Generate)
68        })
69    }
70
71    fn insert(&mut self, name: String, generate: TypeGeneration) {
72        self.map.insert(name, generate);
73    }
74
75    fn iter(&self) -> impl Iterator<Item = (&String, &TypeGeneration)> {
76        self.map.iter()
77    }
78}
79
80/// How a wit interface or type should be rendered in Rust
81enum TypeGeneration {
82    /// Uses a Rust identifier defined elsewhere
83    Remap(String),
84    /// Define the interface or type with this bindgen invocation
85    Generate,
86}
87
88impl TypeGeneration {
89    /// Returns true if the interface or type should be defined with this bindgen invocation
90    fn generated(&self) -> bool {
91        match self {
92            TypeGeneration::Generate => true,
93            TypeGeneration::Remap(_) => false,
94        }
95    }
96}
97
98#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
99enum RuntimeItem {
100    AllocCrate,
101    StringType,
102    StdAllocModule,
103    VecType,
104    StringLift,
105    InvalidEnumDiscriminant,
106    CharLift,
107    BoolLift,
108    CabiDealloc,
109    RunCtorsOnce,
110    AsI32,
111    AsI64,
112    AsF32,
113    AsF64,
114    ResourceType,
115    BoxType,
116}
117
118#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
119#[cfg_attr(
120    feature = "serde",
121    derive(serde::Deserialize),
122    serde(rename_all = "kebab-case")
123)]
124pub enum ExportKey {
125    World,
126    Name(String),
127}
128
129#[cfg(feature = "clap")]
130fn parse_with(s: &str) -> Result<(String, WithOption), String> {
131    let (k, v) = s.split_once('=').ok_or_else(|| {
132        format!("expected string of form `<key>=<value>[,<key>=<value>...]`; got `{s}`")
133    })?;
134    let v = match v {
135        "generate" => WithOption::Generate,
136        other => WithOption::Path(other.to_string()),
137    };
138    Ok((k.to_string(), v))
139}
140
141#[derive(Default, Debug, Clone)]
142#[cfg_attr(feature = "clap", derive(clap::Parser))]
143#[cfg_attr(
144    feature = "serde",
145    derive(serde::Deserialize),
146    serde(default, rename_all = "kebab-case")
147)]
148pub struct Opts {
149    /// Whether or not a formatter is executed to format generated code.
150    #[cfg_attr(feature = "clap", arg(long))]
151    pub format: bool,
152
153    /// If true, code generation should qualify any features that depend on
154    /// `std` with `cfg(feature = "std")`.
155    #[cfg_attr(feature = "clap", arg(long))]
156    pub std_feature: bool,
157
158    /// If true, code generation should pass borrowed string arguments as
159    /// `&[u8]` instead of `&str`. Strings are still required to be valid
160    /// UTF-8, but this avoids the need for Rust code to do its own UTF-8
161    /// validation if it doesn't already have a `&str`.
162    #[cfg_attr(feature = "clap", arg(long))]
163    pub raw_strings: bool,
164
165    /// Names of functions to skip generating bindings for.
166    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
167    pub skip: Vec<String>,
168
169    /// If true, generate stub implementations for any exported functions,
170    /// interfaces, and/or resources.
171    #[cfg_attr(feature = "clap", arg(long))]
172    pub stubs: bool,
173
174    /// Optionally prefix any export names with the specified value.
175    ///
176    /// This is useful to avoid name conflicts when testing.
177    #[cfg_attr(feature = "clap", arg(long, value_name = "STRING"))]
178    pub export_prefix: Option<String>,
179
180    /// Whether to generate owning or borrowing type definitions.
181    ///
182    /// Valid values include:
183    ///
184    /// - `owning`: Generated types will be composed entirely of owning fields,
185    /// regardless of whether they are used as parameters to imports or not.
186    ///
187    /// - `borrowing`: Generated types used as parameters to imports will be
188    /// "deeply borrowing", i.e. contain references rather than owned values
189    /// when applicable.
190    ///
191    /// - `borrowing-duplicate-if-necessary`: As above, but generating distinct
192    /// types for borrowing and owning, if necessary.
193    #[cfg_attr(feature = "clap", arg(long, default_value_t = Ownership::Owning))]
194    pub ownership: Ownership,
195
196    /// The optional path to the wit-bindgen runtime module to use.
197    ///
198    /// This defaults to `wit_bindgen::rt`.
199    #[cfg_attr(feature = "clap", arg(long, value_name = "PATH"))]
200    pub runtime_path: Option<String>,
201
202    /// The optional path to the bitflags crate to use.
203    ///
204    /// This defaults to `wit_bindgen::bitflags`.
205    #[cfg_attr(feature = "clap", arg(long))]
206    pub bitflags_path: Option<String>,
207
208    /// Additional derive attributes to add to generated types. If using in a CLI, this flag can be
209    /// specified multiple times to add multiple attributes.
210    ///
211    /// These derive attributes will be added to any generated structs or enums
212    #[cfg_attr(feature = "clap", arg(long, short = 'd', value_name = "DERIVE"))]
213    pub additional_derive_attributes: Vec<String>,
214
215    /// Variants and records to ignore when applying additional derive attributes.
216    ///
217    /// These names are specified as they are listed in the wit file, i.e. in kebab case.
218    /// This feature allows some variants and records to use types for which adding traits will cause
219    /// compilation to fail, such as serde::Deserialize on wasi:io/streams.
220    ///
221    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
222    pub additional_derive_ignore: Vec<String>,
223
224    /// Remapping of wit import interface and type names to Rust module names
225    /// and types.
226    ///
227    /// Argument must be of the form `k=v` and this option can be passed
228    /// multiple times or one option can be comma separated, for example
229    /// `k1=v1,k2=v2`.
230    #[cfg_attr(feature = "clap", arg(long, value_parser = parse_with, value_delimiter = ','))]
231    pub with: Vec<(String, WithOption)>,
232
233    /// Indicates that all interfaces not specified in `with` should be
234    /// generated.
235    #[cfg_attr(feature = "clap", arg(long))]
236    pub generate_all: bool,
237
238    /// Add the specified suffix to the name of the custome section containing
239    /// the component type.
240    #[cfg_attr(feature = "clap", arg(long, value_name = "STRING"))]
241    pub type_section_suffix: Option<String>,
242
243    /// Disable a workaround used to prevent libc ctors/dtors from being invoked
244    /// too much.
245    #[cfg_attr(feature = "clap", arg(long))]
246    pub disable_run_ctors_once_workaround: bool,
247
248    /// Changes the default module used in the generated `export!` macro to
249    /// something other than `self`.
250    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
251    pub default_bindings_module: Option<String>,
252
253    /// Alternative name to use for the `export!` macro if one is generated.
254    #[cfg_attr(feature = "clap", arg(long, value_name = "NAME"))]
255    pub export_macro_name: Option<String>,
256
257    /// Ensures that the `export!` macro will be defined as `pub` so it is a
258    /// candidate for being exported outside of the crate.
259    #[cfg_attr(feature = "clap", arg(long))]
260    pub pub_export_macro: bool,
261
262    /// Whether to generate unused structures, not generated by default (false)
263    #[cfg_attr(feature = "clap", arg(long))]
264    pub generate_unused_types: bool,
265
266    /// Whether or not to generate helper function/constants to help link custom
267    /// sections into the final output.
268    ///
269    /// Disabling this can shave a few bytes off a binary but makes
270    /// library-based usage of `generate!` prone to breakage.
271    #[cfg_attr(feature = "clap", arg(long))]
272    pub disable_custom_section_link_helpers: bool,
273
274    #[cfg_attr(feature = "clap", clap(flatten))]
275    #[cfg_attr(feature = "serde", serde(flatten))]
276    pub async_: AsyncFilterSet,
277
278    /// Find all structurally equal types and only generate one type definition
279    /// for each equivalence class.
280    ///
281    /// Other types in the same class will be type aliases to the generated
282    /// type. This avoids clone when converting between types that are
283    /// structurally equal, which is useful when import and export the same
284    /// interface.
285    #[cfg_attr(
286        feature = "clap",
287        arg(long, require_equals = true, value_name = "true|false")
288    )]
289    pub merge_structurally_equal_types: Option<Option<bool>>,
290}
291
292impl Opts {
293    pub fn build(self) -> RustWasm {
294        let mut r = RustWasm::new();
295        r.skip = self.skip.iter().cloned().collect();
296        r.opts = self;
297        r
298    }
299
300    fn merge_structurally_equal_types(&self) -> bool {
301        const DEFAULT: bool = false;
302        match self.merge_structurally_equal_types {
303            // no option passed, use the default
304            None => DEFAULT,
305            // --merge-structurally-equal-types
306            Some(None) => true,
307            // --merge-structurally-equal-types=val
308            Some(Some(val)) => val,
309        }
310    }
311}
312
313impl RustWasm {
314    /// Generates Rust bindings from the `wit/` directory and writes
315    /// the result into Cargo’s `OUT_DIR`. Intended for use in `build.rs`.
316    ///
317    /// The `world` parameter specifies the world name to select.
318    /// It must be provided unless the main package contains exactly one world.
319    ///
320    /// Returns the full path to the generated bindings file.
321    pub fn generate_to_out_dir(mut self, world: Option<&str>) -> Result<PathBuf> {
322        let mut resolve = Resolve::default();
323        println!("cargo:rerun-if-changed=wit/");
324        let (pkg, _files) = resolve.push_path("wit")?;
325        let main_packages = vec![pkg];
326        let world = resolve.select_world(&main_packages, world)?;
327
328        let mut files = Files::default();
329        self.generate(&mut resolve, world, &mut files)?;
330        let out_dir = std::env::var("OUT_DIR").expect("cargo sets OUT_DIR");
331        let (name, contents) = files
332            .iter()
333            .next()
334            .expect("exactly one file should be generated");
335        let dst = Path::new(&out_dir).join(name);
336        std::fs::write(&dst, contents)?;
337        Ok(dst)
338    }
339
340    fn new() -> RustWasm {
341        RustWasm::default()
342    }
343
344    fn interface<'a>(
345        &'a mut self,
346        identifier: Identifier<'a>,
347        wasm_import_module: &'a str,
348        resolve: &'a Resolve,
349        in_import: bool,
350    ) -> InterfaceGenerator<'a> {
351        let mut sizes = SizeAlign::default();
352        sizes.fill(resolve);
353
354        InterfaceGenerator {
355            identifier,
356            wasm_import_module,
357            src: Source::default(),
358            in_import,
359            r#gen: self,
360            sizes,
361            resolve,
362            return_pointer_area_size: Default::default(),
363            return_pointer_area_align: Default::default(),
364            needs_runtime_module: false,
365        }
366    }
367
368    fn emit_modules(&mut self, modules: Vec<(String, Vec<String>)>) {
369        #[derive(Default)]
370        struct Module {
371            submodules: BTreeMap<String, Module>,
372            contents: Vec<String>,
373        }
374        let mut map = Module::default();
375        for (module, path) in modules {
376            let mut cur = &mut map;
377            for name in path[..path.len() - 1].iter() {
378                cur = cur
379                    .submodules
380                    .entry(name.clone())
381                    .or_insert(Module::default());
382            }
383            cur.contents.push(module);
384        }
385
386        emit(&mut self.src, map, &self.opts, true);
387        fn emit(me: &mut Source, module: Module, opts: &Opts, toplevel: bool) {
388            for (name, submodule) in module.submodules {
389                if toplevel {
390                    // Disable rustfmt. By default we already format the code
391                    // using prettyplease, so we don't want `cargo fmt` to create
392                    // extra diffs for users to deal with.
393                    if opts.format {
394                        uwriteln!(me, "#[rustfmt::skip]");
395                    }
396
397                    // Ignore dead-code and clippy warnings. If the bindings are
398                    // only used within a crate, and not exported to a different
399                    // crate, some parts may be unused, and that's ok.
400                    uwriteln!(me, "#[allow(dead_code, clippy::all)]");
401                }
402
403                uwriteln!(me, "pub mod {name} {{");
404                emit(me, submodule, opts, false);
405                uwriteln!(me, "}}");
406            }
407            for submodule in module.contents {
408                uwriteln!(me, "{submodule}");
409            }
410        }
411    }
412
413    fn runtime_path(&self) -> &str {
414        self.opts
415            .runtime_path
416            .as_deref()
417            .unwrap_or("wit_bindgen::rt")
418    }
419
420    fn bitflags_path(&self) -> String {
421        self.opts
422            .bitflags_path
423            .to_owned()
424            .unwrap_or(format!("{}::bitflags", self.runtime_path()))
425    }
426
427    fn async_support_path(&self) -> String {
428        format!("{}::async_support", self.runtime_path())
429    }
430
431    fn name_interface(
432        &mut self,
433        resolve: &Resolve,
434        id: InterfaceId,
435        name: &WorldKey,
436        is_export: bool,
437    ) -> Result<bool> {
438        let with_name = resolve.name_world_key(name);
439        let remapping = if is_export {
440            &TypeGeneration::Generate
441        } else {
442            match self.with.get(&with_name) {
443                Some(remapping) => remapping,
444                None => bail!(MissingWith(with_name)),
445            }
446        };
447        self.generated_types.insert(with_name);
448        let entry = match remapping {
449            TypeGeneration::Remap(remapped_path) => {
450                let name = format!("__with_name{}", self.with_name_counter);
451                self.with_name_counter += 1;
452                uwriteln!(
453                    self.src,
454                    "#[allow(unfulfilled_lint_expectations, unused_imports)]"
455                );
456                uwriteln!(self.src, "use {remapped_path} as {name};");
457                InterfaceName {
458                    remapped: true,
459                    path: name,
460                }
461            }
462            TypeGeneration::Generate => {
463                let path = compute_module_path(name, resolve, is_export).join("::");
464
465                InterfaceName {
466                    remapped: false,
467                    path,
468                }
469            }
470        };
471
472        let remapped = entry.remapped;
473        let prev = self.interface_names.insert(id, entry);
474        assert!(prev.is_none());
475
476        Ok(remapped)
477    }
478
479    fn finish_runtime_module(&mut self) {
480        if !self.rt_module.is_empty() {
481            // As above, disable rustfmt, as we use prettyplease.
482            if self.opts.format {
483                uwriteln!(self.src, "#[rustfmt::skip]");
484            }
485
486            self.src.push_str("mod _rt {\n");
487            self.src
488                .push_str("#![allow(dead_code, unused_imports, clippy::all)]\n");
489            let mut emitted = IndexSet::new();
490            while !self.rt_module.is_empty() {
491                for item in mem::take(&mut self.rt_module) {
492                    if emitted.insert(item) {
493                        self.emit_runtime_item(item);
494                    }
495                }
496            }
497            self.src.push_str("}\n");
498        }
499
500        if !self.future_payloads.is_empty() {
501            let async_support = self.async_support_path();
502            self.src.push_str(&format!(
503                "\
504pub mod wit_future {{
505    #![allow(dead_code, unused_variables, clippy::all)]
506
507    #[doc(hidden)]
508    pub trait FuturePayload: Unpin + Sized + 'static {{
509        const VTABLE: &'static {async_support}::FutureVtable<Self>;
510    }}"
511            ));
512            for code in self.future_payloads.values() {
513                self.src.push_str(code);
514            }
515            self.src.push_str(&format!(
516                "\
517    /// Creates a new Component Model `future` with the specified payload type.
518    ///
519    /// The `default` function provided computes the default value to be sent in
520    /// this future if no other value was otherwise sent.
521    pub fn new<T: FuturePayload>(default: fn() -> T) -> ({async_support}::FutureWriter<T>, {async_support}::FutureReader<T>) {{
522        unsafe {{ {async_support}::future_new::<T>(default, T::VTABLE) }}
523    }}
524}}
525                ",
526            ));
527        }
528
529        if !self.stream_payloads.is_empty() {
530            let async_support = self.async_support_path();
531            self.src.push_str(&format!(
532                "\
533pub mod wit_stream {{
534    #![allow(dead_code, unused_variables, clippy::all)]
535
536    pub trait StreamPayload: Unpin + Sized + 'static {{
537        const VTABLE: &'static {async_support}::StreamVtable<Self>;
538    }}"
539            ));
540            for code in self.stream_payloads.values() {
541                self.src.push_str(code);
542            }
543            self.src.push_str(
544                &format!("\
545    /// Creates a new Component Model `stream` with the specified payload type.
546    pub fn new<T: StreamPayload>() -> ({async_support}::StreamWriter<T>, {async_support}::StreamReader<T>) {{
547        unsafe {{ {async_support}::stream_new::<T>(T::VTABLE) }}
548    }}
549}}
550                "),
551            );
552        }
553    }
554
555    fn emit_runtime_item(&mut self, item: RuntimeItem) {
556        match item {
557            RuntimeItem::AllocCrate => {
558                uwriteln!(self.src, "extern crate alloc as alloc_crate;");
559            }
560            RuntimeItem::StdAllocModule => {
561                self.rt_module.insert(RuntimeItem::AllocCrate);
562                uwriteln!(self.src, "pub use alloc_crate::alloc;");
563            }
564            RuntimeItem::StringType => {
565                self.rt_module.insert(RuntimeItem::AllocCrate);
566                uwriteln!(self.src, "pub use alloc_crate::string::String;");
567            }
568            RuntimeItem::BoxType => {
569                self.rt_module.insert(RuntimeItem::AllocCrate);
570                uwriteln!(self.src, "pub use alloc_crate::boxed::Box;");
571            }
572            RuntimeItem::VecType => {
573                self.rt_module.insert(RuntimeItem::AllocCrate);
574                uwriteln!(self.src, "pub use alloc_crate::vec::Vec;");
575            }
576            RuntimeItem::CabiDealloc => {
577                self.rt_module.insert(RuntimeItem::StdAllocModule);
578                self.src.push_str(
579                    "\
580pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) {
581    if size == 0 {
582        return;
583    }
584    unsafe {
585        let layout = alloc::Layout::from_size_align_unchecked(size, align);
586        alloc::dealloc(ptr, layout);
587    }
588}
589                    ",
590                );
591            }
592
593            RuntimeItem::StringLift => {
594                self.rt_module.insert(RuntimeItem::StringType);
595                self.src.push_str(
596                    "\
597pub unsafe fn string_lift(bytes: Vec<u8>) -> String {
598    if cfg!(debug_assertions) {
599        String::from_utf8(bytes).unwrap()
600    } else {
601        unsafe { String::from_utf8_unchecked(bytes) }
602    }
603}
604                    ",
605                );
606            }
607
608            RuntimeItem::InvalidEnumDiscriminant => {
609                self.src.push_str(
610                    "\
611pub unsafe fn invalid_enum_discriminant<T>() -> T {
612    if cfg!(debug_assertions) {
613        panic!(\"invalid enum discriminant\")
614    } else {
615        unsafe { core::hint::unreachable_unchecked() }
616    }
617}
618                    ",
619                );
620            }
621
622            RuntimeItem::CharLift => {
623                self.src.push_str(
624                    "\
625pub unsafe fn char_lift(val: u32) -> char {
626    if cfg!(debug_assertions) {
627        core::char::from_u32(val).unwrap()
628    } else {
629        unsafe { core::char::from_u32_unchecked(val) }
630    }
631}
632                    ",
633                );
634            }
635
636            RuntimeItem::BoolLift => {
637                self.src.push_str(
638                    "\
639pub unsafe fn bool_lift(val: u8) -> bool {
640    if cfg!(debug_assertions) {
641        match val {
642            0 => false,
643            1 => true,
644            _ => panic!(\"invalid bool discriminant\"),
645        }
646    } else {
647        val != 0
648    }
649}
650                    ",
651                );
652            }
653
654            RuntimeItem::RunCtorsOnce => {
655                let rt = self.runtime_path();
656                self.src.push_str(&format!(
657                    r#"
658#[cfg(target_arch = "wasm32")]
659pub fn run_ctors_once() {{
660    {rt}::run_ctors_once();
661}}
662                    "#,
663                ));
664            }
665
666            RuntimeItem::AsI32 => {
667                self.emit_runtime_as_trait(
668                    "i32",
669                    &["i32", "u32", "i16", "u16", "i8", "u8", "char", "usize"],
670                );
671            }
672
673            RuntimeItem::AsI64 => {
674                self.emit_runtime_as_trait("i64", &["i64", "u64"]);
675            }
676
677            RuntimeItem::AsF32 => {
678                self.emit_runtime_as_trait("f32", &["f32"]);
679            }
680
681            RuntimeItem::AsF64 => {
682                self.emit_runtime_as_trait("f64", &["f64"]);
683            }
684
685            RuntimeItem::ResourceType => {
686                self.src.push_str(
687                    r#"
688
689use core::fmt;
690use core::marker;
691use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
692
693/// A type which represents a component model resource, either imported or
694/// exported into this component.
695///
696/// This is a low-level wrapper which handles the lifetime of the resource
697/// (namely this has a destructor). The `T` provided defines the component model
698/// intrinsics that this wrapper uses.
699///
700/// One of the chief purposes of this type is to provide `Deref` implementations
701/// to access the underlying data when it is owned.
702///
703/// This type is primarily used in generated code for exported and imported
704/// resources.
705#[repr(transparent)]
706pub struct Resource<T: WasmResource> {
707    // NB: This would ideally be `u32` but it is not. The fact that this has
708    // interior mutability is not exposed in the API of this type except for the
709    // `take_handle` method which is supposed to in theory be private.
710    //
711    // This represents, almost all the time, a valid handle value. When it's
712    // invalid it's stored as `u32::MAX`.
713    handle: AtomicU32,
714    _marker: marker::PhantomData<T>,
715}
716
717/// A trait which all wasm resources implement, namely providing the ability to
718/// drop a resource.
719///
720/// This generally is implemented by generated code, not user-facing code.
721#[allow(clippy::missing_safety_doc)]
722pub unsafe trait WasmResource {
723    /// Invokes the `[resource-drop]...` intrinsic.
724    unsafe fn drop(handle: u32);
725}
726
727impl<T: WasmResource> Resource<T> {
728    #[doc(hidden)]
729    pub unsafe fn from_handle(handle: u32) -> Self {
730        debug_assert!(handle != 0 && handle != u32::MAX);
731        Self {
732            handle: AtomicU32::new(handle),
733            _marker: marker::PhantomData,
734        }
735    }
736
737    /// Takes ownership of the handle owned by `resource`.
738    ///
739    /// Note that this ideally would be `into_handle` taking `Resource<T>` by
740    /// ownership. The code generator does not enable that in all situations,
741    /// unfortunately, so this is provided instead.
742    ///
743    /// Also note that `take_handle` is in theory only ever called on values
744    /// owned by a generated function. For example a generated function might
745    /// take `Resource<T>` as an argument but then call `take_handle` on a
746    /// reference to that argument. In that sense the dynamic nature of
747    /// `take_handle` should only be exposed internally to generated code, not
748    /// to user code.
749    #[doc(hidden)]
750    pub fn take_handle(resource: &Resource<T>) -> u32 {
751        resource.handle.swap(u32::MAX, Relaxed)
752    }
753
754    #[doc(hidden)]
755    pub fn handle(resource: &Resource<T>) -> u32 {
756        resource.handle.load(Relaxed)
757    }
758}
759
760impl<T: WasmResource> fmt::Debug for Resource<T> {
761    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
762        f.debug_struct("Resource")
763            .field("handle", &self.handle)
764            .finish()
765    }
766}
767
768impl<T: WasmResource> Drop for Resource<T> {
769    fn drop(&mut self) {
770        unsafe {
771            match self.handle.load(Relaxed) {
772                // If this handle was "taken" then don't do anything in the
773                // destructor.
774                u32::MAX => {}
775
776                // ... but otherwise do actually destroy it with the imported
777                // component model intrinsic as defined through `T`.
778                other => T::drop(other),
779            }
780        }
781    }
782}
783                    "#,
784                );
785            }
786        }
787    }
788
789    // This is a workaround for in the bindings sometimes we've got `&i32` and
790    // sometimes we've got `i32` but that should all be able to be worked with
791    // as `i32`, so these helper functions are used to boil away the
792    // indirection.
793    fn emit_runtime_as_trait(&mut self, ty: &str, to_convert: &[&str]) {
794        let upcase = ty.to_uppercase();
795        self.src.push_str(&format!(
796            r#"
797pub fn as_{ty}<T: As{upcase}>(t: T) -> {ty} {{
798    t.as_{ty}()
799}}
800
801pub trait As{upcase} {{
802    fn as_{ty}(self) -> {ty};
803}}
804
805impl<'a, T: Copy + As{upcase}> As{upcase} for &'a T {{
806    fn as_{ty}(self) -> {ty} {{
807        (*self).as_{ty}()
808    }}
809}}
810            "#
811        ));
812
813        for to_convert in to_convert {
814            self.src.push_str(&format!(
815                r#"
816impl As{upcase} for {to_convert} {{
817    #[inline]
818    fn as_{ty}(self) -> {ty} {{
819        self as {ty}
820    }}
821}}
822                "#
823            ));
824        }
825    }
826
827    /// Generates an `export!` macro for the `world_id` specified.
828    ///
829    /// This will generate a macro which will then itself invoke all the
830    /// other macros collected in `self.export_macros` prior. All these macros
831    /// are woven together in this single invocation.
832    fn finish_export_macro(&mut self, resolve: &Resolve, world_id: WorldId) {
833        if self.export_macros.is_empty() {
834            return;
835        }
836        let world = &resolve.worlds[world_id];
837        let world_name = world.name.to_snake_case();
838
839        let default_bindings_module = self
840            .opts
841            .default_bindings_module
842            .clone()
843            .unwrap_or("self".to_string());
844        let (macro_export, use_vis) = if self.opts.pub_export_macro {
845            ("#[macro_export]", "pub")
846        } else {
847            ("", "pub(crate)")
848        };
849        let export_macro_name = self
850            .opts
851            .export_macro_name
852            .as_deref()
853            .unwrap_or("export")
854            .to_string();
855        uwriteln!(
856            self.src,
857            r#"
858/// Generates `#[unsafe(no_mangle)]` functions to export the specified type as
859/// the root implementation of all generated traits.
860///
861/// For more information see the documentation of `wit_bindgen::generate!`.
862///
863/// ```rust
864/// # macro_rules! {export_macro_name} {{ ($($t:tt)*) => (); }}
865/// # trait Guest {{}}
866/// struct MyType;
867///
868/// impl Guest for MyType {{
869///     // ...
870/// }}
871///
872/// {export_macro_name}!(MyType);
873/// ```
874#[allow(unused_macros)]
875#[doc(hidden)]
876{macro_export}
877macro_rules! __export_{world_name}_impl {{
878    ($ty:ident) => ({default_bindings_module}::{export_macro_name}!($ty with_types_in {default_bindings_module}););
879    ($ty:ident with_types_in $($path_to_types_root:tt)*) => ("#
880        );
881        for (name, path_to_types) in self.export_macros.iter() {
882            let mut path = "$($path_to_types_root)*".to_string();
883            if !path_to_types.is_empty() {
884                path.push_str("::");
885                path.push_str(path_to_types)
886            }
887            uwriteln!(self.src, "{path}::{name}!($ty with_types_in {path});");
888        }
889
890        // See comments in `finish` for why this conditionally happens here.
891        if self.opts.pub_export_macro {
892            uwriteln!(self.src, "const _: () = {{");
893            self.emit_custom_section(resolve, world_id, "imports and exports", None);
894            uwriteln!(self.src, "}};");
895        }
896
897        uwriteln!(self.src, ")\n}}");
898
899        uwriteln!(
900            self.src,
901            "#[doc(inline)]\n\
902            {use_vis} use __export_{world_name}_impl as {export_macro_name};"
903        );
904
905        if self.opts.stubs {
906            uwriteln!(self.src, "export!(Stub);");
907        }
908    }
909
910    /// Generates a `#[link_section]` custom section to get smuggled through
911    /// `wasm-ld`.
912    ///
913    /// This custom section is an encoding of the component metadata and will be
914    /// used as part of the `wit-component`-based componentization process.
915    ///
916    /// The `section_suffix` here is used to distinguish the multiple sections
917    /// that this generator emits, and `func_name` is an optional function to
918    /// generate next to this which is used to force rustc to at least visit
919    /// this `static` and codegen it.
920    fn emit_custom_section(
921        &mut self,
922        resolve: &Resolve,
923        world_id: WorldId,
924        section_suffix: &str,
925        func_name: Option<&str>,
926    ) {
927        // As above, disable rustfmt, as we use prettyplease.
928        if self.opts.format {
929            uwriteln!(self.src, "#[rustfmt::skip]");
930        }
931        self.src.push_str("\n#[cfg(target_arch = \"wasm32\")]\n");
932
933        // The custom section name here must start with "component-type" but
934        // otherwise is attempted to be unique here to ensure that this doesn't get
935        // concatenated to other custom sections by LLD by accident since LLD will
936        // concatenate custom sections of the same name.
937        let opts_suffix = self.opts.type_section_suffix.as_deref().unwrap_or("");
938        let world = &resolve.worlds[world_id];
939        let world_name = &world.name;
940        let pkg = &resolve.packages[world.package.unwrap()].name;
941        let version = env!("CARGO_PKG_VERSION");
942        self.src.push_str(&format!(
943            "#[unsafe(link_section = \"component-type:wit-bindgen:{version}:\
944             {pkg}:{world_name}:{section_suffix}{opts_suffix}\")]\n"
945        ));
946
947        let mut producers = wasm_metadata::Producers::empty();
948        producers.add(
949            "processed-by",
950            env!("CARGO_PKG_NAME"),
951            env!("CARGO_PKG_VERSION"),
952        );
953
954        let component_type = wit_component::metadata::encode(
955            resolve,
956            world_id,
957            wit_component::StringEncoding::UTF8,
958            Some(&producers),
959        )
960        .unwrap();
961
962        self.src.push_str("#[doc(hidden)]\n");
963        self.src.push_str("#[allow(clippy::octal_escapes)]\n");
964        self.src.push_str(&format!(
965            "pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; {}] = *b\"\\\n",
966            component_type.len()
967        ));
968        let old_indent = self.src.set_indent(0);
969        let mut line_length = 0;
970        let s = self.src.as_mut_string();
971        for byte in component_type.iter() {
972            if line_length >= 80 {
973                s.push_str("\\\n");
974                line_length = 0;
975            }
976            match byte {
977                b'\\' => {
978                    s.push_str("\\\\");
979                    line_length += 2;
980                }
981                b'"' => {
982                    s.push_str("\\\"");
983                    line_length += 2;
984                }
985                b if b.is_ascii_alphanumeric() || b.is_ascii_punctuation() => {
986                    s.push(char::from(*byte));
987                    line_length += 1;
988                }
989                0 => {
990                    s.push_str("\\0");
991                    line_length += 2;
992                }
993                _ => {
994                    uwrite!(s, "\\x{:02x}", byte);
995                    line_length += 4;
996                }
997            }
998        }
999
1000        self.src.push_str("\";\n");
1001        self.src.set_indent(old_indent);
1002
1003        if let Some(func_name) = func_name {
1004            let rt = self.runtime_path().to_string();
1005            uwriteln!(
1006                self.src,
1007                "
1008                #[inline(never)]
1009                #[doc(hidden)]
1010                pub fn {func_name}() {{
1011                    {rt}::maybe_link_cabi_realloc();
1012                }}
1013            ",
1014            );
1015        }
1016    }
1017
1018    fn is_async(
1019        &mut self,
1020        resolve: &Resolve,
1021        interface: Option<&WorldKey>,
1022        func: &Function,
1023        is_import: bool,
1024    ) -> bool {
1025        self.opts
1026            .async_
1027            .is_async(resolve, interface, func, is_import)
1028    }
1029}
1030
1031impl WorldGenerator for RustWasm {
1032    fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
1033        wit_bindgen_core::generated_preamble(&mut self.src_preamble, env!("CARGO_PKG_VERSION"));
1034
1035        // Render some generator options to assist with debugging and/or to help
1036        // recreate it if the original generation command is lost.
1037        uwriteln!(self.src_preamble, "// Options used:");
1038        if self.opts.std_feature {
1039            uwriteln!(self.src_preamble, "//   * std_feature");
1040        }
1041        if self.opts.raw_strings {
1042            uwriteln!(self.src_preamble, "//   * raw_strings");
1043        }
1044        if !self.opts.skip.is_empty() {
1045            uwriteln!(self.src_preamble, "//   * skip: {:?}", self.opts.skip);
1046        }
1047        if self.opts.stubs {
1048            uwriteln!(self.src_preamble, "//   * stubs");
1049        }
1050        if let Some(export_prefix) = &self.opts.export_prefix {
1051            uwriteln!(
1052                self.src_preamble,
1053                "//   * export_prefix: {:?}",
1054                export_prefix
1055            );
1056        }
1057        if let Some(runtime_path) = &self.opts.runtime_path {
1058            uwriteln!(self.src_preamble, "//   * runtime_path: {:?}", runtime_path);
1059        }
1060        if let Some(bitflags_path) = &self.opts.bitflags_path {
1061            uwriteln!(
1062                self.src_preamble,
1063                "//   * bitflags_path: {:?}",
1064                bitflags_path
1065            );
1066        }
1067        if !matches!(self.opts.ownership, Ownership::Owning) {
1068            uwriteln!(
1069                self.src_preamble,
1070                "//   * ownership: {:?}",
1071                self.opts.ownership
1072            );
1073        }
1074        if !self.opts.additional_derive_attributes.is_empty() {
1075            uwriteln!(
1076                self.src_preamble,
1077                "//   * additional derives {:?}",
1078                self.opts.additional_derive_attributes
1079            );
1080        }
1081        if !self.opts.additional_derive_ignore.is_empty() {
1082            uwriteln!(
1083                self.src_preamble,
1084                "//   * additional derives ignored {:?}",
1085                self.opts.additional_derive_ignore
1086            );
1087        }
1088        for (k, v) in self.opts.with.iter() {
1089            uwriteln!(self.src_preamble, "//   * with {k:?} = {v}");
1090        }
1091        if let Some(type_section_suffix) = &self.opts.type_section_suffix {
1092            uwriteln!(
1093                self.src_preamble,
1094                "//   * type_section_suffix: {:?}",
1095                type_section_suffix
1096            );
1097        }
1098        if let Some(default) = &self.opts.default_bindings_module {
1099            uwriteln!(
1100                self.src_preamble,
1101                "//   * default-bindings-module: {default:?}"
1102            );
1103        }
1104        if self.opts.disable_run_ctors_once_workaround {
1105            uwriteln!(
1106                self.src_preamble,
1107                "//   * disable-run-ctors-once-workaround"
1108            );
1109        }
1110        if self.opts.merge_structurally_equal_types() {
1111            uwriteln!(self.src_preamble, "//   * merge_structurally_equal_types");
1112        }
1113        if let Some(s) = &self.opts.export_macro_name {
1114            uwriteln!(self.src_preamble, "//   * export-macro-name: {s}");
1115        }
1116        if self.opts.pub_export_macro {
1117            uwriteln!(self.src_preamble, "//   * pub-export-macro");
1118        }
1119        if self.opts.generate_unused_types {
1120            uwriteln!(self.src_preamble, "//   * generate_unused_types");
1121        }
1122        if self.opts.disable_custom_section_link_helpers {
1123            uwriteln!(
1124                self.src_preamble,
1125                "//   * disable_custom_section_link_helpers"
1126            );
1127        }
1128        for opt in self.opts.async_.debug_opts() {
1129            uwriteln!(self.src_preamble, "//   * async: {opt}");
1130        }
1131        self.types.analyze(resolve);
1132        self.types.collect_equal_types(resolve, &|a| {
1133            // If `--merge-structurally-equal-types` is enabled then any type
1134            // anywhere can be generated as a type alias to anything else.
1135            if self.opts.merge_structurally_equal_types() {
1136                return true;
1137            }
1138
1139            match resolve.types[a].kind {
1140                // These types are all defined with `type Foo = ...` in Rust
1141                // since Rust either has native representations or they live in
1142                // libraries or similar.
1143                TypeDefKind::Type(_)
1144                | TypeDefKind::Handle(_)
1145                | TypeDefKind::List(_)
1146                | TypeDefKind::Tuple(_)
1147                | TypeDefKind::Option(_)
1148                | TypeDefKind::Result(_)
1149                | TypeDefKind::Future(_)
1150                | TypeDefKind::Stream(_)
1151                | TypeDefKind::Map(..)
1152                | TypeDefKind::FixedLengthList(..) => true,
1153
1154                // These types are all defined with fresh new types defined
1155                // in generated bindings and thus can't alias some other
1156                // existing type.
1157                TypeDefKind::Record(_)
1158                | TypeDefKind::Variant(_)
1159                | TypeDefKind::Enum(_)
1160                | TypeDefKind::Flags(_)
1161                | TypeDefKind::Resource
1162                | TypeDefKind::Unknown => false,
1163            }
1164        });
1165        self.world = Some(world);
1166
1167        let world = &resolve.worlds[world];
1168        // Specify that all imports local to the world's package should be
1169        // generated
1170        for (key, item) in world.imports.iter() {
1171            if let WorldItem::Interface { id, .. } = item {
1172                if resolve.interfaces[*id].package == world.package {
1173                    let name = resolve.name_world_key(key);
1174                    if self.with.get(&name).is_none() {
1175                        self.with.insert(name, TypeGeneration::Generate);
1176                    }
1177                }
1178            }
1179        }
1180
1181        for item in world.exports.values() {
1182            let WorldItem::Interface { id, .. } = item else {
1183                continue;
1184            };
1185            for id in resolve.interfaces[*id].types.values().copied() {
1186                let TypeDefKind::Resource = &resolve.types[id].kind else {
1187                    continue;
1188                };
1189                assert!(self.exported_resources.insert(id));
1190            }
1191        }
1192
1193        for (k, v) in self.opts.with.iter() {
1194            self.with.insert(k.clone(), v.clone().into());
1195        }
1196        self.with.generate_by_default = self.opts.generate_all;
1197    }
1198
1199    fn import_interface(
1200        &mut self,
1201        resolve: &Resolve,
1202        name: &WorldKey,
1203        id: InterfaceId,
1204        _files: &mut Files,
1205    ) -> Result<()> {
1206        let mut to_define = Vec::new();
1207        for (name, ty_id) in resolve.interfaces[id].types.iter() {
1208            let full_name = full_wit_type_name(resolve, *ty_id);
1209            if let Some(type_gen) = self.with.get(&full_name) {
1210                // skip type definition generation for remapped types
1211                if type_gen.generated() {
1212                    to_define.push((name, ty_id));
1213                }
1214            } else {
1215                to_define.push((name, ty_id));
1216            }
1217            self.generated_types.insert(full_name);
1218        }
1219
1220        let wasm_import_module = resolve.name_world_key(name);
1221        let mut r#gen = self.interface(
1222            Identifier::Interface(id, name),
1223            &wasm_import_module,
1224            resolve,
1225            true,
1226        );
1227        let (snake, module_path) = r#gen.start_append_submodule(name);
1228        if r#gen.r#gen.name_interface(resolve, id, name, false)? {
1229            return Ok(());
1230        }
1231
1232        for (name, ty_id) in to_define {
1233            r#gen.define_type(&name, *ty_id);
1234        }
1235
1236        r#gen.generate_imports(resolve.interfaces[id].functions.values(), Some(name));
1237
1238        let docs = &resolve.interfaces[id].docs;
1239
1240        r#gen.finish_append_submodule(&snake, module_path, docs);
1241
1242        Ok(())
1243    }
1244
1245    fn import_funcs(
1246        &mut self,
1247        resolve: &Resolve,
1248        world: WorldId,
1249        funcs: &[(&str, &Function)],
1250        _files: &mut Files,
1251    ) {
1252        self.import_funcs_called = true;
1253
1254        let mut r#gen = self.interface(Identifier::World(world), "$root", resolve, true);
1255
1256        r#gen.generate_imports(funcs.iter().map(|(_, func)| *func), None);
1257
1258        let src = r#gen.finish();
1259        self.src.push_str(&src);
1260    }
1261
1262    fn export_interface(
1263        &mut self,
1264        resolve: &Resolve,
1265        name: &WorldKey,
1266        id: InterfaceId,
1267        _files: &mut Files,
1268    ) -> Result<()> {
1269        let mut to_define = Vec::new();
1270        for (ty_name, ty_id) in resolve.interfaces[id].types.iter() {
1271            let full_name = full_wit_type_name(resolve, *ty_id);
1272            to_define.push((ty_name, ty_id));
1273            self.generated_types.insert(full_name);
1274        }
1275
1276        let wasm_import_module = format!("[export]{}", resolve.name_world_key(name));
1277        let mut r#gen = self.interface(
1278            Identifier::Interface(id, name),
1279            &wasm_import_module,
1280            resolve,
1281            false,
1282        );
1283        let (snake, module_path) = r#gen.start_append_submodule(name);
1284        if r#gen.r#gen.name_interface(resolve, id, name, true)? {
1285            return Ok(());
1286        }
1287
1288        for (ty_name, ty_id) in to_define {
1289            r#gen.define_type(&ty_name, *ty_id);
1290        }
1291
1292        let macro_name =
1293            r#gen.generate_exports(Some((id, name)), resolve.interfaces[id].functions.values())?;
1294
1295        let docs = &resolve.interfaces[id].docs;
1296
1297        r#gen.finish_append_submodule(&snake, module_path, docs);
1298        self.export_macros
1299            .push((macro_name, self.interface_names[&id].path.clone()));
1300
1301        if self.opts.stubs {
1302            let world_id = self.world.unwrap();
1303            let mut r#gen = self.interface(
1304                Identifier::World(world_id),
1305                &wasm_import_module,
1306                resolve,
1307                false,
1308            );
1309            r#gen.generate_stub(Some((id, name)), resolve.interfaces[id].functions.values());
1310            let stub = r#gen.finish();
1311            self.src.push_str(&stub);
1312        }
1313        Ok(())
1314    }
1315
1316    fn export_funcs(
1317        &mut self,
1318        resolve: &Resolve,
1319        world: WorldId,
1320        funcs: &[(&str, &Function)],
1321        _files: &mut Files,
1322    ) -> Result<()> {
1323        let mut r#gen = self.interface(Identifier::World(world), "[export]$root", resolve, false);
1324        let macro_name = r#gen.generate_exports(None, funcs.iter().map(|f| f.1))?;
1325        let src = r#gen.finish();
1326        self.src.push_str(&src);
1327        self.export_macros.push((macro_name, String::new()));
1328
1329        if self.opts.stubs {
1330            let mut r#gen =
1331                self.interface(Identifier::World(world), "[export]$root", resolve, false);
1332            r#gen.generate_stub(None, funcs.iter().map(|f| f.1));
1333            let stub = r#gen.finish();
1334            self.src.push_str(&stub);
1335        }
1336        Ok(())
1337    }
1338
1339    fn import_types(
1340        &mut self,
1341        resolve: &Resolve,
1342        world: WorldId,
1343        types: &[(&str, TypeId)],
1344        _files: &mut Files,
1345    ) {
1346        let mut to_define = Vec::new();
1347        for (name, ty_id) in types {
1348            let full_name = full_wit_type_name(resolve, *ty_id);
1349            if let Some(type_gen) = self.with.get(&full_name) {
1350                // skip type definition generation for remapped types
1351                if type_gen.generated() {
1352                    to_define.push((name, ty_id));
1353                }
1354            } else {
1355                to_define.push((name, ty_id));
1356            }
1357            self.generated_types.insert(full_name);
1358        }
1359        let mut r#gen = self.interface(Identifier::World(world), "$root", resolve, true);
1360        for (name, ty) in to_define {
1361            r#gen.define_type(name, *ty);
1362        }
1363        let src = r#gen.finish();
1364        self.src.push_str(&src);
1365    }
1366
1367    fn finish_imports(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) {
1368        if !self.import_funcs_called {
1369            // We call `import_funcs` even if the world doesn't import any
1370            // functions since one of the side effects of that method is to
1371            // generate `struct`s for any imported resources.
1372            self.import_funcs(resolve, world, &[], files);
1373        }
1374    }
1375
1376    fn finish(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) -> Result<()> {
1377        let name = &resolve.worlds[world].name;
1378
1379        let imports = mem::take(&mut self.import_modules);
1380        self.emit_modules(imports);
1381        let exports = mem::take(&mut self.export_modules);
1382        self.emit_modules(exports);
1383
1384        self.finish_runtime_module();
1385        self.finish_export_macro(resolve, world);
1386
1387        // This is a bit tricky, but we sometimes want to "split" the `world` in
1388        // two and only encode the imports here.
1389        //
1390        // First, a primer. Each invocation of `generate!` has a WIT world as
1391        // input. This is one of the first steps in the build process as wasm
1392        // hasn't even been produced yet. One of the later stages of the build
1393        // process will be to emit a component, currently through the
1394        // `wit-component` crate. That crate relies on custom sections being
1395        // present to describe what WIT worlds were present in the wasm binary.
1396        //
1397        // Additionally a `generate!` macro is not the only thing in a binary.
1398        // There might be multiple `generate!` macros, perhaps even across
1399        // different languages. To handle all this `wit-component` will decode
1400        // each custom section and "union" everything together. Unioning in
1401        // general should work so long as everything has the same structure and
1402        // came from the same source.
1403        //
1404        // The problem here is that if `pub_export_macros` is turned on, meaning
1405        // that the macros are supposed to be used across crates, then neither
1406        // the imports nor the exports of this world are guaranteed to be used.
1407        // For imports that's ok because `wit-component` will drop any unused
1408        // imports automatically. For exports that's a problem because
1409        // `wit-component` unconditionally looks for a definition for all
1410        // exports.
1411        //
1412        // When `pub_export_macros` is turned on, and cross-crate usage of the
1413        // macro is expected, this is solved by emitting two custom sections:
1414        //
1415        // 1. The first section emitted here only has the imports of the world.
1416        //    This slimmed down world should be able to be unioned with the
1417        //    first world trivially and will be GC'd by `wit-component` if not
1418        //    used.
1419        // 2. The second section is emitted as part of the generated `export!`
1420        //    macro invocation. That world has all the export information as
1421        //    well as all the import information.
1422        //
1423        // In the end this is hoped to ensure that usage of crates like `wasi`
1424        // don't accidentally try to export things, for example.
1425        let mut resolve_copy;
1426        let (resolve_to_encode, world_to_encode) = if self.opts.pub_export_macro {
1427            resolve_copy = resolve.clone();
1428            let world_copy = resolve_copy.worlds.alloc(World {
1429                exports: Default::default(),
1430                name: format!("{name}-with-all-of-its-exports-removed"),
1431                ..resolve.worlds[world].clone()
1432            });
1433            (&resolve_copy, world_copy)
1434        } else {
1435            (resolve, world)
1436        };
1437        self.emit_custom_section(
1438            resolve_to_encode,
1439            world_to_encode,
1440            "encoded world",
1441            if self.opts.disable_custom_section_link_helpers {
1442                None
1443            } else {
1444                Some("__link_custom_section_describing_imports")
1445            },
1446        );
1447
1448        if self.opts.stubs {
1449            self.src.push_str("\n#[derive(Debug)]\npub struct Stub;\n");
1450        }
1451
1452        let mut src = mem::take(&mut self.src);
1453        if self.opts.format {
1454            let syntax_tree = syn::parse_file(src.as_str()).unwrap();
1455            *src.as_mut_string() = prettyplease::unparse(&syntax_tree);
1456        }
1457
1458        // Prepend the preamble. We do this after formatting because
1459        // `syn::parse_file` + `prettyplease::unparse` does not preserve comments.
1460        let src_preamble = mem::take(&mut self.src_preamble);
1461        *src.as_mut_string() = format!("{}{}", src_preamble.as_str(), src.as_str());
1462
1463        let module_name = name.to_snake_case();
1464        files.push(&format!("{module_name}.rs"), src.as_bytes());
1465
1466        let remapped_keys = self
1467            .with
1468            .iter()
1469            .map(|(k, _)| k)
1470            .cloned()
1471            .collect::<HashSet<String>>();
1472
1473        let mut unused_keys = remapped_keys
1474            .difference(&self.generated_types)
1475            .collect::<Vec<&String>>();
1476
1477        unused_keys.sort();
1478
1479        if !unused_keys.is_empty() {
1480            bail!("unused remappings provided via `with`: {unused_keys:?}");
1481        }
1482
1483        // Error about unused async configuration to help catch configuration
1484        // errors.
1485        self.opts.async_.ensure_all_used()?;
1486
1487        Ok(())
1488    }
1489}
1490
1491pub(crate) fn compute_module_path(
1492    name: &WorldKey,
1493    resolve: &Resolve,
1494    is_export: bool,
1495) -> Vec<String> {
1496    let mut path = Vec::new();
1497    if is_export {
1498        path.push("exports".to_string());
1499    }
1500    match name {
1501        WorldKey::Name(name) => {
1502            path.push(to_rust_ident(name));
1503        }
1504        WorldKey::Interface(id) => {
1505            let iface = &resolve.interfaces[*id];
1506            let pkg = iface.package.unwrap();
1507            let pkgname = resolve.packages[pkg].name.clone();
1508            path.push(to_rust_ident(&pkgname.namespace));
1509            path.push(name_package_module(resolve, pkg));
1510            path.push(to_rust_ident(iface.name.as_ref().unwrap()));
1511        }
1512    }
1513    path
1514}
1515
1516enum Identifier<'a> {
1517    World(WorldId),
1518    Interface(InterfaceId, &'a WorldKey),
1519    StreamOrFuturePayload,
1520}
1521
1522fn group_by_resource<'a>(
1523    funcs: impl Iterator<Item = &'a Function>,
1524) -> BTreeMap<Option<TypeId>, Vec<&'a Function>> {
1525    let mut by_resource = BTreeMap::<_, Vec<_>>::new();
1526    for func in funcs {
1527        by_resource
1528            .entry(func.kind.resource())
1529            .or_default()
1530            .push(func);
1531    }
1532    by_resource
1533}
1534
1535#[derive(Default, Debug, Clone, Copy)]
1536#[cfg_attr(
1537    feature = "serde",
1538    derive(serde::Deserialize),
1539    serde(rename_all = "kebab-case")
1540)]
1541pub enum Ownership {
1542    /// Generated types will be composed entirely of owning fields, regardless
1543    /// of whether they are used as parameters to imports or not.
1544    #[default]
1545    Owning,
1546
1547    /// Generated types used as parameters to imports will be "deeply
1548    /// borrowing", i.e. contain references rather than owned values when
1549    /// applicable.
1550    Borrowing {
1551        /// Whether or not to generate "duplicate" type definitions for a single
1552        /// WIT type if necessary, for example if it's used as both an import
1553        /// and an export, or if it's used both as a parameter to an import and
1554        /// a return value from an import.
1555        duplicate_if_necessary: bool,
1556    },
1557}
1558
1559impl FromStr for Ownership {
1560    type Err = String;
1561
1562    fn from_str(s: &str) -> Result<Self, Self::Err> {
1563        match s {
1564            "owning" => Ok(Self::Owning),
1565            "borrowing" => Ok(Self::Borrowing {
1566                duplicate_if_necessary: false,
1567            }),
1568            "borrowing-duplicate-if-necessary" => Ok(Self::Borrowing {
1569                duplicate_if_necessary: true,
1570            }),
1571            _ => Err(format!(
1572                "unrecognized ownership: `{s}`; \
1573                 expected `owning`, `borrowing`, or `borrowing-duplicate-if-necessary`"
1574            )),
1575        }
1576    }
1577}
1578
1579impl fmt::Display for Ownership {
1580    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1581        f.write_str(match self {
1582            Ownership::Owning => "owning",
1583            Ownership::Borrowing {
1584                duplicate_if_necessary: false,
1585            } => "borrowing",
1586            Ownership::Borrowing {
1587                duplicate_if_necessary: true,
1588            } => "borrowing-duplicate-if-necessary",
1589        })
1590    }
1591}
1592
1593/// Options for with "with" remappings.
1594#[derive(Debug, Clone)]
1595#[cfg_attr(
1596    feature = "serde",
1597    derive(serde::Deserialize),
1598    serde(rename_all = "kebab-case")
1599)]
1600pub enum WithOption {
1601    Path(String),
1602    Generate,
1603}
1604
1605impl std::fmt::Display for WithOption {
1606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607        match self {
1608            WithOption::Path(p) => f.write_fmt(format_args!("\"{p}\"")),
1609            WithOption::Generate => f.write_str("generate"),
1610        }
1611    }
1612}
1613
1614impl From<WithOption> for TypeGeneration {
1615    fn from(opt: WithOption) -> Self {
1616        match opt {
1617            WithOption::Path(p) => TypeGeneration::Remap(p),
1618            WithOption::Generate => TypeGeneration::Generate,
1619        }
1620    }
1621}
1622
1623#[derive(Default)]
1624struct FnSig {
1625    async_: bool,
1626    unsafe_: bool,
1627    private: bool,
1628    use_item_name: bool,
1629    generics: Option<String>,
1630    self_arg: Option<String>,
1631    self_is_first_param: bool,
1632}
1633
1634impl FnSig {
1635    fn update_for_func(&mut self, func: &Function) {
1636        if let FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) = &func.kind {
1637            self.self_arg = Some("&self".into());
1638            self.self_is_first_param = true;
1639        }
1640    }
1641}
1642
1643pub fn to_rust_ident(name: &str) -> String {
1644    match name {
1645        // Escape Rust keywords.
1646        // Source: https://doc.rust-lang.org/reference/keywords.html
1647        "as" => "as_".into(),
1648        "break" => "break_".into(),
1649        "const" => "const_".into(),
1650        "continue" => "continue_".into(),
1651        "crate" => "crate_".into(),
1652        "else" => "else_".into(),
1653        "enum" => "enum_".into(),
1654        "extern" => "extern_".into(),
1655        "false" => "false_".into(),
1656        "fn" => "fn_".into(),
1657        "for" => "for_".into(),
1658        "if" => "if_".into(),
1659        "impl" => "impl_".into(),
1660        "in" => "in_".into(),
1661        "let" => "let_".into(),
1662        "loop" => "loop_".into(),
1663        "match" => "match_".into(),
1664        "mod" => "mod_".into(),
1665        "move" => "move_".into(),
1666        "mut" => "mut_".into(),
1667        "pub" => "pub_".into(),
1668        "ref" => "ref_".into(),
1669        "return" => "return_".into(),
1670        "self" => "self_".into(),
1671        "static" => "static_".into(),
1672        "struct" => "struct_".into(),
1673        "super" => "super_".into(),
1674        "trait" => "trait_".into(),
1675        "true" => "true_".into(),
1676        "type" => "type_".into(),
1677        "unsafe" => "unsafe_".into(),
1678        "use" => "use_".into(),
1679        "where" => "where_".into(),
1680        "while" => "while_".into(),
1681        "async" => "async_".into(),
1682        "await" => "await_".into(),
1683        "dyn" => "dyn_".into(),
1684        "abstract" => "abstract_".into(),
1685        "become" => "become_".into(),
1686        "box" => "box_".into(),
1687        "do" => "do_".into(),
1688        "final" => "final_".into(),
1689        "macro" => "macro_".into(),
1690        "override" => "override_".into(),
1691        "priv" => "priv_".into(),
1692        "typeof" => "typeof_".into(),
1693        "unsized" => "unsized_".into(),
1694        "virtual" => "virtual_".into(),
1695        "yield" => "yield_".into(),
1696        "try" => "try_".into(),
1697        s => s.to_snake_case(),
1698    }
1699}
1700
1701fn to_upper_camel_case(name: &str) -> String {
1702    match name {
1703        // The name "Guest" is reserved for traits generated by exported
1704        // interfaces, so remap types defined in wit to something else.
1705        "guest" => "Guest_".to_string(),
1706        s => s.to_upper_camel_case(),
1707    }
1708}
1709
1710fn wasm_type(ty: WasmType) -> &'static str {
1711    match ty {
1712        WasmType::I32 => "i32",
1713        WasmType::I64 => "i64",
1714        WasmType::F32 => "f32",
1715        WasmType::F64 => "f64",
1716        WasmType::Pointer => "*mut u8",
1717        WasmType::Length => "usize",
1718
1719        // `PointerOrI64` can hold either a `u64` or a pointer with provenance.
1720        // Neither a `u64` nor a pointer type can portably do both, so we use
1721        // `MaybeUninit<u64>`, since `MaybeUninit` is [documented] to preserve
1722        // provenance.
1723        // [documented]: https://github.com/rust-lang/rfcs/blob/master/text/3559-rust-has-provenance.md#reference-level-explanation
1724        WasmType::PointerOrI64 => "::core::mem::MaybeUninit::<u64>",
1725    }
1726}
1727
1728fn declare_import(
1729    wasm_import_module: &str,
1730    wasm_import_name: &str,
1731    rust_name: &str,
1732    params: &[WasmType],
1733    results: &[WasmType],
1734) -> String {
1735    let mut sig = "(".to_owned();
1736    for param in params.iter() {
1737        sig.push_str("_: ");
1738        sig.push_str(wasm_type(*param));
1739        sig.push_str(", ");
1740    }
1741    sig.push(')');
1742    assert!(results.len() < 2);
1743    for result in results.iter() {
1744        sig.push_str(" -> ");
1745        sig.push_str(wasm_type(*result));
1746    }
1747    format!(
1748        "
1749            #[cfg(target_arch = \"wasm32\")]
1750            #[link(wasm_import_module = \"{wasm_import_module}\")]
1751            unsafe extern \"C\" {{
1752                #[link_name = \"{wasm_import_name}\"]
1753                fn {rust_name}{sig};
1754            }}
1755
1756            #[cfg(not(target_arch = \"wasm32\"))]
1757            unsafe extern \"C\" fn {rust_name}{sig} {{ unreachable!() }}
1758        "
1759    )
1760}
1761
1762fn int_repr(repr: Int) -> &'static str {
1763    match repr {
1764        Int::U8 => "u8",
1765        Int::U16 => "u16",
1766        Int::U32 => "u32",
1767        Int::U64 => "u64",
1768    }
1769}
1770
1771fn bitcast(casts: &[Bitcast], operands: &[String], results: &mut Vec<String>) {
1772    for (cast, operand) in casts.iter().zip(operands) {
1773        results.push(perform_cast(operand, cast));
1774    }
1775}
1776
1777fn perform_cast(operand: &str, cast: &Bitcast) -> String {
1778    match cast {
1779        Bitcast::None => operand.to_owned(),
1780        Bitcast::I32ToI64 => format!("i64::from({operand})"),
1781        Bitcast::F32ToI32 => format!("({operand}).to_bits() as i32"),
1782        Bitcast::F64ToI64 => format!("({operand}).to_bits() as i64"),
1783        Bitcast::I64ToI32 => format!("{operand} as i32"),
1784        Bitcast::I32ToF32 => format!("f32::from_bits({operand} as u32)"),
1785        Bitcast::I64ToF64 => format!("f64::from_bits({operand} as u64)"),
1786        Bitcast::F32ToI64 => format!("i64::from(({operand}).to_bits())"),
1787        Bitcast::I64ToF32 => format!("f32::from_bits({operand} as u32)"),
1788
1789        // Convert an `i64` into a `MaybeUninit<u64>`.
1790        Bitcast::I64ToP64 => format!("::core::mem::MaybeUninit::new({operand} as u64)"),
1791        // Convert a `MaybeUninit<u64>` holding an `i64` value back into
1792        // the `i64` value.
1793        Bitcast::P64ToI64 => format!("{operand}.assume_init() as i64"),
1794
1795        // Convert a pointer value into a `MaybeUninit<u64>`.
1796        Bitcast::PToP64 => {
1797            format!(
1798                "{{
1799                        let mut t = ::core::mem::MaybeUninit::<u64>::uninit();
1800                        t.as_mut_ptr().cast::<*mut u8>().write({operand});
1801                        t
1802                    }}"
1803            )
1804        }
1805        // Convert a `MaybeUninit<u64>` holding a pointer value back into
1806        // the pointer value.
1807        Bitcast::P64ToP => {
1808            format!("{operand}.as_ptr().cast::<*mut u8>().read()")
1809        }
1810        // Convert an `i32` or a `usize` into a pointer.
1811        Bitcast::I32ToP | Bitcast::LToP => {
1812            format!("{operand} as *mut u8")
1813        }
1814        // Convert a pointer or length holding an `i32` value back into the `i32`.
1815        Bitcast::PToI32 | Bitcast::LToI32 => {
1816            format!("{operand} as i32")
1817        }
1818        // Convert an `i32`, `i64`, or pointer holding a `usize` value back into the `usize`.
1819        Bitcast::I32ToL | Bitcast::I64ToL | Bitcast::PToL => {
1820            format!("{operand} as usize")
1821        }
1822        // Convert a `usize` into an `i64`.
1823        Bitcast::LToI64 => {
1824            format!("{operand} as i64")
1825        }
1826        Bitcast::Sequence(sequence) => {
1827            let [first, second] = &**sequence;
1828            perform_cast(&perform_cast(operand, first), second)
1829        }
1830    }
1831}
1832
1833enum RustFlagsRepr {
1834    U8,
1835    U16,
1836    U32,
1837    U64,
1838    U128,
1839}
1840
1841impl RustFlagsRepr {
1842    fn new(f: &Flags) -> RustFlagsRepr {
1843        match f.repr() {
1844            FlagsRepr::U8 => RustFlagsRepr::U8,
1845            FlagsRepr::U16 => RustFlagsRepr::U16,
1846            FlagsRepr::U32(1) => RustFlagsRepr::U32,
1847            FlagsRepr::U32(2) => RustFlagsRepr::U64,
1848            FlagsRepr::U32(3 | 4) => RustFlagsRepr::U128,
1849            FlagsRepr::U32(n) => panic!("unsupported number of flags: {}", n * 32),
1850        }
1851    }
1852}
1853
1854impl fmt::Display for RustFlagsRepr {
1855    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1856        match self {
1857            RustFlagsRepr::U8 => "u8".fmt(f),
1858            RustFlagsRepr::U16 => "u16".fmt(f),
1859            RustFlagsRepr::U32 => "u32".fmt(f),
1860            RustFlagsRepr::U64 => "u64".fmt(f),
1861            RustFlagsRepr::U128 => "u128".fmt(f),
1862        }
1863    }
1864}
1865
1866#[derive(Debug, Clone)]
1867pub struct MissingWith(pub String);
1868
1869impl fmt::Display for MissingWith {
1870    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1871        write!(f, "missing `with` mapping for the key `{}`", self.0)
1872    }
1873}
1874
1875impl std::error::Error for MissingWith {}
1876
1877// bail!("no remapping found for {with_name:?} - use the `generate!` macro's `with` option to force the interface to be generated or specify where it is already defined:
1878// ```
1879// with: {{\n\t{with_name:?}: generate\n}}
1880// ```")
1881
1882/// Returns the full WIT type name with fully qualified interface name
1883fn full_wit_type_name(resolve: &Resolve, id: TypeId) -> String {
1884    let id = dealias(resolve, id);
1885    let type_def = &resolve.types[id];
1886    let interface_name = match type_def.owner {
1887        TypeOwner::World(w) => Some(resolve.worlds[w].name.clone()),
1888        TypeOwner::Interface(id) => resolve.id_of(id),
1889        TypeOwner::None => None,
1890    };
1891    match interface_name {
1892        Some(interface_name) => format!("{}/{}", interface_name, type_def.name.clone().unwrap()),
1893        None => type_def.name.clone().unwrap(),
1894    }
1895}
1896
1897enum ConstructorReturnType {
1898    /// Resource constructor is infallible. E.g.:
1899    /// ```wit
1900    /// resource R {
1901    ///    constructor(..);
1902    /// }
1903    /// ```
1904    Self_,
1905
1906    /// Resource constructor is fallible. E.g.:
1907    /// ```wit
1908    /// resource R {
1909    ///    constructor(..) -> result<R, err>;
1910    /// }
1911    /// ```
1912    Result { err: Option<Type> },
1913}
1914
1915fn classify_constructor_return_type(
1916    resolve: &Resolve,
1917    resource_id: TypeId,
1918    result: &Option<Type>,
1919) -> ConstructorReturnType {
1920    fn classify(
1921        resolve: &Resolve,
1922        resource_id: TypeId,
1923        result: &Option<Type>,
1924    ) -> Option<ConstructorReturnType> {
1925        let resource_id = dealias(resolve, resource_id);
1926        let typedef = match result.as_ref()? {
1927            Type::Id(id) => &resolve.types[dealias(resolve, *id)],
1928            _ => return None,
1929        };
1930
1931        match &typedef.kind {
1932            TypeDefKind::Handle(Handle::Own(id)) if dealias(resolve, *id) == resource_id => {
1933                Some(ConstructorReturnType::Self_)
1934            }
1935            TypeDefKind::Result(Result_ { ok, err }) => {
1936                let ok_typedef = match ok.as_ref()? {
1937                    Type::Id(id) => &resolve.types[dealias(resolve, *id)],
1938                    _ => return None,
1939                };
1940
1941                match &ok_typedef.kind {
1942                    TypeDefKind::Handle(Handle::Own(id))
1943                        if dealias(resolve, *id) == resource_id =>
1944                    {
1945                        Some(ConstructorReturnType::Result { err: *err })
1946                    }
1947                    _ => None,
1948                }
1949            }
1950            _ => None,
1951        }
1952    }
1953
1954    classify(resolve, resource_id, result).expect("invalid constructor")
1955}