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