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