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