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