1 use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
2 use crate::types::{TypeInfo, Types};
3 use anyhow::bail;
4 use heck::*;
5 use indexmap::{IndexMap, IndexSet};
6 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
7 use std::fmt::Write as _;
8 use std::io::{Read, Write};
9 use std::mem;
10 use std::process::{Command, Stdio};
11 use wit_parser::*;
12 
13 macro_rules! uwrite {
14     ($dst:expr, $($arg:tt)*) => {
15         write!($dst, $($arg)*).unwrap()
16     };
17 }
18 
19 macro_rules! uwriteln {
20     ($dst:expr, $($arg:tt)*) => {
21         writeln!($dst, $($arg)*).unwrap()
22     };
23 }
24 
25 mod rust;
26 mod source;
27 mod types;
28 use source::Source;
29 
30 #[derive(Clone)]
31 enum InterfaceName {
32     /// This interface was remapped using `with` to some other Rust code.
33     Remapped {
34         /// This is the `::`-separated string which is the path to the mapped
35         /// item relative to the root of the `bindgen!` macro invocation.
36         ///
37         /// This path currently starts with `__with_name$N` and will then
38         /// optionally have `::` projections through to the actual item
39         /// depending on how `with` was configured.
40         name_at_root: String,
41 
42         /// This is currently only used for exports and is the relative path to
43         /// where this mapped name would be located if `with` were not
44         /// specified. Basically it's the same as the `Path` variant of this
45         /// enum if the mapping weren't present.
46         local_path: Vec<String>,
47     },
48 
49     /// This interface is generated in the module hierarchy specified.
50     ///
51     /// The path listed here is the path, from the root of the `bindgen!` macro,
52     /// to where this interface is generated.
53     Path(Vec<String>),
54 }
55 
56 #[derive(Default)]
57 struct Wasmtime {
58     src: Source,
59     opts: Opts,
60     /// A list of all interfaces which were imported by this world.
61     ///
62     /// The first value here is the contents of the module that this interface
63     /// generated. The second value is the name of the interface as also present
64     /// in `self.interface_names`.
65     import_interfaces: Vec<(String, InterfaceName)>,
66     import_functions: Vec<ImportFunction>,
67     exports: Exports,
68     types: Types,
69     sizes: SizeAlign,
70     interface_names: HashMap<InterfaceId, InterfaceName>,
71     interface_last_seen_as_import: HashMap<InterfaceId, bool>,
72     trappable_errors: IndexMap<TypeId, String>,
73     // Track the with options that were used. Remapped interfaces provided via `with`
74     // are required to be used.
75     used_with_opts: HashSet<String>,
76     // Track the imports that matched the `trappable_imports` spec.
77     used_trappable_imports_opts: HashSet<String>,
78 }
79 
80 struct ImportFunction {
81     func: Function,
82     add_to_linker: String,
83     sig: Option<String>,
84 }
85 
86 #[derive(Default)]
87 struct Exports {
88     fields: BTreeMap<String, ExportField>,
89     modules: Vec<(String, InterfaceName)>,
90     funcs: Vec<String>,
91 }
92 
93 struct ExportField {
94     ty: String,
95     ty_index: String,
96     load: String,
97     get_index_from_component: String,
98     get_index_from_instance: String,
99 }
100 
101 #[derive(Default, Debug, Clone, Copy)]
102 pub enum Ownership {
103     /// Generated types will be composed entirely of owning fields, regardless
104     /// of whether they are used as parameters to guest exports or not.
105     #[default]
106     Owning,
107 
108     /// Generated types used as parameters to guest exports will be "deeply
109     /// borrowing", i.e. contain references rather than owned values when
110     /// applicable.
111     Borrowing {
112         /// Whether or not to generate "duplicate" type definitions for a single
113         /// WIT type if necessary, for example if it's used as both an import
114         /// and an export, or if it's used both as a parameter to an export and
115         /// a return value from an export.
116         duplicate_if_necessary: bool,
117     },
118 }
119 
120 #[derive(Default, Debug, Clone)]
121 pub struct Opts {
122     /// Whether or not `rustfmt` is executed to format generated code.
123     pub rustfmt: bool,
124 
125     /// Whether or not to emit `tracing` macro calls on function entry/exit.
126     pub tracing: bool,
127 
128     /// Whether or not `tracing` macro calls should included argument and
129     /// return values which contain dynamically-sized `list` values.
130     pub verbose_tracing: bool,
131 
132     /// Whether or not to use async rust functions and traits.
133     pub async_: AsyncConfig,
134 
135     /// A list of "trappable errors" which are used to replace the `E` in
136     /// `result<T, E>` found in WIT.
137     pub trappable_error_type: Vec<TrappableError>,
138 
139     /// Whether to generate owning or borrowing type definitions.
140     pub ownership: Ownership,
141 
142     /// Whether or not to generate code for only the interfaces of this wit file or not.
143     pub only_interfaces: bool,
144 
145     /// Configuration of which imports are allowed to generate a trap.
146     pub trappable_imports: TrappableImports,
147 
148     /// Remapping of interface names to rust module names.
149     /// TODO: is there a better type to use for the value of this map?
150     pub with: HashMap<String, String>,
151 
152     /// Additional derive attributes to add to generated types. If using in a CLI, this flag can be
153     /// specified multiple times to add multiple attributes.
154     ///
155     /// These derive attributes will be added to any generated structs or enums
156     pub additional_derive_attributes: Vec<String>,
157 
158     /// Evaluate to a string literal containing the generated code rather than the generated tokens
159     /// themselves. Mostly useful for Wasmtime internal debugging and development.
160     pub stringify: bool,
161 
162     /// Temporary option to skip `impl<T: Trait> Trait for &mut T` for the
163     /// `wasmtime-wasi` crate while that's given a chance to update its b
164     /// indings.
165     pub skip_mut_forwarding_impls: bool,
166 
167     /// Indicates that the `T` in `Store<T>` should be send even if async is not
168     /// enabled.
169     ///
170     /// This is helpful when sync bindings depend on generated functions from
171     /// async bindings as is the case with WASI in-tree.
172     pub require_store_data_send: bool,
173 
174     /// Path to the `wasmtime` crate if it's not the default path.
175     pub wasmtime_crate: Option<String>,
176 }
177 
178 #[derive(Debug, Clone)]
179 pub struct TrappableError {
180     /// Full path to the error, such as `wasi:io/streams/error`.
181     pub wit_path: String,
182 
183     /// The name, in Rust, of the error type to generate.
184     pub rust_type_name: String,
185 }
186 
187 /// Which imports should be generated as async functions.
188 ///
189 /// The imports should be declared in the following format:
190 /// - Regular functions: `"{function-name}"`
191 /// - Resource methods: `"[method]{resource-name}.{method-name}"`
192 /// - Resource destructors: `"[drop]{resource-name}"`
193 ///
194 /// Examples:
195 /// - Regular function: `"get-environment"`
196 /// - Resource method: `"[method]input-stream.read"`
197 /// - Resource destructor: `"[drop]input-stream"`
198 #[derive(Default, Debug, Clone)]
199 pub enum AsyncConfig {
200     /// No functions are `async`.
201     #[default]
202     None,
203     /// All generated functions should be `async`.
204     All,
205     /// These imported functions should not be async, but everything else is.
206     AllExceptImports(HashSet<String>),
207     /// These functions are the only imports that are async, all other imports
208     /// are sync.
209     ///
210     /// Note that all exports are still async in this situation.
211     OnlyImports(HashSet<String>),
212 }
213 
214 impl AsyncConfig {
215     pub fn is_import_async(&self, f: &str) -> bool {
216         match self {
217             AsyncConfig::None => false,
218             AsyncConfig::All => true,
219             AsyncConfig::AllExceptImports(set) => !set.contains(f),
220             AsyncConfig::OnlyImports(set) => set.contains(f),
221         }
222     }
223 
224     pub fn is_drop_async(&self, r: &str) -> bool {
225         self.is_import_async(&format!("[drop]{r}"))
226     }
227 
228     pub fn maybe_async(&self) -> bool {
229         match self {
230             AsyncConfig::None => false,
231             AsyncConfig::All | AsyncConfig::AllExceptImports(_) | AsyncConfig::OnlyImports(_) => {
232                 true
233             }
234         }
235     }
236 }
237 
238 #[derive(Default, Debug, Clone)]
239 pub enum TrappableImports {
240     /// No imports are allowed to trap.
241     #[default]
242     None,
243     /// All imports may trap.
244     All,
245     /// Only the specified set of functions may trap.
246     Only(HashSet<String>),
247 }
248 
249 impl TrappableImports {
250     fn can_trap(&self, f: &Function) -> bool {
251         match self {
252             TrappableImports::None => false,
253             TrappableImports::All => true,
254             TrappableImports::Only(set) => set.contains(&f.name),
255         }
256     }
257 }
258 
259 impl Opts {
260     pub fn generate(&self, resolve: &Resolve, world: WorldId) -> anyhow::Result<String> {
261         let mut r = Wasmtime::default();
262         r.sizes.fill(resolve);
263         r.opts = self.clone();
264         r.generate(resolve, world)
265     }
266 
267     fn is_store_data_send(&self) -> bool {
268         self.async_.maybe_async() || self.require_store_data_send
269     }
270 }
271 
272 impl Wasmtime {
273     fn name_interface(
274         &mut self,
275         resolve: &Resolve,
276         id: InterfaceId,
277         name: &WorldKey,
278         is_export: bool,
279     ) -> bool {
280         let mut path = Vec::new();
281         if is_export {
282             path.push("exports".to_string());
283         }
284         match name {
285             WorldKey::Name(name) => {
286                 path.push(name.to_snake_case());
287             }
288             WorldKey::Interface(_) => {
289                 let iface = &resolve.interfaces[id];
290                 let pkgname = &resolve.packages[iface.package.unwrap()].name;
291                 path.push(pkgname.namespace.to_snake_case());
292                 path.push(self.name_package_module(resolve, iface.package.unwrap()));
293                 path.push(to_rust_ident(iface.name.as_ref().unwrap()));
294             }
295         }
296         let entry = if let Some(name_at_root) = self.lookup_replacement(resolve, name, None) {
297             InterfaceName::Remapped {
298                 name_at_root,
299                 local_path: path,
300             }
301         } else {
302             InterfaceName::Path(path)
303         };
304 
305         let remapped = matches!(entry, InterfaceName::Remapped { .. });
306         self.interface_names.insert(id, entry);
307         remapped
308     }
309 
310     /// If the package `id` is the only package with its namespace/name combo
311     /// then pass through the name unmodified. If, however, there are multiple
312     /// versions of this package then the package module is going to get version
313     /// information.
314     fn name_package_module(&self, resolve: &Resolve, id: PackageId) -> String {
315         let pkg = &resolve.packages[id];
316         let versions_with_same_name = resolve
317             .packages
318             .iter()
319             .filter_map(|(_, p)| {
320                 if p.name.namespace == pkg.name.namespace && p.name.name == pkg.name.name {
321                     Some(&p.name.version)
322                 } else {
323                     None
324                 }
325             })
326             .collect::<Vec<_>>();
327         let base = pkg.name.name.to_snake_case();
328         if versions_with_same_name.len() == 1 {
329             return base;
330         }
331 
332         let version = match &pkg.name.version {
333             Some(version) => version,
334             // If this package didn't have a version then don't mangle its name
335             // and other packages with the same name but with versions present
336             // will have their names mangled.
337             None => return base,
338         };
339 
340         // Here there's multiple packages with the same name that differ only in
341         // version, so the version needs to be mangled into the Rust module name
342         // that we're generating. This in theory could look at all of
343         // `versions_with_same_name` and produce a minimal diff, e.g. for 0.1.0
344         // and 0.2.0 this could generate "foo1" and "foo2", but for now
345         // a simpler path is chosen to generate "foo0_1_0" and "foo0_2_0".
346         let version = version
347             .to_string()
348             .replace('.', "_")
349             .replace('-', "_")
350             .replace('+', "_")
351             .to_snake_case();
352         format!("{base}{version}")
353     }
354 
355     fn generate(&mut self, resolve: &Resolve, id: WorldId) -> anyhow::Result<String> {
356         self.types.analyze(resolve, id);
357 
358         // Resolve the `trappable_error_type` configuration values to `TypeId`
359         // values. This is done by iterating over each `trappable_error_type`
360         // and then locating the interface that it corresponds to as well as the
361         // type within that interface.
362         //
363         // Note that `LookupItem::InterfaceNoPop` is used here as the full
364         // hierarchical behavior of `lookup_keys` isn't used as the interface
365         // must be named here.
366         'outer: for (i, te) in self.opts.trappable_error_type.iter().enumerate() {
367             let error_name = format!("_TrappableError{i}");
368             for (id, iface) in resolve.interfaces.iter() {
369                 for (key, projection) in lookup_keys(
370                     resolve,
371                     &WorldKey::Interface(id),
372                     LookupItem::InterfaceNoPop,
373                 ) {
374                     assert!(projection.is_empty());
375 
376                     // If `wit_path` looks like `{key}/{type_name}` where
377                     // `type_name` is a type within `iface` then we've found a
378                     // match. Otherwise continue to the next lookup key if there
379                     // is one, and failing that continue to the next interface.
380                     let suffix = match te.wit_path.strip_prefix(&key) {
381                         Some(s) => s,
382                         None => continue,
383                     };
384                     let suffix = match suffix.strip_prefix('/') {
385                         Some(s) => s,
386                         None => continue,
387                     };
388                     if let Some(id) = iface.types.get(suffix) {
389                         uwriteln!(self.src, "type {error_name} = {};", te.rust_type_name);
390                         let prev = self.trappable_errors.insert(*id, error_name);
391                         assert!(prev.is_none());
392                         continue 'outer;
393                     }
394                 }
395             }
396 
397             bail!(
398                 "failed to locate a WIT error type corresponding to the \
399                    `trappable_error_type` name `{}` provided",
400                 te.wit_path
401             )
402         }
403 
404         // Convert all entries in `with` as relative to the root of where the
405         // macro itself is invoked. This emits a `pub use` to bring the name
406         // into scope under an "anonymous name" which then replaces the `with`
407         // map entry.
408         let mut with = self.opts.with.iter_mut().collect::<Vec<_>>();
409         with.sort();
410         for (i, (_k, v)) in with.into_iter().enumerate() {
411             let name = format!("__with_name{i}");
412             uwriteln!(self.src, "#[doc(hidden)]\npub use {v} as {name};");
413             *v = name;
414         }
415 
416         let world = &resolve.worlds[id];
417         for (name, import) in world.imports.iter() {
418             if !self.opts.only_interfaces || matches!(import, WorldItem::Interface { .. }) {
419                 self.import(resolve, id, name, import);
420             }
421         }
422 
423         for (name, export) in world.exports.iter() {
424             if !self.opts.only_interfaces || matches!(export, WorldItem::Interface { .. }) {
425                 self.export(resolve, name, export);
426             }
427         }
428         self.finish(resolve, id)
429     }
430 
431     fn import(&mut self, resolve: &Resolve, world: WorldId, name: &WorldKey, item: &WorldItem) {
432         let mut gen = InterfaceGenerator::new(self, resolve);
433         match item {
434             WorldItem::Function(func) => {
435                 // Only generate a trait signature for free functions since
436                 // resource-related functions get their trait signatures
437                 // during `type_resource`.
438                 let sig = if let FunctionKind::Freestanding = func.kind {
439                     gen.generate_function_trait_sig(func);
440                     Some(mem::take(&mut gen.src).into())
441                 } else {
442                     None
443                 };
444                 gen.generate_add_function_to_linker(TypeOwner::World(world), func, "linker");
445                 let add_to_linker = gen.src.into();
446                 self.import_functions.push(ImportFunction {
447                     func: func.clone(),
448                     sig,
449                     add_to_linker,
450                 });
451             }
452             WorldItem::Interface { id, .. } => {
453                 gen.gen.interface_last_seen_as_import.insert(*id, true);
454                 gen.current_interface = Some((*id, name, false));
455                 let snake = match name {
456                     WorldKey::Name(s) => s.to_snake_case(),
457                     WorldKey::Interface(id) => resolve.interfaces[*id]
458                         .name
459                         .as_ref()
460                         .unwrap()
461                         .to_snake_case(),
462                 };
463                 let module = if gen.gen.name_interface(resolve, *id, name, false) {
464                     // If this interface is remapped then that means that it was
465                     // provided via the `with` key in the bindgen configuration.
466                     // That means that bindings generation is skipped here. To
467                     // accommodate future bindgens depending on this bindgen
468                     // though we still generate a module which reexports the
469                     // original module. This helps maintain the same output
470                     // structure regardless of whether `with` is used.
471                     let name_at_root = match &gen.gen.interface_names[id] {
472                         InterfaceName::Remapped { name_at_root, .. } => name_at_root,
473                         InterfaceName::Path(_) => unreachable!(),
474                     };
475                     let path_to_root = gen.path_to_root();
476                     format!(
477                         "
478                             pub mod {snake} {{
479                                 #[allow(unused_imports)]
480                                 pub use {path_to_root}{name_at_root}::*;
481                             }}
482                         "
483                     )
484                 } else {
485                     // If this interface is not remapped then it's time to
486                     // actually generate bindings here.
487                     gen.types(*id);
488                     let key_name = resolve.name_world_key(name);
489                     gen.generate_add_to_linker(*id, &key_name);
490 
491                     let module = &gen.src[..];
492                     let wt = gen.gen.wasmtime_path();
493 
494                     format!(
495                         "
496                             #[allow(clippy::all)]
497                             pub mod {snake} {{
498                                 #[allow(unused_imports)]
499                                 use {wt}::component::__internal::anyhow;
500 
501                                 {module}
502                             }}
503                         "
504                     )
505                 };
506                 self.import_interfaces
507                     .push((module, self.interface_names[id].clone()));
508             }
509             WorldItem::Type(ty) => {
510                 let name = match name {
511                     WorldKey::Name(name) => name,
512                     WorldKey::Interface(_) => unreachable!(),
513                 };
514                 gen.define_type(name, *ty);
515                 let body = mem::take(&mut gen.src);
516                 self.src.push_str(&body);
517             }
518         };
519     }
520 
521     fn export(&mut self, resolve: &Resolve, name: &WorldKey, item: &WorldItem) {
522         let wt = self.wasmtime_path();
523         let mut gen = InterfaceGenerator::new(self, resolve);
524         let field;
525         let ty;
526         let ty_index;
527         let load;
528         let get_index_from_component;
529         let get_index_from_instance;
530         match item {
531             WorldItem::Function(func) => {
532                 gen.define_rust_guest_export(resolve, None, func);
533                 let body = mem::take(&mut gen.src).into();
534                 load = gen.extract_typed_function(func).1;
535                 assert!(gen.src.is_empty());
536                 self.exports.funcs.push(body);
537                 ty_index = format!("{wt}::component::ComponentExportIndex");
538                 field = func_field_name(resolve, func);
539                 ty = format!("{wt}::component::Func");
540                 get_index_from_component = format!(
541                     "_component.export_index(None, \"{}\")
542                         .ok_or_else(|| anyhow::anyhow!(\"no function export `{0}` found\"))?.1",
543                     func.name
544                 );
545                 get_index_from_instance = format!(
546                     "_instance.get_export(&mut store, None, \"{}\")
547                         .ok_or_else(|| anyhow::anyhow!(\"no function export `{0}` found\"))?",
548                     func.name
549                 );
550             }
551             WorldItem::Type(_) => unreachable!(),
552             WorldItem::Interface { id, .. } => {
553                 gen.gen.interface_last_seen_as_import.insert(*id, false);
554                 gen.gen.name_interface(resolve, *id, name, true);
555                 gen.current_interface = Some((*id, name, true));
556                 gen.types(*id);
557                 let struct_name = "Guest";
558                 let iface = &resolve.interfaces[*id];
559                 let iface_name = match name {
560                     WorldKey::Name(name) => name,
561                     WorldKey::Interface(_) => iface.name.as_ref().unwrap(),
562                 };
563                 uwriteln!(gen.src, "pub struct {struct_name} {{");
564                 for (_, func) in iface.functions.iter() {
565                     uwriteln!(
566                         gen.src,
567                         "{}: {wt}::component::Func,",
568                         func_field_name(resolve, func)
569                     );
570                 }
571                 uwriteln!(gen.src, "}}");
572 
573                 uwriteln!(gen.src, "#[derive(Clone)]");
574                 uwriteln!(gen.src, "pub struct {struct_name}Indices {{");
575                 for (_, func) in iface.functions.iter() {
576                     uwriteln!(
577                         gen.src,
578                         "{}: {wt}::component::ComponentExportIndex,",
579                         func_field_name(resolve, func)
580                     );
581                 }
582                 uwriteln!(gen.src, "}}");
583 
584                 uwriteln!(gen.src, "impl {struct_name}Indices {{");
585                 let instance_name = resolve.name_world_key(name);
586                 uwrite!(
587                     gen.src,
588                     "
589 /// Constructor for [`{struct_name}Indices`] which takes a
590 /// [`Component`]({wt}::component::Component) as input and can be executed
591 /// before instantiation.
592 ///
593 /// This constructor can be used to front-load string lookups to find exports
594 /// within a component.
595 pub fn new(
596     component: &{wt}::component::Component,
597 ) -> {wt}::Result<{struct_name}Indices> {{
598     let (_, instance) = component.export_index(None, \"{instance_name}\")
599         .ok_or_else(|| anyhow::anyhow!(\"no exported instance named `{instance_name}`\"))?;
600     Self::_new(|name| {{
601         component.export_index(Some(&instance), name)
602             .map(|p| p.1)
603     }})
604 }}
605 
606 /// This constructor is similar to [`{struct_name}Indices::new`] except that it
607 /// performs string lookups after instantiation time.
608 pub fn new_instance(
609     mut store: impl {wt}::AsContextMut,
610     instance: &{wt}::component::Instance,
611 ) -> {wt}::Result<{struct_name}Indices> {{
612     let instance_export = instance.get_export(&mut store, None, \"{instance_name}\")
613         .ok_or_else(|| anyhow::anyhow!(\"no exported instance named `{instance_name}`\"))?;
614     Self::_new(|name| {{
615         instance.get_export(&mut store, Some(&instance_export), name)
616     }})
617 }}
618 
619 fn _new(
620     mut lookup: impl FnMut (&str) -> Option<{wt}::component::ComponentExportIndex>,
621 ) -> {wt}::Result<{struct_name}Indices> {{
622     let mut lookup = move |name| {{
623         lookup(name).ok_or_else(|| {{
624             anyhow::anyhow!(
625                 \"instance export `{instance_name}` does \\
626                   not have export `{{name}}`\"
627             )
628         }})
629     }};
630     let _ = &mut lookup;
631                     "
632                 );
633                 let mut fields = Vec::new();
634                 for (_, func) in iface.functions.iter() {
635                     let name = func_field_name(resolve, func);
636                     uwriteln!(gen.src, "let {name} = lookup(\"{}\")?;", func.name);
637                     fields.push(name);
638                 }
639                 uwriteln!(gen.src, "Ok({struct_name}Indices {{");
640                 for name in fields {
641                     uwriteln!(gen.src, "{name},");
642                 }
643                 uwriteln!(gen.src, "}})");
644                 uwriteln!(gen.src, "}}"); // end `fn _new`
645 
646                 uwrite!(
647                     gen.src,
648                     "
649                         pub fn load(
650                             &self,
651                             mut store: impl {wt}::AsContextMut,
652                             instance: &{wt}::component::Instance,
653                         ) -> {wt}::Result<{struct_name}> {{
654                             let mut store = store.as_context_mut();
655                             let _ = &mut store;
656                             let _instance = instance;
657                     "
658                 );
659                 let mut fields = Vec::new();
660                 for (_, func) in iface.functions.iter() {
661                     let (name, getter) = gen.extract_typed_function(func);
662                     uwriteln!(gen.src, "let {name} = {getter};");
663                     fields.push(name);
664                 }
665                 uwriteln!(gen.src, "Ok({struct_name} {{");
666                 for name in fields {
667                     uwriteln!(gen.src, "{name},");
668                 }
669                 uwriteln!(gen.src, "}})");
670                 uwriteln!(gen.src, "}}"); // end `fn new`
671                 uwriteln!(gen.src, "}}"); // end `impl {struct_name}Indices`
672 
673                 uwriteln!(gen.src, "impl {struct_name} {{");
674                 let mut resource_methods = IndexMap::new();
675 
676                 for (_, func) in iface.functions.iter() {
677                     match func.kind {
678                         FunctionKind::Freestanding => {
679                             gen.define_rust_guest_export(resolve, Some(name), func);
680                         }
681                         FunctionKind::Method(id)
682                         | FunctionKind::Constructor(id)
683                         | FunctionKind::Static(id) => {
684                             resource_methods.entry(id).or_insert(Vec::new()).push(func);
685                         }
686                     }
687                 }
688 
689                 for (id, _) in resource_methods.iter() {
690                     let name = resolve.types[*id].name.as_ref().unwrap();
691                     let snake = name.to_snake_case();
692                     let camel = name.to_upper_camel_case();
693                     uwriteln!(
694                         gen.src,
695                         "pub fn {snake}(&self) -> Guest{camel}<'_> {{
696                             Guest{camel} {{ funcs: self }}
697                         }}"
698                     );
699                 }
700 
701                 uwriteln!(gen.src, "}}");
702 
703                 for (id, methods) in resource_methods {
704                     let resource_name = resolve.types[id].name.as_ref().unwrap();
705                     let camel = resource_name.to_upper_camel_case();
706                     uwriteln!(gen.src, "impl Guest{camel}<'_> {{");
707                     for method in methods {
708                         gen.define_rust_guest_export(resolve, Some(name), method);
709                     }
710                     uwriteln!(gen.src, "}}");
711                 }
712 
713                 let module = &gen.src[..];
714                 let snake = to_rust_ident(iface_name);
715 
716                 let module = format!(
717                     "
718                         #[allow(clippy::all)]
719                         pub mod {snake} {{
720                             #[allow(unused_imports)]
721                             use {wt}::component::__internal::anyhow;
722 
723                             {module}
724                         }}
725                     "
726                 );
727                 let pkgname = match name {
728                     WorldKey::Name(_) => None,
729                     WorldKey::Interface(_) => {
730                         Some(resolve.packages[iface.package.unwrap()].name.clone())
731                     }
732                 };
733                 self.exports
734                     .modules
735                     .push((module, self.interface_names[id].clone()));
736 
737                 let (path, method_name) = match pkgname {
738                     Some(pkgname) => (
739                         format!(
740                             "exports::{}::{}::{snake}::{struct_name}",
741                             pkgname.namespace.to_snake_case(),
742                             self.name_package_module(resolve, iface.package.unwrap()),
743                         ),
744                         format!(
745                             "{}_{}_{snake}",
746                             pkgname.namespace.to_snake_case(),
747                             self.name_package_module(resolve, iface.package.unwrap())
748                         ),
749                     ),
750                     None => (format!("exports::{snake}::{struct_name}"), snake.clone()),
751                 };
752                 field = format!("interface{}", self.exports.fields.len());
753                 load = format!("self.{field}.load(&mut store, &_instance)?");
754                 self.exports.funcs.push(format!(
755                     "
756                         pub fn {method_name}(&self) -> &{path} {{
757                             &self.{field}
758                         }}
759                     ",
760                 ));
761                 ty_index = format!("{path}Indices");
762                 ty = path;
763                 get_index_from_component = format!("{ty_index}::new(_component)?");
764                 get_index_from_instance =
765                     format!("{ty_index}::new_instance(&mut store, _instance)?");
766             }
767         }
768         let prev = self.exports.fields.insert(
769             field,
770             ExportField {
771                 ty,
772                 ty_index,
773                 load,
774                 get_index_from_component,
775                 get_index_from_instance,
776             },
777         );
778         assert!(prev.is_none());
779     }
780 
781     fn build_world_struct(&mut self, resolve: &Resolve, world: WorldId) {
782         let wt = self.wasmtime_path();
783         let world_name = &resolve.worlds[world].name;
784         let camel = to_rust_upper_camel_case(&world_name);
785         let (async_, async__, where_clause, await_) = if self.opts.async_.maybe_async() {
786             ("async", "_async", "where _T: Send", ".await")
787         } else {
788             ("", "", "", "")
789         };
790         uwriteln!(
791             self.src,
792             "
793 /// Auto-generated bindings for a pre-instantiated version of a
794 /// component which implements the world `{world_name}`.
795 ///
796 /// This structure is created through [`{camel}Pre::new`] which
797 /// takes a [`InstancePre`]({wt}::component::InstancePre) that
798 /// has been created through a [`Linker`]({wt}::component::Linker).
799 ///
800 /// For more information see [`{camel}`] as well.
801 pub struct {camel}Pre<T> {{
802     instance_pre: {wt}::component::InstancePre<T>,
803     indices: {camel}Indices,
804 }}
805 
806 impl<T> Clone for {camel}Pre<T> {{
807     fn clone(&self) -> Self {{
808         Self {{
809             instance_pre: self.instance_pre.clone(),
810             indices: self.indices.clone(),
811         }}
812     }}
813 }}
814 
815 impl<_T> {camel}Pre<_T> {{
816     /// Creates a new copy of `{camel}Pre` bindings which can then
817     /// be used to instantiate into a particular store.
818     ///
819     /// This method may fail if the component behind `instance_pre`
820     /// does not have the required exports.
821     pub fn new(instance_pre: {wt}::component::InstancePre<_T>) -> {wt}::Result<Self> {{
822         let indices = {camel}Indices::new(instance_pre.component())?;
823         Ok(Self {{ instance_pre, indices }})
824     }}
825 
826     pub fn engine(&self) -> &{wt}::Engine {{
827         self.instance_pre.engine()
828     }}
829 
830     pub fn instance_pre(&self) -> &{wt}::component::InstancePre<_T> {{
831         &self.instance_pre
832     }}
833 
834     /// Instantiates a new instance of [`{camel}`] within the
835     /// `store` provided.
836     ///
837     /// This function will use `self` as the pre-instantiated
838     /// instance to perform instantiation. Afterwards the preloaded
839     /// indices in `self` are used to lookup all exports on the
840     /// resulting instance.
841     pub {async_} fn instantiate{async__}(
842         &self,
843         mut store: impl {wt}::AsContextMut<Data = _T>,
844     ) -> {wt}::Result<{camel}>
845         {where_clause}
846     {{
847         let mut store = store.as_context_mut();
848         let instance = self.instance_pre.instantiate{async__}(&mut store){await_}?;
849         self.indices.load(&mut store, &instance)
850     }}
851 }}
852 "
853         );
854 
855         uwriteln!(
856             self.src,
857             "
858             /// Auto-generated bindings for index of the exports of
859             /// `{world_name}`.
860             ///
861             /// This is an implementation detail of [`{camel}Pre`] and can
862             /// be constructed if needed as well.
863             ///
864             /// For more information see [`{camel}`] as well.
865             #[derive(Clone)]
866             pub struct {camel}Indices {{"
867         );
868         for (name, field) in self.exports.fields.iter() {
869             uwriteln!(self.src, "{name}: {},", field.ty_index);
870         }
871         self.src.push_str("}\n");
872 
873         uwriteln!(
874             self.src,
875             "
876                 /// Auto-generated bindings for an instance a component which
877                 /// implements the world `{world_name}`.
878                 ///
879                 /// This structure can be created through a number of means
880                 /// depending on your requirements and what you have on hand:
881                 ///
882                 /// * The most convenient way is to use
883                 ///   [`{camel}::instantiate{async__}`] which only needs a
884                 ///   [`Store`], [`Component`], and [`Linker`].
885                 ///
886                 /// * Alternatively you can create a [`{camel}Pre`] ahead of
887                 ///   time with a [`Component`] to front-load string lookups
888                 ///   of exports once instead of per-instantiation. This
889                 ///   method then uses [`{camel}Pre::instantiate{async__}`] to
890                 ///   create a [`{camel}`].
891                 ///
892                 /// * If you've instantiated the instance yourself already
893                 ///   then you can use [`{camel}::new`].
894                 ///
895                 /// * You can also access the guts of instantiation through
896                 ///   [`{camel}Indices::new_instance`] followed
897                 ///   by [`{camel}Indices::load`] to crate an instance of this
898                 ///   type.
899                 ///
900                 /// These methods are all equivalent to one another and move
901                 /// around the tradeoff of what work is performed when.
902                 ///
903                 /// [`Store`]: {wt}::Store
904                 /// [`Component`]: {wt}::component::Component
905                 /// [`Linker`]: {wt}::component::Linker
906                 pub struct {camel} {{"
907         );
908         for (name, field) in self.exports.fields.iter() {
909             uwriteln!(self.src, "{name}: {},", field.ty);
910         }
911         self.src.push_str("}\n");
912 
913         self.world_imports_trait(resolve, world);
914 
915         uwriteln!(self.src, "const _: () = {{");
916         uwriteln!(
917             self.src,
918             "
919                 #[allow(unused_imports)]
920                 use {wt}::component::__internal::anyhow;
921             "
922         );
923 
924         uwriteln!(
925             self.src,
926             "impl {camel}Indices {{
927                 /// Creates a new copy of `{camel}Indices` bindings which can then
928                 /// be used to instantiate into a particular store.
929                 ///
930                 /// This method may fail if the component does not have the
931                 /// required exports.
932                 pub fn new(component: &{wt}::component::Component) -> {wt}::Result<Self> {{
933                     let _component = component;
934             ",
935         );
936         for (name, field) in self.exports.fields.iter() {
937             uwriteln!(self.src, "let {name} = {};", field.get_index_from_component);
938         }
939         uwriteln!(self.src, "Ok({camel}Indices {{");
940         for (name, _) in self.exports.fields.iter() {
941             uwriteln!(self.src, "{name},");
942         }
943         uwriteln!(self.src, "}})");
944         uwriteln!(self.src, "}}"); // close `fn new`
945 
946         uwriteln!(
947             self.src,
948             "
949                 /// Creates a new instance of [`{camel}Indices`] from an
950                 /// instantiated component.
951                 ///
952                 /// This method of creating a [`{camel}`] will perform string
953                 /// lookups for all exports when this method is called. This
954                 /// will only succeed if the provided instance matches the
955                 /// requirements of [`{camel}`].
956                 pub fn new_instance(
957                     mut store: impl {wt}::AsContextMut,
958                     instance: &{wt}::component::Instance,
959                 ) -> {wt}::Result<Self> {{
960                     let _instance = instance;
961             ",
962         );
963         for (name, field) in self.exports.fields.iter() {
964             uwriteln!(self.src, "let {name} = {};", field.get_index_from_instance);
965         }
966         uwriteln!(self.src, "Ok({camel}Indices {{");
967         for (name, _) in self.exports.fields.iter() {
968             uwriteln!(self.src, "{name},");
969         }
970         uwriteln!(self.src, "}})");
971         uwriteln!(self.src, "}}"); // close `fn new_instance`
972 
973         uwriteln!(
974             self.src,
975             "
976                 /// Uses the indices stored in `self` to load an instance
977                 /// of [`{camel}`] from the instance provided.
978                 ///
979                 /// Note that at this time this method will additionally
980                 /// perform type-checks of all exports.
981                 pub fn load(
982                     &self,
983                     mut store: impl {wt}::AsContextMut,
984                     instance: &{wt}::component::Instance,
985                 ) -> {wt}::Result<{camel}> {{
986                     let _instance = instance;
987             ",
988         );
989         for (name, field) in self.exports.fields.iter() {
990             uwriteln!(self.src, "let {name} = {};", field.load);
991         }
992         uwriteln!(self.src, "Ok({camel} {{");
993         for (name, _) in self.exports.fields.iter() {
994             uwriteln!(self.src, "{name},");
995         }
996         uwriteln!(self.src, "}})");
997         uwriteln!(self.src, "}}"); // close `fn load`
998         uwriteln!(self.src, "}}"); // close `impl {camel}Indices`
999 
1000         uwriteln!(
1001             self.src,
1002             "impl {camel} {{
1003                 /// Convenience wrapper around [`{camel}Pre::new`] and
1004                 /// [`{camel}Pre::instantiate{async__}`].
1005                 pub {async_} fn instantiate{async__}<_T>(
1006                     mut store: impl {wt}::AsContextMut<Data = _T>,
1007                     component: &{wt}::component::Component,
1008                     linker: &{wt}::component::Linker<_T>,
1009                 ) -> {wt}::Result<{camel}>
1010                     {where_clause}
1011                 {{
1012                     let pre = linker.instantiate_pre(component)?;
1013                     {camel}Pre::new(pre)?.instantiate{async__}(store){await_}
1014                 }}
1015 
1016                 /// Convenience wrapper around [`{camel}Indices::new_instance`] and
1017                 /// [`{camel}Indices::load`].
1018                 pub fn new(
1019                     mut store: impl {wt}::AsContextMut,
1020                     instance: &{wt}::component::Instance,
1021                 ) -> {wt}::Result<{camel}> {{
1022                     let indices = {camel}Indices::new_instance(&mut store, instance)?;
1023                     indices.load(store, instance)
1024                 }}
1025             ",
1026         );
1027         self.world_add_to_linker(resolve, world);
1028 
1029         for func in self.exports.funcs.iter() {
1030             self.src.push_str(func);
1031         }
1032 
1033         uwriteln!(self.src, "}}"); // close `impl {camel}`
1034 
1035         uwriteln!(self.src, "}};"); // close `const _: () = ...
1036     }
1037 
1038     fn finish(&mut self, resolve: &Resolve, world: WorldId) -> anyhow::Result<String> {
1039         let remapping_keys = self.opts.with.keys().cloned().collect::<HashSet<String>>();
1040 
1041         let mut unused_keys = remapping_keys
1042             .difference(&self.used_with_opts)
1043             .map(|s| s.as_str())
1044             .collect::<Vec<&str>>();
1045 
1046         unused_keys.sort();
1047 
1048         if !unused_keys.is_empty() {
1049             anyhow::bail!("interfaces were specified in the `with` config option but are not referenced in the target world: {unused_keys:?}");
1050         }
1051 
1052         if let TrappableImports::Only(only) = &self.opts.trappable_imports {
1053             let mut unused_imports = Vec::from_iter(
1054                 only.difference(&self.used_trappable_imports_opts)
1055                     .map(|s| s.as_str()),
1056             );
1057 
1058             if !unused_imports.is_empty() {
1059                 unused_imports.sort();
1060                 anyhow::bail!("names specified in the `trappable_imports` config option but are not referenced in the target world: {unused_imports:?}");
1061             }
1062         }
1063 
1064         if !self.opts.only_interfaces {
1065             self.build_world_struct(resolve, world)
1066         }
1067 
1068         let imports = mem::take(&mut self.import_interfaces);
1069         self.emit_modules(imports);
1070 
1071         let exports = mem::take(&mut self.exports.modules);
1072         self.emit_modules(exports);
1073 
1074         let mut src = mem::take(&mut self.src);
1075         if self.opts.rustfmt {
1076             let mut child = Command::new("rustfmt")
1077                 .arg("--edition=2018")
1078                 .stdin(Stdio::piped())
1079                 .stdout(Stdio::piped())
1080                 .spawn()
1081                 .expect("failed to spawn `rustfmt`");
1082             child
1083                 .stdin
1084                 .take()
1085                 .unwrap()
1086                 .write_all(src.as_bytes())
1087                 .unwrap();
1088             src.as_mut_string().truncate(0);
1089             child
1090                 .stdout
1091                 .take()
1092                 .unwrap()
1093                 .read_to_string(src.as_mut_string())
1094                 .unwrap();
1095             let status = child.wait().unwrap();
1096             assert!(status.success());
1097         }
1098 
1099         Ok(src.into())
1100     }
1101 
1102     fn emit_modules(&mut self, modules: Vec<(String, InterfaceName)>) {
1103         #[derive(Default)]
1104         struct Module {
1105             submodules: BTreeMap<String, Module>,
1106             contents: Vec<String>,
1107         }
1108         let mut map = Module::default();
1109         for (module, name) in modules {
1110             let path = match name {
1111                 InterfaceName::Remapped { local_path, .. } => local_path,
1112                 InterfaceName::Path(path) => path,
1113             };
1114             let mut cur = &mut map;
1115             for name in path[..path.len() - 1].iter() {
1116                 cur = cur
1117                     .submodules
1118                     .entry(name.clone())
1119                     .or_insert(Module::default());
1120             }
1121             cur.contents.push(module);
1122         }
1123 
1124         emit(&mut self.src, map);
1125 
1126         fn emit(me: &mut Source, module: Module) {
1127             for (name, submodule) in module.submodules {
1128                 uwriteln!(me, "pub mod {name} {{");
1129                 emit(me, submodule);
1130                 uwriteln!(me, "}}");
1131             }
1132             for submodule in module.contents {
1133                 uwriteln!(me, "{submodule}");
1134             }
1135         }
1136     }
1137 
1138     /// Attempts to find the `key`, possibly with the resource projection
1139     /// `item`, within the `with` map provided to bindings configuration.
1140     fn lookup_replacement(
1141         &mut self,
1142         resolve: &Resolve,
1143         key: &WorldKey,
1144         item: Option<&str>,
1145     ) -> Option<String> {
1146         let item = match item {
1147             Some(item) => LookupItem::Name(item),
1148             None => LookupItem::None,
1149         };
1150 
1151         for (lookup, mut projection) in lookup_keys(resolve, key, item) {
1152             if let Some(renamed) = self.opts.with.get(&lookup) {
1153                 projection.push(renamed.clone());
1154                 projection.reverse();
1155                 self.used_with_opts.insert(lookup);
1156                 return Some(projection.join("::"));
1157             }
1158         }
1159 
1160         None
1161     }
1162 
1163     fn wasmtime_path(&self) -> String {
1164         self.opts
1165             .wasmtime_crate
1166             .clone()
1167             .unwrap_or("wasmtime".to_string())
1168     }
1169 }
1170 
1171 enum LookupItem<'a> {
1172     None,
1173     Name(&'a str),
1174     InterfaceNoPop,
1175 }
1176 
1177 fn lookup_keys(
1178     resolve: &Resolve,
1179     key: &WorldKey,
1180     item: LookupItem<'_>,
1181 ) -> Vec<(String, Vec<String>)> {
1182     struct Name<'a> {
1183         prefix: Prefix,
1184         item: Option<&'a str>,
1185     }
1186 
1187     #[derive(Copy, Clone)]
1188     enum Prefix {
1189         Namespace(PackageId),
1190         UnversionedPackage(PackageId),
1191         VersionedPackage(PackageId),
1192         UnversionedInterface(InterfaceId),
1193         VersionedInterface(InterfaceId),
1194     }
1195 
1196     let prefix = match key {
1197         WorldKey::Interface(id) => Prefix::VersionedInterface(*id),
1198 
1199         // Non-interface-keyed names don't get the lookup logic below,
1200         // they're relatively uncommon so only lookup the precise key here.
1201         WorldKey::Name(key) => {
1202             let to_lookup = match item {
1203                 LookupItem::Name(item) => format!("{key}/{item}"),
1204                 LookupItem::None | LookupItem::InterfaceNoPop => key.to_string(),
1205             };
1206             return vec![(to_lookup, Vec::new())];
1207         }
1208     };
1209 
1210     // Here names are iteratively attempted as `key` + `item` is "walked to
1211     // its root" and each attempt is consulted in `self.opts.with`. This
1212     // loop will start at the leaf, the most specific path, and then walk to
1213     // the root, popping items, trying to find a result.
1214     //
1215     // Each time a name is "popped" the projection from the next path is
1216     // pushed onto `projection`. This means that if we actually find a match
1217     // then `projection` is a collection of namespaces that results in the
1218     // final replacement name.
1219     let (interface_required, item) = match item {
1220         LookupItem::None => (false, None),
1221         LookupItem::Name(s) => (false, Some(s)),
1222         LookupItem::InterfaceNoPop => (true, None),
1223     };
1224     let mut name = Name { prefix, item };
1225     let mut projection = Vec::new();
1226     let mut ret = Vec::new();
1227     loop {
1228         let lookup = name.lookup_key(resolve);
1229         ret.push((lookup, projection.clone()));
1230         if !name.pop(resolve, &mut projection) {
1231             break;
1232         }
1233         if interface_required {
1234             match name.prefix {
1235                 Prefix::VersionedInterface(_) | Prefix::UnversionedInterface(_) => {}
1236                 _ => break,
1237             }
1238         }
1239     }
1240 
1241     return ret;
1242 
1243     impl<'a> Name<'a> {
1244         fn lookup_key(&self, resolve: &Resolve) -> String {
1245             let mut s = self.prefix.lookup_key(resolve);
1246             if let Some(item) = self.item {
1247                 s.push_str("/");
1248                 s.push_str(item);
1249             }
1250             s
1251         }
1252 
1253         fn pop(&mut self, resolve: &'a Resolve, projection: &mut Vec<String>) -> bool {
1254             match (self.item, self.prefix) {
1255                 // If this is a versioned resource name, try the unversioned
1256                 // resource name next.
1257                 (Some(_), Prefix::VersionedInterface(id)) => {
1258                     self.prefix = Prefix::UnversionedInterface(id);
1259                     true
1260                 }
1261                 // If this is an unversioned resource name then time to
1262                 // ignore the resource itself and move on to the next most
1263                 // specific item, versioned interface names.
1264                 (Some(item), Prefix::UnversionedInterface(id)) => {
1265                     self.prefix = Prefix::VersionedInterface(id);
1266                     self.item = None;
1267                     projection.push(item.to_upper_camel_case());
1268                     true
1269                 }
1270                 (Some(_), _) => unreachable!(),
1271                 (None, _) => self.prefix.pop(resolve, projection),
1272             }
1273         }
1274     }
1275 
1276     impl Prefix {
1277         fn lookup_key(&self, resolve: &Resolve) -> String {
1278             match *self {
1279                 Prefix::Namespace(id) => resolve.packages[id].name.namespace.clone(),
1280                 Prefix::UnversionedPackage(id) => {
1281                     let mut name = resolve.packages[id].name.clone();
1282                     name.version = None;
1283                     name.to_string()
1284                 }
1285                 Prefix::VersionedPackage(id) => resolve.packages[id].name.to_string(),
1286                 Prefix::UnversionedInterface(id) => {
1287                     let id = resolve.id_of(id).unwrap();
1288                     match id.find('@') {
1289                         Some(i) => id[..i].to_string(),
1290                         None => id,
1291                     }
1292                 }
1293                 Prefix::VersionedInterface(id) => resolve.id_of(id).unwrap(),
1294             }
1295         }
1296 
1297         fn pop(&mut self, resolve: &Resolve, projection: &mut Vec<String>) -> bool {
1298             *self = match *self {
1299                 // try the unversioned interface next
1300                 Prefix::VersionedInterface(id) => Prefix::UnversionedInterface(id),
1301                 // try this interface's versioned package next
1302                 Prefix::UnversionedInterface(id) => {
1303                     let iface = &resolve.interfaces[id];
1304                     let name = iface.name.as_ref().unwrap();
1305                     projection.push(to_rust_ident(name));
1306                     Prefix::VersionedPackage(iface.package.unwrap())
1307                 }
1308                 // try the unversioned package next
1309                 Prefix::VersionedPackage(id) => Prefix::UnversionedPackage(id),
1310                 // try this package's namespace next
1311                 Prefix::UnversionedPackage(id) => {
1312                     let name = &resolve.packages[id].name;
1313                     projection.push(to_rust_ident(&name.name));
1314                     Prefix::Namespace(id)
1315                 }
1316                 // nothing left to try any more
1317                 Prefix::Namespace(_) => return false,
1318             };
1319             true
1320         }
1321     }
1322 }
1323 
1324 impl Wasmtime {
1325     fn has_world_imports_trait(&self, resolve: &Resolve, world: WorldId) -> bool {
1326         !self.import_functions.is_empty() || get_world_resources(resolve, world).count() > 0
1327     }
1328 
1329     fn world_imports_trait(&mut self, resolve: &Resolve, world: WorldId) {
1330         if !self.has_world_imports_trait(resolve, world) {
1331             return;
1332         }
1333 
1334         let wt = self.wasmtime_path();
1335         let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1336         if self.opts.async_.maybe_async() {
1337             uwriteln!(self.src, "#[{wt}::component::__internal::async_trait]")
1338         }
1339         uwrite!(self.src, "pub trait {world_camel}Imports");
1340         let mut supertraits = vec![];
1341         if self.opts.async_.maybe_async() {
1342             supertraits.push("Send".to_string());
1343         }
1344         for resource in get_world_resources(resolve, world) {
1345             supertraits.push(format!("Host{}", resource.to_upper_camel_case()));
1346         }
1347         if !supertraits.is_empty() {
1348             uwrite!(self.src, ": {}", supertraits.join(" + "));
1349         }
1350         uwriteln!(self.src, " {{");
1351         for f in self.import_functions.iter() {
1352             if let Some(sig) = &f.sig {
1353                 self.src.push_str(sig);
1354                 self.src.push_str(";\n");
1355             }
1356         }
1357         uwriteln!(self.src, "}}");
1358 
1359         uwriteln!(
1360             self.src,
1361             "
1362                 pub trait {world_camel}ImportsGetHost<T>:
1363                     Fn(T) -> <Self as {world_camel}ImportsGetHost<T>>::Host
1364                         + Send
1365                         + Sync
1366                         + Copy
1367                         + 'static
1368                 {{
1369                     type Host: {world_camel}Imports;
1370                 }}
1371 
1372                 impl<F, T, O> {world_camel}ImportsGetHost<T> for F
1373                 where
1374                     F: Fn(T) -> O + Send + Sync + Copy + 'static,
1375                     O: {world_camel}Imports
1376                 {{
1377                     type Host = O;
1378                 }}
1379             "
1380         );
1381 
1382         // Generate impl WorldImports for &mut WorldImports
1383         let (async_trait, maybe_send) = if self.opts.async_.maybe_async() {
1384             (
1385                 format!("#[{wt}::component::__internal::async_trait]\n"),
1386                 "+ Send",
1387             )
1388         } else {
1389             (String::new(), "")
1390         };
1391         if !self.opts.skip_mut_forwarding_impls {
1392             uwriteln!(
1393                 self.src,
1394                 "{async_trait}impl<_T: {world_camel}Imports + ?Sized {maybe_send}> {world_camel}Imports for &mut _T {{"
1395             );
1396             // Forward each method call to &mut T
1397             for f in self.import_functions.iter() {
1398                 if let Some(sig) = &f.sig {
1399                     self.src.push_str(sig);
1400                     uwrite!(
1401                         self.src,
1402                         "{{ {world_camel}Imports::{}(*self,",
1403                         rust_function_name(&f.func)
1404                     );
1405                     for (name, _) in f.func.params.iter() {
1406                         uwrite!(self.src, "{},", to_rust_ident(name));
1407                     }
1408                     uwrite!(self.src, ")");
1409                     if self.opts.async_.is_import_async(&f.func.name) {
1410                         uwrite!(self.src, ".await");
1411                     }
1412                     uwriteln!(self.src, "}}");
1413                 }
1414             }
1415             uwriteln!(self.src, "}}");
1416         }
1417     }
1418 
1419     fn import_interface_paths(&self) -> Vec<String> {
1420         self.import_interfaces
1421             .iter()
1422             .map(|(_, name)| match name {
1423                 InterfaceName::Path(path) => path.join("::"),
1424                 InterfaceName::Remapped { name_at_root, .. } => name_at_root.clone(),
1425             })
1426             .collect()
1427     }
1428 
1429     fn world_host_traits(&self, resolve: &Resolve, world: WorldId) -> Vec<String> {
1430         let mut traits = self
1431             .import_interface_paths()
1432             .iter()
1433             .map(|path| format!("{path}::Host"))
1434             .collect::<Vec<_>>();
1435         if self.has_world_imports_trait(resolve, world) {
1436             let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1437             traits.push(format!("{world_camel}Imports"));
1438         }
1439         if self.opts.async_.maybe_async() {
1440             traits.push("Send".to_string());
1441         }
1442         traits
1443     }
1444 
1445     fn world_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) {
1446         let has_world_imports_trait = self.has_world_imports_trait(resolve, world);
1447         if self.import_interfaces.is_empty() && !has_world_imports_trait {
1448             return;
1449         }
1450 
1451         let camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
1452         let data_bounds = if self.opts.is_store_data_send() {
1453             "T: Send,"
1454         } else {
1455             ""
1456         };
1457         let wt = self.wasmtime_path();
1458         if has_world_imports_trait {
1459             uwrite!(
1460                 self.src,
1461                 "
1462                     pub fn add_to_linker_imports_get_host<T>(
1463                         linker: &mut {wt}::component::Linker<T>,
1464                         host_getter: impl for<'a> {camel}ImportsGetHost<&'a mut T>,
1465                     ) -> {wt}::Result<()>
1466                         where {data_bounds}
1467                     {{
1468                         let mut linker = linker.root();
1469                 "
1470             );
1471             for name in get_world_resources(resolve, world) {
1472                 Self::generate_add_resource_to_linker(
1473                     &mut self.src,
1474                     &self.opts,
1475                     &wt,
1476                     "linker",
1477                     name,
1478                 );
1479             }
1480             for f in self.import_functions.iter() {
1481                 self.src.push_str(&f.add_to_linker);
1482                 self.src.push_str("\n");
1483             }
1484             uwriteln!(self.src, "Ok(())\n}}");
1485         }
1486 
1487         let host_bounds = format!("U: {}", self.world_host_traits(resolve, world).join(" + "));
1488 
1489         if !self.opts.skip_mut_forwarding_impls {
1490             uwriteln!(
1491                 self.src,
1492                 "
1493                     pub fn add_to_linker<T, U>(
1494                         linker: &mut {wt}::component::Linker<T>,
1495                         get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
1496                     ) -> {wt}::Result<()>
1497                         where
1498                             {data_bounds}
1499                             {host_bounds}
1500                     {{
1501                 "
1502             );
1503             if has_world_imports_trait {
1504                 uwriteln!(
1505                     self.src,
1506                     "Self::add_to_linker_imports_get_host(linker, get)?;"
1507                 );
1508             }
1509             for path in self.import_interface_paths() {
1510                 uwriteln!(self.src, "{path}::add_to_linker(linker, get)?;");
1511             }
1512             uwriteln!(self.src, "Ok(())\n}}");
1513         }
1514     }
1515 
1516     fn generate_add_resource_to_linker(
1517         src: &mut Source,
1518         opts: &Opts,
1519         wt: &str,
1520         inst: &str,
1521         name: &str,
1522     ) {
1523         let camel = name.to_upper_camel_case();
1524         if opts.async_.is_drop_async(name) {
1525             uwriteln!(
1526                 src,
1527                 "{inst}.resource_async(
1528                     \"{name}\",
1529                     {wt}::component::ResourceType::host::<{camel}>(),
1530                     move |mut store, rep| {{
1531                         std::boxed::Box::new(async move {{
1532                             Host{camel}::drop(&mut host_getter(store.data_mut()), {wt}::component::Resource::new_own(rep)).await
1533                         }})
1534                     }},
1535                 )?;"
1536             )
1537         } else {
1538             uwriteln!(
1539                 src,
1540                 "{inst}.resource(
1541                     \"{name}\",
1542                     {wt}::component::ResourceType::host::<{camel}>(),
1543                     move |mut store, rep| -> {wt}::Result<()> {{
1544                         Host{camel}::drop(&mut host_getter(store.data_mut()), {wt}::component::Resource::new_own(rep))
1545                     }},
1546                 )?;"
1547             )
1548         }
1549     }
1550 }
1551 
1552 struct InterfaceGenerator<'a> {
1553     src: Source,
1554     gen: &'a mut Wasmtime,
1555     resolve: &'a Resolve,
1556     current_interface: Option<(InterfaceId, &'a WorldKey, bool)>,
1557 }
1558 
1559 impl<'a> InterfaceGenerator<'a> {
1560     fn new(gen: &'a mut Wasmtime, resolve: &'a Resolve) -> InterfaceGenerator<'a> {
1561         InterfaceGenerator {
1562             src: Source::default(),
1563             gen,
1564             resolve,
1565             current_interface: None,
1566         }
1567     }
1568 
1569     fn types_imported(&self) -> bool {
1570         match self.current_interface {
1571             Some((_, _, is_export)) => !is_export,
1572             None => true,
1573         }
1574     }
1575 
1576     fn types(&mut self, id: InterfaceId) {
1577         for (name, id) in self.resolve.interfaces[id].types.iter() {
1578             self.define_type(name, *id);
1579         }
1580     }
1581 
1582     fn define_type(&mut self, name: &str, id: TypeId) {
1583         let ty = &self.resolve.types[id];
1584         match &ty.kind {
1585             TypeDefKind::Record(record) => self.type_record(id, name, record, &ty.docs),
1586             TypeDefKind::Flags(flags) => self.type_flags(id, name, flags, &ty.docs),
1587             TypeDefKind::Tuple(tuple) => self.type_tuple(id, name, tuple, &ty.docs),
1588             TypeDefKind::Enum(enum_) => self.type_enum(id, name, enum_, &ty.docs),
1589             TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs),
1590             TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs),
1591             TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
1592             TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
1593             TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
1594             TypeDefKind::Future(_) => todo!("generate for future"),
1595             TypeDefKind::Stream(_) => todo!("generate for stream"),
1596             TypeDefKind::Handle(handle) => self.type_handle(id, name, handle, &ty.docs),
1597             TypeDefKind::Resource => self.type_resource(id, name, ty, &ty.docs),
1598             TypeDefKind::Unknown => unreachable!(),
1599         }
1600     }
1601 
1602     fn type_handle(&mut self, id: TypeId, name: &str, handle: &Handle, docs: &Docs) {
1603         self.rustdoc(docs);
1604         let name = name.to_upper_camel_case();
1605         uwriteln!(self.src, "pub type {name} = ");
1606         self.print_handle(handle);
1607         self.push_str(";\n");
1608         self.assert_type(id, &name);
1609     }
1610 
1611     fn type_resource(&mut self, id: TypeId, name: &str, resource: &TypeDef, docs: &Docs) {
1612         let camel = name.to_upper_camel_case();
1613         let wt = self.gen.wasmtime_path();
1614 
1615         if self.types_imported() {
1616             self.rustdoc(docs);
1617 
1618             let replacement = match self.current_interface {
1619                 Some((_, key, _)) => self.gen.lookup_replacement(self.resolve, key, Some(name)),
1620                 None => {
1621                     self.gen.used_with_opts.insert(name.into());
1622                     self.gen.opts.with.get(name).cloned()
1623                 }
1624             };
1625             match replacement {
1626                 Some(path) => {
1627                     uwriteln!(
1628                         self.src,
1629                         "pub use {}{path} as {camel};",
1630                         self.path_to_root()
1631                     );
1632                 }
1633                 None => {
1634                     uwriteln!(self.src, "pub enum {camel} {{}}");
1635                 }
1636             }
1637 
1638             // Generate resource trait
1639             if self.gen.opts.async_.maybe_async() {
1640                 uwriteln!(self.src, "#[{wt}::component::__internal::async_trait]")
1641             }
1642             uwriteln!(self.src, "pub trait Host{camel} {{");
1643 
1644             let mut functions = match resource.owner {
1645                 TypeOwner::World(id) => self.resolve.worlds[id]
1646                     .imports
1647                     .values()
1648                     .filter_map(|item| match item {
1649                         WorldItem::Function(f) => Some(f),
1650                         _ => None,
1651                     })
1652                     .collect(),
1653                 TypeOwner::Interface(id) => self.resolve.interfaces[id]
1654                     .functions
1655                     .values()
1656                     .collect::<Vec<_>>(),
1657                 TypeOwner::None => {
1658                     panic!("A resource must be owned by a world or interface");
1659                 }
1660             };
1661 
1662             functions.retain(|func| match func.kind {
1663                 FunctionKind::Freestanding => false,
1664                 FunctionKind::Method(resource)
1665                 | FunctionKind::Static(resource)
1666                 | FunctionKind::Constructor(resource) => id == resource,
1667             });
1668 
1669             for func in &functions {
1670                 self.generate_function_trait_sig(func);
1671                 self.push_str(";\n");
1672             }
1673 
1674             if self.gen.opts.async_.is_drop_async(name) {
1675                 uwrite!(self.src, "async ");
1676             }
1677             uwrite!(
1678                 self.src,
1679                 "fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()>;"
1680             );
1681 
1682             uwriteln!(self.src, "}}");
1683 
1684             // Generate impl HostResource for &mut HostResource
1685             if !self.gen.opts.skip_mut_forwarding_impls {
1686                 let (async_trait, maybe_send) = if self.gen.opts.async_.maybe_async() {
1687                     (
1688                         format!("#[{wt}::component::__internal::async_trait]\n"),
1689                         "+ Send",
1690                     )
1691                 } else {
1692                     (String::new(), "")
1693                 };
1694                 uwriteln!(
1695                     self.src,
1696                     "{async_trait}impl <_T: Host{camel} + ?Sized {maybe_send}> Host{camel} for &mut _T {{"
1697                 );
1698                 for func in &functions {
1699                     self.generate_function_trait_sig(func);
1700                     uwrite!(
1701                         self.src,
1702                         "{{ Host{camel}::{}(*self,",
1703                         rust_function_name(func)
1704                     );
1705                     for (name, _) in func.params.iter() {
1706                         uwrite!(self.src, "{},", to_rust_ident(name));
1707                     }
1708                     uwrite!(self.src, ")");
1709                     if self.gen.opts.async_.is_import_async(&func.name) {
1710                         uwrite!(self.src, ".await");
1711                     }
1712                     uwriteln!(self.src, "}}");
1713                 }
1714                 if self.gen.opts.async_.is_drop_async(name) {
1715                     uwriteln!(self.src, "
1716                         async fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()> {{
1717                             Host{camel}::drop(*self, rep).await
1718                         }}",
1719                     );
1720                 } else {
1721                     uwriteln!(self.src, "
1722                         fn drop(&mut self, rep: {wt}::component::Resource<{camel}>) -> {wt}::Result<()> {{
1723                             Host{camel}::drop(*self, rep)
1724                         }}",
1725                     );
1726                 }
1727                 uwriteln!(self.src, "}}");
1728             }
1729         } else {
1730             self.rustdoc(docs);
1731             uwriteln!(
1732                 self.src,
1733                 "
1734                     pub type {camel} = {wt}::component::ResourceAny;
1735 
1736                     pub struct Guest{camel}<'a> {{
1737                         funcs: &'a Guest,
1738                     }}
1739                 "
1740             );
1741         }
1742     }
1743 
1744     fn type_record(&mut self, id: TypeId, _name: &str, record: &Record, docs: &Docs) {
1745         let info = self.info(id);
1746         let wt = self.gen.wasmtime_path();
1747 
1748         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
1749         let additional_derives: BTreeSet<String> = self
1750             .gen
1751             .opts
1752             .additional_derive_attributes
1753             .iter()
1754             .cloned()
1755             .collect();
1756 
1757         for (name, mode) in self.modes_of(id) {
1758             let lt = self.lifetime_for(&info, mode);
1759             self.rustdoc(docs);
1760 
1761             let mut derives = additional_derives.clone();
1762 
1763             uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
1764             if lt.is_none() {
1765                 uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
1766             }
1767             uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
1768             self.push_str("#[component(record)]\n");
1769             if let Some(path) = &self.gen.opts.wasmtime_crate {
1770                 uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
1771             }
1772 
1773             if info.is_copy() {
1774                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
1775             } else if info.is_clone() {
1776                 derives.insert("Clone".to_string());
1777             }
1778 
1779             if !derives.is_empty() {
1780                 self.push_str("#[derive(");
1781                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
1782                 self.push_str(")]\n")
1783             }
1784 
1785             self.push_str(&format!("pub struct {name}"));
1786             self.print_generics(lt);
1787             self.push_str(" {\n");
1788             for field in record.fields.iter() {
1789                 self.rustdoc(&field.docs);
1790                 self.push_str(&format!("#[component(name = \"{}\")]\n", field.name));
1791                 self.push_str("pub ");
1792                 self.push_str(&to_rust_ident(&field.name));
1793                 self.push_str(": ");
1794                 self.print_ty(&field.ty, mode);
1795                 self.push_str(",\n");
1796             }
1797             self.push_str("}\n");
1798 
1799             self.push_str("impl");
1800             self.print_generics(lt);
1801             self.push_str(" core::fmt::Debug for ");
1802             self.push_str(&name);
1803             self.print_generics(lt);
1804             self.push_str(" {\n");
1805             self.push_str(
1806                 "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1807             );
1808             self.push_str(&format!("f.debug_struct(\"{name}\")"));
1809             for field in record.fields.iter() {
1810                 self.push_str(&format!(
1811                     ".field(\"{}\", &self.{})",
1812                     field.name,
1813                     to_rust_ident(&field.name)
1814                 ));
1815             }
1816             self.push_str(".finish()\n");
1817             self.push_str("}\n");
1818             self.push_str("}\n");
1819 
1820             if info.error {
1821                 self.push_str("impl");
1822                 self.print_generics(lt);
1823                 self.push_str(" core::fmt::Display for ");
1824                 self.push_str(&name);
1825                 self.print_generics(lt);
1826                 self.push_str(" {\n");
1827                 self.push_str(
1828                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
1829                 );
1830                 self.push_str("write!(f, \"{:?}\", self)\n");
1831                 self.push_str("}\n");
1832                 self.push_str("}\n");
1833 
1834                 if cfg!(feature = "std") {
1835                     self.push_str("impl std::error::Error for ");
1836                     self.push_str(&name);
1837                     self.push_str("{}\n");
1838                 }
1839             }
1840             self.assert_type(id, &name);
1841         }
1842     }
1843 
1844     fn type_tuple(&mut self, id: TypeId, _name: &str, tuple: &Tuple, docs: &Docs) {
1845         let info = self.info(id);
1846         for (name, mode) in self.modes_of(id) {
1847             let lt = self.lifetime_for(&info, mode);
1848             self.rustdoc(docs);
1849             self.push_str(&format!("pub type {name}"));
1850             self.print_generics(lt);
1851             self.push_str(" = (");
1852             for ty in tuple.types.iter() {
1853                 self.print_ty(ty, mode);
1854                 self.push_str(",");
1855             }
1856             self.push_str(");\n");
1857             self.assert_type(id, &name);
1858         }
1859     }
1860 
1861     fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs) {
1862         self.rustdoc(docs);
1863         let wt = self.gen.wasmtime_path();
1864         let rust_name = to_rust_upper_camel_case(name);
1865         uwriteln!(self.src, "{wt}::component::flags!(\n");
1866         self.src.push_str(&format!("{rust_name} {{\n"));
1867         for flag in flags.flags.iter() {
1868             // TODO wasmtime-component-macro doesn't support docs for flags rn
1869             uwrite!(
1870                 self.src,
1871                 "#[component(name=\"{}\")] const {};\n",
1872                 flag.name,
1873                 flag.name.to_shouty_snake_case()
1874             );
1875         }
1876         self.src.push_str("}\n");
1877         self.src.push_str(");\n\n");
1878         self.assert_type(id, &rust_name);
1879     }
1880 
1881     fn type_variant(&mut self, id: TypeId, _name: &str, variant: &Variant, docs: &Docs) {
1882         self.print_rust_enum(
1883             id,
1884             variant.cases.iter().map(|c| {
1885                 (
1886                     c.name.to_upper_camel_case(),
1887                     Some(c.name.clone()),
1888                     &c.docs,
1889                     c.ty.as_ref(),
1890                 )
1891             }),
1892             docs,
1893             "variant",
1894         );
1895     }
1896 
1897     fn type_option(&mut self, id: TypeId, _name: &str, payload: &Type, docs: &Docs) {
1898         let info = self.info(id);
1899 
1900         for (name, mode) in self.modes_of(id) {
1901             self.rustdoc(docs);
1902             let lt = self.lifetime_for(&info, mode);
1903             self.push_str(&format!("pub type {name}"));
1904             self.print_generics(lt);
1905             self.push_str("= Option<");
1906             self.print_ty(payload, mode);
1907             self.push_str(">;\n");
1908             self.assert_type(id, &name);
1909         }
1910     }
1911 
1912     // Emit a double-check that the wit-parser-understood size of a type agrees
1913     // with the Wasmtime-understood size of a type.
1914     fn assert_type(&mut self, id: TypeId, name: &str) {
1915         self.push_str("const _: () = {\n");
1916         let wt = self.gen.wasmtime_path();
1917         uwriteln!(
1918             self.src,
1919             "assert!({} == <{name} as {wt}::component::ComponentType>::SIZE32);",
1920             self.gen.sizes.size(&Type::Id(id)).size_wasm32(),
1921         );
1922         uwriteln!(
1923             self.src,
1924             "assert!({} == <{name} as {wt}::component::ComponentType>::ALIGN32);",
1925             self.gen.sizes.align(&Type::Id(id)).align_wasm32(),
1926         );
1927         self.push_str("};\n");
1928     }
1929 
1930     fn print_rust_enum<'b>(
1931         &mut self,
1932         id: TypeId,
1933         cases: impl IntoIterator<Item = (String, Option<String>, &'b Docs, Option<&'b Type>)> + Clone,
1934         docs: &Docs,
1935         derive_component: &str,
1936     ) where
1937         Self: Sized,
1938     {
1939         let info = self.info(id);
1940         let wt = self.gen.wasmtime_path();
1941 
1942         // We use a BTree set to make sure we don't have any duplicates and we have a stable order
1943         let additional_derives: BTreeSet<String> = self
1944             .gen
1945             .opts
1946             .additional_derive_attributes
1947             .iter()
1948             .cloned()
1949             .collect();
1950 
1951         for (name, mode) in self.modes_of(id) {
1952             let name = to_rust_upper_camel_case(&name);
1953 
1954             let mut derives = additional_derives.clone();
1955 
1956             self.rustdoc(docs);
1957             let lt = self.lifetime_for(&info, mode);
1958             uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
1959             if lt.is_none() {
1960                 uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
1961             }
1962             uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
1963             self.push_str(&format!("#[component({derive_component})]\n"));
1964             if let Some(path) = &self.gen.opts.wasmtime_crate {
1965                 uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
1966             }
1967             if info.is_copy() {
1968                 derives.extend(["Copy", "Clone"].into_iter().map(|s| s.to_string()));
1969             } else if info.is_clone() {
1970                 derives.insert("Clone".to_string());
1971             }
1972 
1973             if !derives.is_empty() {
1974                 self.push_str("#[derive(");
1975                 self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
1976                 self.push_str(")]\n")
1977             }
1978 
1979             self.push_str(&format!("pub enum {name}"));
1980             self.print_generics(lt);
1981             self.push_str("{\n");
1982             for (case_name, component_name, docs, payload) in cases.clone() {
1983                 self.rustdoc(docs);
1984                 if let Some(n) = component_name {
1985                     self.push_str(&format!("#[component(name = \"{n}\")] "));
1986                 }
1987                 self.push_str(&case_name);
1988                 if let Some(ty) = payload {
1989                     self.push_str("(");
1990                     self.print_ty(ty, mode);
1991                     self.push_str(")")
1992                 }
1993                 self.push_str(",\n");
1994             }
1995             self.push_str("}\n");
1996 
1997             self.print_rust_enum_debug(
1998                 id,
1999                 mode,
2000                 &name,
2001                 cases
2002                     .clone()
2003                     .into_iter()
2004                     .map(|(name, _attr, _docs, ty)| (name, ty)),
2005             );
2006 
2007             if info.error {
2008                 self.push_str("impl");
2009                 self.print_generics(lt);
2010                 self.push_str(" core::fmt::Display for ");
2011                 self.push_str(&name);
2012                 self.print_generics(lt);
2013                 self.push_str(" {\n");
2014                 self.push_str(
2015                     "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2016                 );
2017                 self.push_str("write!(f, \"{:?}\", self)");
2018                 self.push_str("}\n");
2019                 self.push_str("}\n");
2020                 self.push_str("\n");
2021 
2022                 if cfg!(feature = "std") {
2023                     self.push_str("impl");
2024                     self.print_generics(lt);
2025                     self.push_str(" std::error::Error for ");
2026                     self.push_str(&name);
2027                     self.print_generics(lt);
2028                     self.push_str(" {}\n");
2029                 }
2030             }
2031 
2032             self.assert_type(id, &name);
2033         }
2034     }
2035 
2036     fn print_rust_enum_debug<'b>(
2037         &mut self,
2038         id: TypeId,
2039         mode: TypeMode,
2040         name: &str,
2041         cases: impl IntoIterator<Item = (String, Option<&'b Type>)>,
2042     ) where
2043         Self: Sized,
2044     {
2045         let info = self.info(id);
2046         let lt = self.lifetime_for(&info, mode);
2047         self.push_str("impl");
2048         self.print_generics(lt);
2049         self.push_str(" core::fmt::Debug for ");
2050         self.push_str(name);
2051         self.print_generics(lt);
2052         self.push_str(" {\n");
2053         self.push_str("fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
2054         self.push_str("match self {\n");
2055         for (case_name, payload) in cases {
2056             self.push_str(name);
2057             self.push_str("::");
2058             self.push_str(&case_name);
2059             if payload.is_some() {
2060                 self.push_str("(e)");
2061             }
2062             self.push_str(" => {\n");
2063             self.push_str(&format!("f.debug_tuple(\"{name}::{case_name}\")"));
2064             if payload.is_some() {
2065                 self.push_str(".field(e)");
2066             }
2067             self.push_str(".finish()\n");
2068             self.push_str("}\n");
2069         }
2070         self.push_str("}\n");
2071         self.push_str("}\n");
2072         self.push_str("}\n");
2073     }
2074 
2075     fn type_result(&mut self, id: TypeId, _name: &str, result: &Result_, docs: &Docs) {
2076         let info = self.info(id);
2077 
2078         for (name, mode) in self.modes_of(id) {
2079             self.rustdoc(docs);
2080             let lt = self.lifetime_for(&info, mode);
2081             self.push_str(&format!("pub type {name}"));
2082             self.print_generics(lt);
2083             self.push_str("= Result<");
2084             self.print_optional_ty(result.ok.as_ref(), mode);
2085             self.push_str(",");
2086             self.print_optional_ty(result.err.as_ref(), mode);
2087             self.push_str(">;\n");
2088             self.assert_type(id, &name);
2089         }
2090     }
2091 
2092     fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
2093         let info = self.info(id);
2094         let wt = self.gen.wasmtime_path();
2095 
2096         // We use a BTree set to make sure we don't have any duplicates and have a stable order
2097         let mut derives: BTreeSet<String> = self
2098             .gen
2099             .opts
2100             .additional_derive_attributes
2101             .iter()
2102             .cloned()
2103             .collect();
2104 
2105         derives.extend(
2106             ["Clone", "Copy", "PartialEq", "Eq"]
2107                 .into_iter()
2108                 .map(|s| s.to_string()),
2109         );
2110 
2111         let name = to_rust_upper_camel_case(name);
2112         self.rustdoc(docs);
2113         uwriteln!(self.src, "#[derive({wt}::component::ComponentType)]");
2114         uwriteln!(self.src, "#[derive({wt}::component::Lift)]");
2115         uwriteln!(self.src, "#[derive({wt}::component::Lower)]");
2116         self.push_str("#[component(enum)]\n");
2117         if let Some(path) = &self.gen.opts.wasmtime_crate {
2118             uwriteln!(self.src, "#[component(wasmtime_crate = {path})]\n");
2119         }
2120 
2121         self.push_str("#[derive(");
2122         self.push_str(&derives.into_iter().collect::<Vec<_>>().join(", "));
2123         self.push_str(")]\n");
2124 
2125         let repr = match enum_.cases.len().ilog2() {
2126             0..=7 => "u8",
2127             8..=15 => "u16",
2128             _ => "u32",
2129         };
2130         uwriteln!(self.src, "#[repr({repr})]");
2131 
2132         self.push_str(&format!("pub enum {name} {{\n"));
2133         for case in enum_.cases.iter() {
2134             self.rustdoc(&case.docs);
2135             self.push_str(&format!("#[component(name = \"{}\")]", case.name));
2136             self.push_str(&case.name.to_upper_camel_case());
2137             self.push_str(",\n");
2138         }
2139         self.push_str("}\n");
2140 
2141         // Auto-synthesize an implementation of the standard `Error` trait for
2142         // error-looking types based on their name.
2143         if info.error {
2144             self.push_str("impl ");
2145             self.push_str(&name);
2146             self.push_str("{\n");
2147 
2148             self.push_str("pub fn name(&self) -> &'static str {\n");
2149             self.push_str("match self {\n");
2150             for case in enum_.cases.iter() {
2151                 self.push_str(&name);
2152                 self.push_str("::");
2153                 self.push_str(&case.name.to_upper_camel_case());
2154                 self.push_str(" => \"");
2155                 self.push_str(case.name.as_str());
2156                 self.push_str("\",\n");
2157             }
2158             self.push_str("}\n");
2159             self.push_str("}\n");
2160 
2161             self.push_str("pub fn message(&self) -> &'static str {\n");
2162             self.push_str("match self {\n");
2163             for case in enum_.cases.iter() {
2164                 self.push_str(&name);
2165                 self.push_str("::");
2166                 self.push_str(&case.name.to_upper_camel_case());
2167                 self.push_str(" => \"");
2168                 if let Some(contents) = &case.docs.contents {
2169                     self.push_str(contents.trim());
2170                 }
2171                 self.push_str("\",\n");
2172             }
2173             self.push_str("}\n");
2174             self.push_str("}\n");
2175 
2176             self.push_str("}\n");
2177 
2178             self.push_str("impl core::fmt::Debug for ");
2179             self.push_str(&name);
2180             self.push_str(
2181                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2182             );
2183             self.push_str("f.debug_struct(\"");
2184             self.push_str(&name);
2185             self.push_str("\")\n");
2186             self.push_str(".field(\"code\", &(*self as i32))\n");
2187             self.push_str(".field(\"name\", &self.name())\n");
2188             self.push_str(".field(\"message\", &self.message())\n");
2189             self.push_str(".finish()\n");
2190             self.push_str("}\n");
2191             self.push_str("}\n");
2192 
2193             self.push_str("impl core::fmt::Display for ");
2194             self.push_str(&name);
2195             self.push_str(
2196                 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
2197             );
2198             self.push_str("write!(f, \"{} (error {})\", self.name(), *self as i32)");
2199             self.push_str("}\n");
2200             self.push_str("}\n");
2201             self.push_str("\n");
2202             if cfg!(feature = "std") {
2203                 self.push_str("impl std::error::Error for ");
2204                 self.push_str(&name);
2205                 self.push_str("{}\n");
2206             }
2207         } else {
2208             self.print_rust_enum_debug(
2209                 id,
2210                 TypeMode::Owned,
2211                 &name,
2212                 enum_
2213                     .cases
2214                     .iter()
2215                     .map(|c| (c.name.to_upper_camel_case(), None)),
2216             )
2217         }
2218         self.assert_type(id, &name);
2219     }
2220 
2221     fn type_alias(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
2222         let info = self.info(id);
2223         for (name, mode) in self.modes_of(id) {
2224             self.rustdoc(docs);
2225             self.push_str(&format!("pub type {name}"));
2226             let lt = self.lifetime_for(&info, mode);
2227             self.print_generics(lt);
2228             self.push_str(" = ");
2229             self.print_ty(ty, mode);
2230             self.push_str(";\n");
2231             let def_id = resolve_type_definition_id(self.resolve, id);
2232             if !matches!(self.resolve().types[def_id].kind, TypeDefKind::Resource) {
2233                 self.assert_type(id, &name);
2234             }
2235         }
2236     }
2237 
2238     fn type_list(&mut self, id: TypeId, _name: &str, ty: &Type, docs: &Docs) {
2239         let info = self.info(id);
2240         for (name, mode) in self.modes_of(id) {
2241             let lt = self.lifetime_for(&info, mode);
2242             self.rustdoc(docs);
2243             self.push_str(&format!("pub type {name}"));
2244             self.print_generics(lt);
2245             self.push_str(" = ");
2246             self.print_list(ty, mode);
2247             self.push_str(";\n");
2248             self.assert_type(id, &name);
2249         }
2250     }
2251 
2252     fn print_result_ty(&mut self, results: &Results, mode: TypeMode) {
2253         match results {
2254             Results::Named(rs) => match rs.len() {
2255                 0 => self.push_str("()"),
2256                 1 => self.print_ty(&rs[0].1, mode),
2257                 _ => {
2258                     self.push_str("(");
2259                     for (i, (_, ty)) in rs.iter().enumerate() {
2260                         if i > 0 {
2261                             self.push_str(", ")
2262                         }
2263                         self.print_ty(ty, mode)
2264                     }
2265                     self.push_str(")");
2266                 }
2267             },
2268             Results::Anon(ty) => self.print_ty(ty, mode),
2269         }
2270     }
2271 
2272     fn special_case_trappable_error(
2273         &mut self,
2274         func: &Function,
2275     ) -> Option<(&'a Result_, TypeId, String)> {
2276         let results = &func.results;
2277 
2278         self.gen
2279             .used_trappable_imports_opts
2280             .insert(func.name.clone());
2281 
2282         // We fillin a special trappable error type in the case when a function has just one
2283         // result, which is itself a `result<a, e>`, and the `e` is *not* a primitive
2284         // (i.e. defined in std) type, and matches the typename given by the user.
2285         let mut i = results.iter_types();
2286         let id = match i.next()? {
2287             Type::Id(id) => id,
2288             _ => return None,
2289         };
2290         if i.next().is_some() {
2291             return None;
2292         }
2293         let result = match &self.resolve.types[*id].kind {
2294             TypeDefKind::Result(r) => r,
2295             _ => return None,
2296         };
2297         let error_typeid = match result.err? {
2298             Type::Id(id) => resolve_type_definition_id(&self.resolve, id),
2299             _ => return None,
2300         };
2301 
2302         let name = self.gen.trappable_errors.get(&error_typeid)?;
2303 
2304         let mut path = self.path_to_root();
2305         uwrite!(path, "{name}");
2306         Some((result, error_typeid, path))
2307     }
2308 
2309     fn generate_add_to_linker(&mut self, id: InterfaceId, name: &str) {
2310         let iface = &self.resolve.interfaces[id];
2311         let owner = TypeOwner::Interface(id);
2312         let wt = self.gen.wasmtime_path();
2313 
2314         let is_maybe_async = self.gen.opts.async_.maybe_async();
2315         if is_maybe_async {
2316             uwriteln!(self.src, "#[{wt}::component::__internal::async_trait]")
2317         }
2318         // Generate the `pub trait` which represents the host functionality for
2319         // this import which additionally inherits from all resource traits
2320         // for this interface defined by `type_resource`.
2321         uwrite!(self.src, "pub trait Host");
2322         let mut host_supertraits = vec![];
2323         if is_maybe_async {
2324             host_supertraits.push("Send".to_string());
2325         }
2326         for resource in get_resources(self.resolve, id) {
2327             host_supertraits.push(format!("Host{}", resource.to_upper_camel_case()));
2328         }
2329         if !host_supertraits.is_empty() {
2330             uwrite!(self.src, ": {}", host_supertraits.join(" + "));
2331         }
2332         uwriteln!(self.src, " {{");
2333         for (_, func) in iface.functions.iter() {
2334             match func.kind {
2335                 FunctionKind::Freestanding => {}
2336                 _ => continue,
2337             }
2338             self.generate_function_trait_sig(func);
2339             self.push_str(";\n");
2340         }
2341 
2342         // Generate `convert_*` functions to convert custom trappable errors
2343         // into the representation required by Wasmtime's component API.
2344         let mut required_conversion_traits = IndexSet::new();
2345         let mut errors_converted = IndexMap::new();
2346         let mut my_error_types = iface
2347             .types
2348             .iter()
2349             .filter(|(_, id)| self.gen.trappable_errors.contains_key(*id))
2350             .map(|(_, id)| *id)
2351             .collect::<Vec<_>>();
2352         my_error_types.extend(
2353             iface
2354                 .functions
2355                 .iter()
2356                 .filter_map(|(_, func)| self.special_case_trappable_error(func))
2357                 .map(|(_, id, _)| id),
2358         );
2359         let root = self.path_to_root();
2360         for err_id in my_error_types {
2361             let custom_name = &self.gen.trappable_errors[&err_id];
2362             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err_id)];
2363             let err_name = err.name.as_ref().unwrap();
2364             let err_snake = err_name.to_snake_case();
2365             let err_camel = err_name.to_upper_camel_case();
2366             let owner = match err.owner {
2367                 TypeOwner::Interface(i) => i,
2368                 _ => unimplemented!(),
2369             };
2370             match self.path_to_interface(owner) {
2371                 Some(path) => {
2372                     required_conversion_traits.insert(format!("{path}::Host"));
2373                 }
2374                 None => {
2375                     if errors_converted.insert(err_name, err_id).is_none() {
2376                         uwriteln!(
2377                             self.src,
2378                             "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> {wt}::Result<{err_camel}>;"
2379                         );
2380                     }
2381                 }
2382             }
2383         }
2384         uwriteln!(self.src, "}}");
2385 
2386         let (data_bounds, mut host_bounds) = if self.gen.opts.is_store_data_send() {
2387             ("T: Send,", "Host + Send".to_string())
2388         } else {
2389             ("", "Host".to_string())
2390         };
2391         for ty in required_conversion_traits {
2392             uwrite!(host_bounds, " + {ty}");
2393         }
2394 
2395         uwriteln!(
2396             self.src,
2397             "
2398                 pub trait GetHost<T>:
2399                     Fn(T) -> <Self as GetHost<T>>::Host
2400                         + Send
2401                         + Sync
2402                         + Copy
2403                         + 'static
2404                 {{
2405                     type Host: {host_bounds};
2406                 }}
2407 
2408                 impl<F, T, O> GetHost<T> for F
2409                 where
2410                     F: Fn(T) -> O + Send + Sync + Copy + 'static,
2411                     O: {host_bounds},
2412                 {{
2413                     type Host = O;
2414                 }}
2415 
2416                 pub fn add_to_linker_get_host<T>(
2417                     linker: &mut {wt}::component::Linker<T>,
2418                     host_getter: impl for<'a> GetHost<&'a mut T>,
2419                 ) -> {wt}::Result<()>
2420                     where {data_bounds}
2421                 {{
2422             "
2423         );
2424         uwriteln!(self.src, "let mut inst = linker.instance(\"{name}\")?;");
2425 
2426         for name in get_resources(self.resolve, id) {
2427             Wasmtime::generate_add_resource_to_linker(
2428                 &mut self.src,
2429                 &self.gen.opts,
2430                 &wt,
2431                 "inst",
2432                 name,
2433             );
2434         }
2435 
2436         for (_, func) in iface.functions.iter() {
2437             self.generate_add_function_to_linker(owner, func, "inst");
2438         }
2439         uwriteln!(self.src, "Ok(())");
2440         uwriteln!(self.src, "}}");
2441 
2442         if !self.gen.opts.skip_mut_forwarding_impls {
2443             // Generate add_to_linker (with closure)
2444             uwriteln!(
2445                 self.src,
2446                 "
2447                 pub fn add_to_linker<T, U>(
2448                     linker: &mut {wt}::component::Linker<T>,
2449                     get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static,
2450                 ) -> {wt}::Result<()>
2451                     where
2452                         U: {host_bounds}, {data_bounds}
2453                 {{
2454                     add_to_linker_get_host(linker, get)
2455                 }}
2456                 "
2457             );
2458 
2459             // Generate impl Host for &mut Host
2460             let (async_trait, maybe_send) = if is_maybe_async {
2461                 (
2462                     format!("#[{wt}::component::__internal::async_trait]"),
2463                     "+ Send",
2464                 )
2465             } else {
2466                 (String::new(), "")
2467             };
2468 
2469             uwriteln!(
2470                 self.src,
2471                 "{async_trait}impl<_T: Host + ?Sized {maybe_send}> Host for &mut _T {{"
2472             );
2473             // Forward each method call to &mut T
2474             for (_, func) in iface.functions.iter() {
2475                 match func.kind {
2476                     FunctionKind::Freestanding => {}
2477                     _ => continue,
2478                 }
2479                 self.generate_function_trait_sig(func);
2480                 uwrite!(self.src, "{{ Host::{}(*self,", rust_function_name(func));
2481                 for (name, _) in func.params.iter() {
2482                     uwrite!(self.src, "{},", to_rust_ident(name));
2483                 }
2484                 uwrite!(self.src, ")");
2485                 if self.gen.opts.async_.is_import_async(&func.name) {
2486                     uwrite!(self.src, ".await");
2487                 }
2488                 uwriteln!(self.src, "}}");
2489             }
2490             for (err_name, err_id) in errors_converted {
2491                 uwriteln!(
2492                     self.src,
2493                     "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> {wt}::Result<{err_camel}> {{
2494                         Host::convert_{err_snake}(*self, err)
2495                     }}",
2496                     custom_name = self.gen.trappable_errors[&err_id],
2497                     err_snake = err_name.to_snake_case(),
2498                     err_camel = err_name.to_upper_camel_case(),
2499                 );
2500             }
2501             uwriteln!(self.src, "}}");
2502         }
2503     }
2504 
2505     fn generate_add_function_to_linker(&mut self, owner: TypeOwner, func: &Function, linker: &str) {
2506         uwrite!(
2507             self.src,
2508             "{linker}.{}(\"{}\", ",
2509             if self.gen.opts.async_.is_import_async(&func.name) {
2510                 "func_wrap_async"
2511             } else {
2512                 "func_wrap"
2513             },
2514             func.name
2515         );
2516         self.generate_guest_import_closure(owner, func);
2517         uwriteln!(self.src, ")?;")
2518     }
2519 
2520     fn generate_guest_import_closure(&mut self, owner: TypeOwner, func: &Function) {
2521         // Generate the closure that's passed to a `Linker`, the final piece of
2522         // codegen here.
2523 
2524         let wt = self.gen.wasmtime_path();
2525         uwrite!(
2526             self.src,
2527             "move |mut caller: {wt}::StoreContextMut<'_, T>, ("
2528         );
2529         for (i, _param) in func.params.iter().enumerate() {
2530             uwrite!(self.src, "arg{},", i);
2531         }
2532         self.src.push_str(") : (");
2533 
2534         for (_, ty) in func.params.iter() {
2535             // Lift is required to be impled for this type, so we can't use
2536             // a borrowed type:
2537             self.print_ty(ty, TypeMode::Owned);
2538             self.src.push_str(", ");
2539         }
2540         self.src.push_str(") |");
2541         self.src.push_str(" {\n");
2542 
2543         if self.gen.opts.tracing {
2544             if self.gen.opts.async_.is_import_async(&func.name) {
2545                 self.src.push_str("use tracing::Instrument;\n");
2546             }
2547 
2548             uwrite!(
2549                 self.src,
2550                 "
2551                    let span = tracing::span!(
2552                        tracing::Level::TRACE,
2553                        \"wit-bindgen import\",
2554                        module = \"{}\",
2555                        function = \"{}\",
2556                    );
2557                ",
2558                 match owner {
2559                     TypeOwner::Interface(id) => self.resolve.interfaces[id]
2560                         .name
2561                         .as_deref()
2562                         .unwrap_or("<no module>"),
2563                     TypeOwner::World(id) => &self.resolve.worlds[id].name,
2564                     TypeOwner::None => "<no owner>",
2565                 },
2566                 func.name,
2567             );
2568         }
2569 
2570         if self.gen.opts.async_.is_import_async(&func.name) {
2571             uwriteln!(
2572                 self.src,
2573                 " {wt}::component::__internal::Box::new(async move {{ "
2574             );
2575         } else {
2576             // Only directly enter the span if the function is sync. Otherwise
2577             // we use tracing::Instrument to ensure that the span is not entered
2578             // across an await point.
2579             if self.gen.opts.tracing {
2580                 self.push_str("let _enter = span.enter();\n");
2581             }
2582         }
2583 
2584         if self.gen.opts.tracing {
2585             let mut event_fields = func
2586                 .params
2587                 .iter()
2588                 .enumerate()
2589                 .map(|(i, (name, ty))| {
2590                     let name = to_rust_ident(&name);
2591                     formatting_for_arg(&name, i, *ty, &self.gen.opts, &self.resolve)
2592                 })
2593                 .collect::<Vec<String>>();
2594             event_fields.push(format!("\"call\""));
2595             uwrite!(
2596                 self.src,
2597                 "tracing::event!(tracing::Level::TRACE, {});\n",
2598                 event_fields.join(", ")
2599             );
2600         }
2601 
2602         self.src
2603             .push_str("let host = &mut host_getter(caller.data_mut());\n");
2604         let func_name = rust_function_name(func);
2605         let host_trait = match func.kind {
2606             FunctionKind::Freestanding => match owner {
2607                 TypeOwner::World(id) => format!(
2608                     "{}Imports",
2609                     rust::to_rust_upper_camel_case(&self.resolve.worlds[id].name)
2610                 ),
2611                 _ => "Host".to_string(),
2612             },
2613             FunctionKind::Method(id) | FunctionKind::Static(id) | FunctionKind::Constructor(id) => {
2614                 let resource = self.resolve.types[id]
2615                     .name
2616                     .as_ref()
2617                     .unwrap()
2618                     .to_upper_camel_case();
2619                 format!("Host{resource}")
2620             }
2621         };
2622         uwrite!(self.src, "let r = {host_trait}::{func_name}(host, ");
2623 
2624         for (i, _) in func.params.iter().enumerate() {
2625             uwrite!(self.src, "arg{},", i);
2626         }
2627         if self.gen.opts.async_.is_import_async(&func.name) {
2628             uwrite!(self.src, ").await;\n");
2629         } else {
2630             uwrite!(self.src, ");\n");
2631         }
2632 
2633         if self.gen.opts.tracing {
2634             uwrite!(
2635                 self.src,
2636                 "tracing::event!(tracing::Level::TRACE, {}, \"return\");",
2637                 formatting_for_results(&func.results, &self.gen.opts, &self.resolve)
2638             );
2639         }
2640 
2641         if !self.gen.opts.trappable_imports.can_trap(&func) {
2642             if func.results.iter_types().len() == 1 {
2643                 uwrite!(self.src, "Ok((r,))\n");
2644             } else {
2645                 uwrite!(self.src, "Ok(r)\n");
2646             }
2647         } else if let Some((_, err, _)) = self.special_case_trappable_error(func) {
2648             let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err)];
2649             let err_name = err.name.as_ref().unwrap();
2650             let owner = match err.owner {
2651                 TypeOwner::Interface(i) => i,
2652                 _ => unimplemented!(),
2653             };
2654             let convert_trait = match self.path_to_interface(owner) {
2655                 Some(path) => format!("{path}::Host"),
2656                 None => format!("Host"),
2657             };
2658             let convert = format!("{}::convert_{}", convert_trait, err_name.to_snake_case());
2659             uwrite!(
2660                 self.src,
2661                 "Ok((match r {{
2662                     Ok(a) => Ok(a),
2663                     Err(e) => Err({convert}(host, e)?),
2664                 }},))"
2665             );
2666         } else if func.results.iter_types().len() == 1 {
2667             uwrite!(self.src, "Ok((r?,))\n");
2668         } else {
2669             uwrite!(self.src, "r\n");
2670         }
2671 
2672         if self.gen.opts.async_.is_import_async(&func.name) {
2673             // Need to close Box::new and async block
2674 
2675             if self.gen.opts.tracing {
2676                 self.src.push_str("}.instrument(span))\n");
2677             } else {
2678                 self.src.push_str("})\n");
2679             }
2680         }
2681 
2682         self.src.push_str("}\n");
2683     }
2684 
2685     fn generate_function_trait_sig(&mut self, func: &Function) {
2686         let wt = self.gen.wasmtime_path();
2687         self.rustdoc(&func.docs);
2688 
2689         if self.gen.opts.async_.is_import_async(&func.name) {
2690             self.push_str("async ");
2691         }
2692         self.push_str("fn ");
2693         self.push_str(&rust_function_name(func));
2694         self.push_str("(&mut self, ");
2695         for (name, param) in func.params.iter() {
2696             let name = to_rust_ident(name);
2697             self.push_str(&name);
2698             self.push_str(": ");
2699             self.print_ty(param, TypeMode::Owned);
2700             self.push_str(",");
2701         }
2702         self.push_str(")");
2703         self.push_str(" -> ");
2704 
2705         if !self.gen.opts.trappable_imports.can_trap(func) {
2706             self.print_result_ty(&func.results, TypeMode::Owned);
2707         } else if let Some((r, _id, error_typename)) = self.special_case_trappable_error(func) {
2708             // Functions which have a single result `result<ok,err>` get special
2709             // cased to use the host_wasmtime_rust::Error<err>, making it possible
2710             // for them to trap or use `?` to propagate their errors
2711             self.push_str("Result<");
2712             if let Some(ok) = r.ok {
2713                 self.print_ty(&ok, TypeMode::Owned);
2714             } else {
2715                 self.push_str("()");
2716             }
2717             self.push_str(",");
2718             self.push_str(&error_typename);
2719             self.push_str(">");
2720         } else {
2721             // All other functions get their return values wrapped in an wasmtime::Result.
2722             // Returning the anyhow::Error case can be used to trap.
2723             uwrite!(self.src, "{wt}::Result<");
2724             self.print_result_ty(&func.results, TypeMode::Owned);
2725             self.push_str(">");
2726         }
2727     }
2728 
2729     fn extract_typed_function(&mut self, func: &Function) -> (String, String) {
2730         let prev = mem::take(&mut self.src);
2731         let snake = func_field_name(self.resolve, func);
2732         uwrite!(self.src, "*_instance.get_typed_func::<(");
2733         for (_, ty) in func.params.iter() {
2734             self.print_ty(ty, TypeMode::AllBorrowed("'_"));
2735             self.push_str(", ");
2736         }
2737         self.src.push_str("), (");
2738         for ty in func.results.iter_types() {
2739             self.print_ty(ty, TypeMode::Owned);
2740             self.push_str(", ");
2741         }
2742         uwriteln!(self.src, ")>(&mut store, &self.{snake})?.func()");
2743 
2744         let ret = (snake, mem::take(&mut self.src).to_string());
2745         self.src = prev;
2746         ret
2747     }
2748 
2749     fn define_rust_guest_export(
2750         &mut self,
2751         resolve: &Resolve,
2752         ns: Option<&WorldKey>,
2753         func: &Function,
2754     ) {
2755         // Exports must be async if anything could be async, it's just imports
2756         // that get to be optionally async/sync.
2757         let is_async = self.gen.opts.async_.maybe_async();
2758 
2759         let (async_, async__, await_) = if is_async {
2760             ("async", "_async", ".await")
2761         } else {
2762             ("", "", "")
2763         };
2764 
2765         self.rustdoc(&func.docs);
2766         let wt = self.gen.wasmtime_path();
2767 
2768         uwrite!(
2769             self.src,
2770             "pub {async_} fn call_{}<S: {wt}::AsContextMut>(&self, mut store: S, ",
2771             func.item_name().to_snake_case(),
2772         );
2773 
2774         for (i, param) in func.params.iter().enumerate() {
2775             uwrite!(self.src, "arg{}: ", i);
2776             self.print_ty(&param.1, TypeMode::AllBorrowed("'_"));
2777             self.push_str(",");
2778         }
2779 
2780         uwrite!(self.src, ") -> {wt}::Result<");
2781         self.print_result_ty(&func.results, TypeMode::Owned);
2782 
2783         if is_async {
2784             uwriteln!(self.src, "> where <S as {wt}::AsContext>::Data: Send {{");
2785         } else {
2786             self.src.push_str("> {\n");
2787         }
2788 
2789         if self.gen.opts.tracing {
2790             if is_async {
2791                 self.src.push_str("use tracing::Instrument;\n");
2792             }
2793 
2794             let ns = match ns {
2795                 Some(key) => resolve.name_world_key(key),
2796                 None => "default".to_string(),
2797             };
2798             self.src.push_str(&format!(
2799                 "
2800                    let span = tracing::span!(
2801                        tracing::Level::TRACE,
2802                        \"wit-bindgen export\",
2803                        module = \"{ns}\",
2804                        function = \"{}\",
2805                    );
2806                ",
2807                 func.name,
2808             ));
2809 
2810             if !is_async {
2811                 self.src.push_str(
2812                     "
2813                    let _enter = span.enter();
2814                    ",
2815                 );
2816             }
2817         }
2818 
2819         self.src.push_str("let callee = unsafe {\n");
2820         uwrite!(self.src, "{wt}::component::TypedFunc::<(");
2821         for (_, ty) in func.params.iter() {
2822             self.print_ty(ty, TypeMode::AllBorrowed("'_"));
2823             self.push_str(", ");
2824         }
2825         self.src.push_str("), (");
2826         for ty in func.results.iter_types() {
2827             self.print_ty(ty, TypeMode::Owned);
2828             self.push_str(", ");
2829         }
2830         let projection_to_func = match &func.kind {
2831             FunctionKind::Freestanding => "",
2832             _ => ".funcs",
2833         };
2834         uwriteln!(
2835             self.src,
2836             ")>::new_unchecked(self{projection_to_func}.{})",
2837             func_field_name(self.resolve, func),
2838         );
2839         self.src.push_str("};\n");
2840         self.src.push_str("let (");
2841         for (i, _) in func.results.iter_types().enumerate() {
2842             uwrite!(self.src, "ret{},", i);
2843         }
2844         uwrite!(
2845             self.src,
2846             ") = callee.call{async__}(store.as_context_mut(), ("
2847         );
2848         for (i, _) in func.params.iter().enumerate() {
2849             uwrite!(self.src, "arg{}, ", i);
2850         }
2851 
2852         let instrument = if is_async && self.gen.opts.tracing {
2853             ".instrument(span.clone())"
2854         } else {
2855             ""
2856         };
2857         uwriteln!(self.src, ")){instrument}{await_}?;");
2858 
2859         let instrument = if is_async && self.gen.opts.tracing {
2860             ".instrument(span)"
2861         } else {
2862             ""
2863         };
2864         uwriteln!(
2865             self.src,
2866             "callee.post_return{async__}(store.as_context_mut()){instrument}{await_}?;"
2867         );
2868 
2869         self.src.push_str("Ok(");
2870         if func.results.iter_types().len() == 1 {
2871             self.src.push_str("ret0");
2872         } else {
2873             self.src.push_str("(");
2874             for (i, _) in func.results.iter_types().enumerate() {
2875                 uwrite!(self.src, "ret{},", i);
2876             }
2877             self.src.push_str(")");
2878         }
2879         self.src.push_str(")\n");
2880 
2881         // End function body
2882         self.src.push_str("}\n");
2883     }
2884 
2885     fn rustdoc(&mut self, docs: &Docs) {
2886         let docs = match &docs.contents {
2887             Some(docs) => docs,
2888             None => return,
2889         };
2890         for line in docs.trim().lines() {
2891             self.push_str("/// ");
2892             self.push_str(line);
2893             self.push_str("\n");
2894         }
2895     }
2896 
2897     fn path_to_root(&self) -> String {
2898         let mut path_to_root = String::new();
2899         if let Some((_, key, is_export)) = self.current_interface {
2900             match key {
2901                 WorldKey::Name(_) => {
2902                     path_to_root.push_str("super::");
2903                 }
2904                 WorldKey::Interface(_) => {
2905                     path_to_root.push_str("super::super::super::");
2906                 }
2907             }
2908             if is_export {
2909                 path_to_root.push_str("super::");
2910             }
2911         }
2912         path_to_root
2913     }
2914 }
2915 
2916 impl<'a> RustGenerator<'a> for InterfaceGenerator<'a> {
2917     fn resolve(&self) -> &'a Resolve {
2918         self.resolve
2919     }
2920 
2921     fn ownership(&self) -> Ownership {
2922         self.gen.opts.ownership
2923     }
2924 
2925     fn path_to_interface(&self, interface: InterfaceId) -> Option<String> {
2926         if let Some((cur, _, _)) = self.current_interface {
2927             if cur == interface {
2928                 return None;
2929             }
2930         }
2931         let mut path_to_root = self.path_to_root();
2932         match &self.gen.interface_names[&interface] {
2933             InterfaceName::Remapped { name_at_root, .. } => path_to_root.push_str(name_at_root),
2934             InterfaceName::Path(path) => {
2935                 for (i, name) in path.iter().enumerate() {
2936                     if i > 0 {
2937                         path_to_root.push_str("::");
2938                     }
2939                     path_to_root.push_str(name);
2940                 }
2941             }
2942         }
2943         Some(path_to_root)
2944     }
2945 
2946     fn push_str(&mut self, s: &str) {
2947         self.src.push_str(s);
2948     }
2949 
2950     fn info(&self, ty: TypeId) -> TypeInfo {
2951         self.gen.types.get(ty)
2952     }
2953 
2954     fn is_imported_interface(&self, interface: InterfaceId) -> bool {
2955         self.gen.interface_last_seen_as_import[&interface]
2956     }
2957 
2958     fn wasmtime_path(&self) -> String {
2959         self.gen.wasmtime_path()
2960     }
2961 }
2962 
2963 /// Produce a string for tracing a function argument.
2964 fn formatting_for_arg(
2965     name: &str,
2966     index: usize,
2967     ty: Type,
2968     opts: &Opts,
2969     resolve: &Resolve,
2970 ) -> String {
2971     if !opts.verbose_tracing && type_contains_lists(ty, resolve) {
2972         return format!("{name} = tracing::field::debug(\"...\")");
2973     }
2974 
2975     // Normal tracing.
2976     format!("{name} = tracing::field::debug(&arg{index})")
2977 }
2978 
2979 /// Produce a string for tracing function results.
2980 fn formatting_for_results(results: &Results, opts: &Opts, resolve: &Resolve) -> String {
2981     let contains_lists = match results {
2982         Results::Anon(ty) => type_contains_lists(*ty, resolve),
2983         Results::Named(params) => params
2984             .iter()
2985             .any(|(_, ty)| type_contains_lists(*ty, resolve)),
2986     };
2987 
2988     if !opts.verbose_tracing && contains_lists {
2989         return format!("result = tracing::field::debug(\"...\")");
2990     }
2991 
2992     // Normal tracing.
2993     format!("result = tracing::field::debug(&r)")
2994 }
2995 
2996 /// Test whether the given type contains lists.
2997 ///
2998 /// Here, a `string` is not considered a list.
2999 fn type_contains_lists(ty: Type, resolve: &Resolve) -> bool {
3000     match ty {
3001         Type::Id(id) => match &resolve.types[id].kind {
3002             TypeDefKind::Resource
3003             | TypeDefKind::Unknown
3004             | TypeDefKind::Flags(_)
3005             | TypeDefKind::Handle(_)
3006             | TypeDefKind::Enum(_) => false,
3007             TypeDefKind::Option(ty) => type_contains_lists(*ty, resolve),
3008             TypeDefKind::Result(Result_ { ok, err }) => {
3009                 option_type_contains_lists(*ok, resolve)
3010                     || option_type_contains_lists(*err, resolve)
3011             }
3012             TypeDefKind::Record(record) => record
3013                 .fields
3014                 .iter()
3015                 .any(|field| type_contains_lists(field.ty, resolve)),
3016             TypeDefKind::Tuple(tuple) => tuple
3017                 .types
3018                 .iter()
3019                 .any(|ty| type_contains_lists(*ty, resolve)),
3020             TypeDefKind::Variant(variant) => variant
3021                 .cases
3022                 .iter()
3023                 .any(|case| option_type_contains_lists(case.ty, resolve)),
3024             TypeDefKind::Type(ty) => type_contains_lists(*ty, resolve),
3025             TypeDefKind::Future(ty) => option_type_contains_lists(*ty, resolve),
3026             TypeDefKind::Stream(Stream { element, end }) => {
3027                 option_type_contains_lists(*element, resolve)
3028                     || option_type_contains_lists(*end, resolve)
3029             }
3030             TypeDefKind::List(_) => true,
3031         },
3032 
3033         // Technically strings are lists too, but we ignore that here because
3034         // they're usually short.
3035         _ => false,
3036     }
3037 }
3038 
3039 fn option_type_contains_lists(ty: Option<Type>, resolve: &Resolve) -> bool {
3040     match ty {
3041         Some(ty) => type_contains_lists(ty, resolve),
3042         None => false,
3043     }
3044 }
3045 
3046 /// When an interface `use`s a type from another interface, it creates a new TypeId
3047 /// referring to the definition TypeId. Chase this chain of references down to
3048 /// a TypeId for type's definition.
3049 fn resolve_type_definition_id(resolve: &Resolve, mut id: TypeId) -> TypeId {
3050     loop {
3051         match resolve.types[id].kind {
3052             TypeDefKind::Type(Type::Id(def_id)) => id = def_id,
3053             _ => return id,
3054         }
3055     }
3056 }
3057 
3058 fn rust_function_name(func: &Function) -> String {
3059     match func.kind {
3060         FunctionKind::Method(_) | FunctionKind::Static(_) => to_rust_ident(func.item_name()),
3061         FunctionKind::Constructor(_) => "new".to_string(),
3062         FunctionKind::Freestanding => to_rust_ident(&func.name),
3063     }
3064 }
3065 
3066 fn func_field_name(resolve: &Resolve, func: &Function) -> String {
3067     let mut name = String::new();
3068     match func.kind {
3069         FunctionKind::Method(id) => {
3070             name.push_str("method-");
3071             name.push_str(resolve.types[id].name.as_ref().unwrap());
3072             name.push_str("-");
3073         }
3074         FunctionKind::Static(id) => {
3075             name.push_str("static-");
3076             name.push_str(resolve.types[id].name.as_ref().unwrap());
3077             name.push_str("-");
3078         }
3079         FunctionKind::Constructor(id) => {
3080             name.push_str("constructor-");
3081             name.push_str(resolve.types[id].name.as_ref().unwrap());
3082             name.push_str("-");
3083         }
3084         FunctionKind::Freestanding => {}
3085     }
3086     name.push_str(func.item_name());
3087     name.to_snake_case()
3088 }
3089 
3090 fn get_resources<'a>(resolve: &'a Resolve, id: InterfaceId) -> impl Iterator<Item = &'a str> + 'a {
3091     resolve.interfaces[id]
3092         .types
3093         .iter()
3094         .filter_map(move |(name, ty)| match resolve.types[*ty].kind {
3095             TypeDefKind::Resource => Some(name.as_str()),
3096             _ => None,
3097         })
3098 }
3099 
3100 fn get_world_resources<'a>(
3101     resolve: &'a Resolve,
3102     id: WorldId,
3103 ) -> impl Iterator<Item = &'a str> + 'a {
3104     resolve.worlds[id]
3105         .imports
3106         .iter()
3107         .filter_map(move |(name, item)| match item {
3108             WorldItem::Type(id) => match resolve.types[*id].kind {
3109                 TypeDefKind::Resource => Some(match name {
3110                     WorldKey::Name(s) => s.as_str(),
3111                     WorldKey::Interface(_) => unreachable!(),
3112                 }),
3113                 _ => None,
3114             },
3115             _ => None,
3116         })
3117 }
3118