wit_bindgen_rust/
lib.rs

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